I'm trying to autoload Classes from within a folder contained in the application itself.
E.G.
/Application
|->Models
|->Custom
|->Object.php
Is this the best way to do it (from bootstrap.php)?
public function _initAutoLoad()
{
$resourceLoader = new Zend_Loader_Autoloader_Resource(array(
'basePath' => APPLICATION_PATH,
'namespace' => '',
'resourceTypes' => array(
'custom' => array(
'path' => 'custom/',
'namespace' => 'Custom',
))
));
}
Meaning from within any controller, I can call:
$object = new Custom_Object();
If you're not intending to prefix the class names with the application namespace (default Application), I'd simply put this stuff in library, eg
library/
Custom/
Object.php -> class Custom_Object
then add your Custom namespace to the autoloader in configuration (application.ini)
autoloadernamespaces[] = "Custom_"
If your class represents some kind of service, you could use the built-in Service resource type which is automatically autoloaded
application/
services/
Object.php -> class Application_Service_Object
Looks like the solution I had is the best... I can find anyways...
Related
I'm trying to use forms with modules, they should be stored inside the module. So at first my filestructure:
application/
(...other directories)
modules/
group/
controllers/
IndexController.php
(...controllers)
forms/
Create.php
views/
scripts/
(...view scripts)
Bootstrap.php
Within the IndexController, I'm trying to set the Form by
new Group_Form_Create()
and the class in Create.php is of course Group_Form_Create. I get the following error message:
Fatal error: Class 'Group_Form_Create' not found in (...)\application\modules\group\controllers\IndexController.php on line 380
The Bootstrap.php with the class Group_Bootstrap is just an empty class.
Actually, I'm using the default Zend structure, but it woun't work anyway. Any ideas wheres the problems or what could be a possible solution?
In my module bootstrap (APPLICATION_PATH/modules/group/Bootstrap.php), if use the following code:
//Loads the autoloader resources
$this->_moduleName = 'group';
$resourceLoader = new Zend_Loader_Autoloader_Resource(array(
'basePath' => APPLICATION_PATH ."/modules/".$this->_moduleName."/",
'namespace' => '',
'resourceTypes' => array(
//Tells the application where to find the forms
'form' => array(
'path' => 'forms/',
'namespace' => ucfirst($this->_moduleName).'_Form_'
),
//Tells the application where to find the models
'model' => array(
'path' => 'models/',
'namespace' => ucfirst($this->_moduleName).'_Model_'
)
)
));
I then call the forms or models like this:
$frm = new Group_Form_Create();
I use the same snippet in all my modules and I only change the value of the $this->_moduleName; each time.
Hope this helps !
It sounds like your module bootstraps are not being run. These are triggered by the module resource, which is loaded if you have:
resources.modules[] = ""
in your application.ini. So add this if it is not present.
Ideally, it should work out of box.
Add this in your bootstrap:
protected function _initAutoload() {
$autoloader = new Zend_Application_Module_Autoloader(array(
'namespace' => 'Group_',
'basePath' => dirname(__FILE__),
));
Zend_Loader_Autoloader::getInstance()->setFallbackAutoloader(true);
return $autoloader;
}
All the classes under a default namespace Application_ is autoloaded by default. When you are creating more modules, the classes under that module is not autoloaded.
I tried setting the extra module's namespace on the application.ini like
autoloaderNamespaces[] = "EXTRA_"
but since the folder structure of the extra modules lies inside the Application it cannot find it.
How to set this correctly?
You can use application resource modules
Module bootstrap(if subclass of Zend_Application_Module_Bootstrap) register autoloader on instantiation.
Following is array of resources registered with autoloader by default:
array(
'dbtable' => array(
'namespace' => 'Model_DbTable',
'path' => 'models/DbTable',
),
'mappers' => array(
'namespace' => 'Model_Mapper',
'path' => 'models/mappers',
),
'form' => array(
'namespace' => 'Form',
'path' => 'forms',
),
'model' => array(
'namespace' => 'Model',
'path' => 'models',
),
'plugin' => array(
'namespace' => 'Plugin',
'path' => 'plugins',
),
'service' => array(
'namespace' => 'Service',
'path' => 'services',
),
'viewhelper' => array(
'namespace' => 'View_Helper',
'path' => 'views/helpers',
),
'viewfilter' => array(
'namespace' => 'View_Filter',
'path' => 'views/filters',
),
)
You can add your own module resource type to autoloader from module bootstrap:
//module bootstrap for module foo
class Foo_Bootstrap extends Zend_Application_Module_Bootstrap
{
function _initMyRes()
{
$autoloader = $this->getResourceLoader();
$autoloader->addResourceType('myres', 'myres/custom/path', 'My_Res');
}
}
first parameter is a key for resource type, second is a path relative to module name, third is a resource prefix.
For example class Foo_My_Res_Bar will be autoloaded from modules/foo/myres/custom/path/Bar.php
Namespaces is for your own library classes (like the Zend_) classes. Modules are different thing and don't have namespace in that sense.
In the application.ini configuration you will have something like this
autoloaderNamespaces.My = "My_"
// these are you library classes
resources.frontController.moduleDirectory = APPLICATION_LIBRARY "/modules"
// this is your module directory
UPDATE If you need support for more than one module directory you need ZF 1.11.1 or this bugfix
In the Bootstrap class for each module, create a new module resource autloloader:
protected function _initResourceAutoloader()
{
$resourceAutoloader = new Zend_Application_Module_Autoloader(array(
'namespace' => 'Mymodule',
'basePath' => dirname(__FILE__),
));
}
Then, you can use the "standard" folder structure for module-specific classes. For example, a form named Mymodule_Form_Edit would reside in the file modules/mymodule/forms/Edit.php
UPDATE
As noted by #Xerkus and others, a module Bootstrap extending Zend_Application_Module_Bootstrap will automatically register some standard namespace/path mappings, so no need to manually instantiate a Zend_Application_Module_Autoloader.
The things I did is
zf create project demo1 in command prompt
add the lines to application.ini
appnamespace = "Application"
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
add a layout with header and footer using partial() (They are perfectly worked)
create Data.php in models directory and add this simple class
<?php class Application_Model_Data{ }//Application for appnamespace
then I tried to load this class(by creating instance)from index controller index action
$data = new Application_Model_Data();
but when I test it even in this level it gives an error
Fatal error: Class 'Application_Model_Data' not found in C:\Zend\...\IndexController.php
Question
Do I want to add a autoloader to
load models in the application( I'm not used modules)
if not what was I missed to add
please help I'm stuck in the beginning,Thank you
this should work!!
add this function to bootstrap:
protected function _initResourceAutoloader()
{
$autoloader = new Zend_Loader_Autoloader_Resource(array(
'basePath' => APPLICATION_PATH,
'namespace' => 'Application',
));
$autoloader->addResourceType( 'model', 'models', 'Model');
return $autoloader;
}
You need to setup a resource Autoloader in your Bootstrap, something like this:
protected function _initResourceAutoloader()
{
$autoloader = new Zend_Loader_Autoloader_Resource(array(
'basePath' => 'path/to/application/directory',
'namespace' => 'Application_',
));
return $autoloader;
}
With that, Zend can load the modules in your application, and just not models, but DbTable, Forms, Plugins, etc.
write the following in your bootstrap file:
protected function _initDefaultModuleAutoloader()
{
$resourceLoader = new Zend_Application_Module_Autoloader(array(
'namespace' => '',
'basePath' => APPLICATION_PATH,
));
return $resourceLoader;
}
in your models folder create new file and name it "Data.php"
in the Data.php declare the class like this:
class Model_Data extends Zend_Db_Table_Abstract {.....}
you can now instantiate your data model like so:
$data = new Model_Data();
good luck :-)
in your application ini you should have
autoloadernamespaces.0 = 'Application' instead of appnamespace
then your model would be in
/library/Application/Model/Data.php
but why dont you use the default "models" folder in the suggested application structure.
I had forgotten to add the file extension .php to the file, just in case someone else makes the same mistake
I'm new to zend framework so maybe this question is stupid..
I've got a default hierarchy
site
|--bootstrap.php
|--application
|--models
|-- Item.php
|-- ModelAbstract.php
|--...
Inside Item.php there's
<?php
//TODO: trying to remove this require...
require_once('ModelAbstract.php');
class CF_Model_Flower extends CF_Model_Abstract
{
...
Inside 'ModelAbstract.php' there's
<?php
class CF_Model_Abstract
{
...
And my application Bootstrap.php looks like
<?php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initAutoload()
{
$autoloader = new Zend_Application_Module_Autoloader(array(
'namespace' => 'CF',
'basePath' => dirname(__FILE__),
));
return $autoloader;
}
...
If I removed the 'require_once' inside Item.php I get
Fatal error: Class 'CF_Model_Abstract' not found in /Mysite/application/models/Item.php on line 6
Why ? And how can I use autoloading to live without this require_once ?
In fact, renaming 'ModelAbstract.php' to 'Abstract.php' works. Can someone explain me why ?
Thx
I'm not familiar with Zend_Application_Module_Autoloader and such. But if they work anything like earlier ZF autoloading mechanisms, the autoloader will look for class CF_Model_Abstract in:
CF/Model/Abstract.php
or maybe with this namespace/basePath configuration in:
models/Model/Abstract.php
or:
models/CF/Model/Abstract.php
but probably not in:
models/ModelAbstract.php
So in other words, the underscores represent child directories.
Try specifying the _ in the namespace.
$autoloader = new Zend_Application_Module_Autoloader(array(
'namespace' => 'CF_',
'basePath' => dirname(__FILE__),
));
Put the following in your bootstrap file:
protected function _initAutoLoad()
{
$loader = new Zend_Loader_Autoloader_Resource(array(
'basePath' => APPLICATION_PATH,
'namespace' => 'CF',
));
$loader->addResourceType('form', 'forms', 'Form')
->addResourceType('model', 'models', 'Model')
->addResourceType('mapper', 'models/mappers', 'Model_Mapper')
->addResourceType('dbtable', 'models/DbTable', 'Model_DbTable');
return $loader;
}
This will load models, forms, dbtables, and mappers for you. Hope this does the trick.
in Zend Framework Quickstart,
protected function _initAutoload() {
$autoloader = new Zend_Application_Module_Autoloader(array(
'namespace' => 'Default_',
'basePath' => dirname(__FILE__),
));
return $autoloader;
}
i thought if the namespace was 'Default', i dont need to specify it?
eg. their class also has Default_ appended to it
class Default_Model_Guestbook
isit required? or isit better practice?
The manual states it is certainly not required. But you could say it's a good practice.
If you do namespace it you could edit your 'default module' in the config and you don't have to go namespace the previous default one...
this can be done by setting the prefixDefaultModule:
resources.frontController.prefixDefaultModule = 1
also have a look at this question: Dynamic default mdoule in ZF