zend framework include another class in my action controller - zend-framework

I am newbie in zend framework ,
a simple question :
in my IndexController file , I want to instance new class.
I put the file of class declaration under /library
and of course its in the include path (index.php)
set_include_path(implode(PATH_SEPARATOR, array(
realpath(APPLICATION_PATH . '/../library'),
get_include_path()
)));
I get an error :
Fatal error: Class 'Profile' not found in ....
what is the way to auto load this class ?
thanks!

Alternatively, you could add namespaces to the autoloader.
So if your class was named My_Profile, stored in a the file library/My/Profile.php, you could add the following to your application/config/application.ini:
autoloadernamespaces[] = "My_"
or in your Bootstrap class's _initAutoload() method:
Zend_Loader_Autoloader::getInstance()->registerNamespace('My_');
See Zend Framework: Autoloading a Class Library

you have to put this class in models ...not in library
and use
set_include_path('./application/models'); in index.php

Related

PHPExcel class not found in Zend Autoloader

I am struggling with namespaces in Zend Framework (at least I think it's a namespace issue).
I want to integrate PHPExcel into my Zend project. Relevant file structure is as follows:
/
-library
-ABCD
-PHPExcel
-Zend
-ZendX
-PHPExcel.php
Custom classes work fine, after
Zend_Loader_Autoloader::getInstance()->registerNamespace('ABCD_');
in the bootstrap. Also, those classes are all named ABCD_blahdeblah.
However, doing registerNamespace('PHPExcel_') doesn't help Zend find the appropriate classes. When I try
$sheet = new PHPExcel;
in the controller, I get a "Class not found" error. I am guessing that this is either because classes in PHPExcel aren't named with the namespace prefix, or because the main PHPExcel.php file sits outside of the namespace I've just declared. But the PHPExcel structure demands that it sit in the parent directory of the rest of the class/font/etc files.
Any pointers would be greatly appreciated.
Thanks in advance.
Create an autoloader for PHPExcel and add it to the Zend autoloader stack.
In library/My/Loader/Autoloader/PHPExcel.php:
class My_Loader_Autoloader_PHPExcel implements Zend_Loader_Autoloader_Interface
{
public function autoload($class)
{
if ('PHPExcel' != $class){
return false;
}
require_once 'PHPExcel.php';
return $class;
}
}
And in application/configs/application.ini:
autoloadernamespaces[] = "My_"
Then, in application/Bootstrap.php:
protected function _initAutoloading()
{
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->pushAutoloader(new My_Loader_Autoloader_PHPExcel());
}
Then you should be able to instantiate PHPExcel - say, in a controller - with a simple:
$excel = new PHPExcel();
The only sticky part is all of this is how PHPExcel handles loading all its dependencies within its own folder. If that is done intelligently - either with calls like require_once basename(__FILE__) . '/someFile.php' or with its own autoloader that somehow doesn't get in the way of the Zend autoloader - then all should be cool. #famouslastwords
Nowadays composer is a frequently used tool that wasn't so popular back in 2012. Even older projects built in ZF1 can make use of composer and its autoloader.
How to get all your libraries to work without having to add custom autoloaders to your application.ini each time?
Make use of composer's autoloader
First, start with setting up composer.json. Once created, run composer install to gather all required packages and create composer's autoloader.
Now, let's update your project's public/index.php. From now on all requirements that are loaded via composer will be autoloaded.
<?php
// Define path to application directory
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
// Define application environment
defined('APPLICATION_ENV')
|| define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'development'));
// Include composer autoloader
require_once __DIR__ . '/../vendor/autoload.php';
/** Zend_Application */
require_once 'Zend/Application.php';
// Create application, bootstrap, and run
$application = new Zend_Application(
APPLICATION_ENV,
array( 'config' => APPLICATION_PATH . '/configs/application.ini' )
);
$application->bootstrap();
$application->run();
Try modifying the PHPExcel autoloader:
Add
if (function_exists('__autoload')) {
spl_autoload_register('__autoload');
}
as the first two lines of the Register() method in /Classes/PHPExcel/Autoloader.php, immediately before
return spl_autoload_register(array('PHPExcel_Autoloader', 'Load'));
I've had a similar problem with both an exel-librare (phpxls) and a pdf-library (fpdf) and after some different tries I just settled with including the required file from the library manually and go from there. Booth phpxls and fdpd can then handle everything else without interfering with the zend autoloader methods.
A psudo_code example would look like this, where I return a object of the desired class and then can continue to work with that. You could offcourse choose to include things in the constructor and build from that.
<?php
class exelClass{
public function exelFunction(){
require_once 'required_file.php';
$exelObject = new exelObject();
return $exelObject->Output();
}
}
?>
This solution might not be that elegant, but I found that it was the easiest way to enable different types of libraries to co-exist without differnet autoloaders or magic functions interfearing with each other.

Zend framework Fatal error: Class 'Application_Model_DbTable_Albums' not found in

I am trying to learn Zend framework from "Getting Started with Zend Framework" By Rob Allen. I have used the same example that has been given, but getting the error -
Fatal error: Class 'Application_Model_DbTable_Albums' not found in /var/www/html/workbench/sreekantk/zf-tutorial/application/controllers/IndexController.php on line 14 .
I think I have to set path to models folder, but don't know how to do it. Could anyone please help me out of this.
This is my Bootstrap.php file.
// application/Bootstrap.php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initAutoload()
{
$autoloader = new Zend_Application_Module_Autoloader(array(
'namespace' => '',
'basePath' => APPLICATION_PATH.'/application/modules'));
return $autoloader;
}
}
Thanks Just H. It worked. Actually I changed the folder structure and after the again added appnamespace="Application" to the application.ini file. Thanks you all for your comments.
As long as you get to the controller your primary setup seems to be fine. So, if you have the class in a separate file the problem is probably a simple typo somewhere.
a) with all the following, look out for lower/upper case
b) note that the models folder is plural whereas the class is Model singular
c) make sure the class is named Application_Model_DbTable_Albums
d) make sure the file is named Albums.php and in a folder named application/models/DbTable
Good luck learning ZF
Since version 1.9.2, the default module will automatically initialise an autoloader for the namespace configured in appnamespace (defaults to "Application" on a vanilla install). You can remove your _initAutoload() method.
So long as your class exists in application/models/DbTable/Albums.php and is named Application_Model_DbTable_Albums, it should be able to autoload the class on first use.
Be mindful of path case sensitivity.
I'm following the same tutorial and what Adrian World said on Aug 9'11 at 13:26 helped me get rid of the error. My Bootstrap now is:
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initAutoload()
{
$autoloader = new Zend_Application_Module_Autoloader(array(
'namespace' => '',
'basePath' => APPLICATION_PATH.'/application/models'));
return $autoloader;
}
}
Where the only thing that changed was going from modules to models
You should define Bootstrap class of the current Module. Then it will be fine.

Zend Autoloading models issue

Zend framework.
I want to autoload my models classes inside models folder, from within bootstrap class.
These models doesnt actually use any namespace (so I have Ex. User.php file's class named User and so on..).
If I understood correctly I should use the Zend_Loader_Autoloader_Resource and I tried:
function _initLoaderResource()
{
$resourceLoader = new Zend_Loader_Autoloader_Resource(array(
'basePath' => APPLICATION_PATH,//points to the "application" path where resides "models" folder
'namespace' =>''
));
$resourceLoader->addResourceType('models', 'models/');
}
And I receive following 'Zend_Loader_Exception' message:
'Initial definition of a resource type must include a namespace'
My questions are:
Is this the right way to autoload models?
How should I manage resource code that doesn't follow Zend Framework coding standard?
Actually you probably don't want to use the resource autoloader for this, since (as you've discovered) it requires a namespace. The standard autoloader (which loads models from the include path) has an option setFallbackAutoloader which tells ZF that that autoloader should be used for any class not matching a namespace covered by another. So all you need to do is ensure your models directory is on the include path and set this option to true.
You are probably already using the standard autoloader for loading the Zend classes, so you'll probably want to modify your application.ini file to add your model directory to the include path, and then set the fallback option either in application.ini or in your Bootstrap class:
protected function _initAutoloader()
{
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->setFallbackAutoloader(true);
return $autoloader;
}
Zend Autoloader uses namespaces to make sure you are not using the autoload process, on those classes you don't want. So you would have to choose a namespace for your classes.
You could start your classes with an application specific namespace, or a general one.
namespaces like 'My_' or 'App_' are general, yet for example if your application name is Job Board, you could use namespaces like 'JB_' in your class files.
You may also write your own autoloader (either a totally new one, or by extending the Zend autoloader) and register it as the SPL autoloader to bypass this.
Your class names does not have to follow the Zend Framework naming conventions, just make sure they have a namespace and register the namespace in the autoloader.
Here I attach a piece of my code that registers some resources to be autoloaded. I'm having multiple modules, and each module has a namespace regarding that module name. Please note that since there were many namespaces, I register them all in a loop.
$nameSpaceToPath = array(
'Application' => APPLICATION_PATH,
'Base' => APPLICATION_PATH . '/base',
'Store' => APPLICATION_PATH . '/modules/Store',
'Payment' => APPLICATION_PATH . '/modules/Payment',
'Admin' => APPLICATION_PATH . '/modules/Admin'
);
foreach($nameSpaceToPath as $ns => $path) {
$autoLoaderResource = new Zend_Loader_Autoloader_Resource(
array(
'basePath' => $path,
'namespace' => $ns
)
);
$autoLoaderResource->addResourceType('controller','controllers','Controller');
$autoLoaderResource->addResourceType('model','models','Model');
$autoLoaderResource->addResourceType('mapper','models/mappers','Model_Mapper');
$autoLoaderResource->addResourceType('service','services','Service');
// I'm using _Util_ in the name of my utility classes, I place them in 'utils' directory
$autoLoaderResource->addResourceType('util','utils','Util');
$autoLoaderResource->addResourceType('plugin','plugins','Plugin');
$autoLoaderResource->addResourceType('form','forms','Form');
// I'm using _Exception_ in the name of my module specific exception classes, I place them in 'exceptions' directory
$autoLoaderResource->addResourceType('exception','exceptions','Exception');
$autoLoader->pushAutoloader($autoLoaderResource);
}
When you are defining a resource type by calling:
$autoLoaderResource->addResourceType('service','services','Service');
You are actually telling Zend Autoloader that you have a type 'service' (1st param), which is placed in the directory named 'services' (2nd param), and you are using 'Service' token in the class names to specify classes of this type.
The above code tells Zend Autoloader to search for class Store_Service_Core in the path 'APPLICATION_PATH/modules/store/services/Core.php'.
As you can see I have registered the general 'Application' namespace for the APPLICATION_PATH path. This means that each class, starting with Application_ would be autoloaded from the APPLICATION_PATH. So forexample I have a class named Application_Init which uses some initialization tasks, and now Zend autoloads it from the path APPLICATION_PATH/Init.php.

Zend Controller Action Helper Problem not able to add helper

Trying to make a controller helper to have similar functionality in some controllers using the preDispatch method.
Error:
Fatal error: Class 'Helper_Action_Test' not found in /var/www/zend.dev/application/Bootstrap.php on line 9`
Application layout
/Application
/Helpers
**/Actions** this is where i will save the classes
/Views
/modules
/configs
/layouts
/Bootstrap.php
In the Bootstrap I have added:
protected function _initActionHelpers(){
Zend_Controller_Action_HelperBroker::addHelper(new Helper_Action_Test());
}
In the helper file I have:
class Helper_Action_Test extends Zend_Controller_Action_Helper_Abstract{
public function preDispatch() {
echo 'Test';
}
}
When I do this in the bootstap it works, it might have to do with the include or how I am trying to instantiate the new class with the addHelper();
include(APPLICATION_PATH.'/helpers/action/Test.php');
Zend_Controller_Action_HelperBroker::addHelper(new Test());
Any ideas?
try this one:
// Action Helpers
Zend_Controller_Action_HelperBroker::addPath(
APPLICATION_PATH .'/controllers/helpers');
$hooks = Zend_Controller_Action_HelperBroker::getStaticHelper('Quote');
Zend_Controller_Action_HelperBroker::addHelper($hooks);
You have to include the helper file bootstrap file I think.
Or I think you want to: require_once() it
By adding the following lines in your config file you will be able to achieve what you want
; Include path
includePaths.library = APPLICATION_PATH "/../library"
; Autoloader Namespace
autoloaderNamespaces[] = 'Helper_'
More info in the official ZF doc Autoloader
To solve your problem, make sure the _initAutoload() on your bootstrap is the first method and also make sure you have added the prefix path:
Zend_Controller_Action_HelperBroker::addPrefix('Helper_Action');
You can aslo provide the path to the classes if they are not on the include_path:
Zend_Controller_Action_HelperBroker::addPath(APPLICATION_PATH . '/helper/action/', 'Helper_Action');

zend modules models

My application setup with 2 modules admin and default
I test the controller which works fine on modules
but the models doesnt work
I created a model application\modules\admin\models\User.php
<?php
class Admin_Model_User{
}
inside the controller
$user = new Admin_Model_User();
Fatal error: Class 'Admin_Model_User'
not found
Essentially, you need 2 lines in the application.ini file;
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.modules[] = ""
Then, for each module, you need a module bootstrap file:
File: myproject/application/modules/{modulename}/Bootstrap.php
<?php
class {Modulename}_Bootstrap extends Zend_Application_Module_Bootstrap
{
}
(Yes, it is an empty class.)
Further details are at http://akrabat.com/zend-framework/bootstrapping-modules-in-zf-1-8/.
Configure an autoloader so that the framework can map your class prefix Admin_Model to the corresponding source path. This is not done automatically.
I suggest reading the part on models of the Zend Framework Quickstart, which explains in detail how to do this.
Are you using an autoloader?
If you do you should change the class name (or path) to reflect the path (or class name)
Models <> Model
You should have
Admin_Model_User in admin/model/user.php
or
Admin_Models_User in admin/models/user.php.