Programmer's Reference Guide

L'autoloader

Autoloaders de ressources

Les autoloaders de ressources servent à manipuler du code de librairies dans des espaces de noms, respectant les conventions de codage du Zend Framework, mais n'ayant pas une correspondance 1:1 entre le nom de la classe et la structure du dossier. Leur but est de faciliter le chargement du code des ressources de l'application, comme les modèles, les ACLs, les formulaires...

Les autoloaders de ressources s'enregistrent dans l'autoloader à leur instanciation, avec l'espace de noms auxquels ils sont rattachés. Ceci permet de facilement isoler du code dans des dossiers, sous l'espace de noms, tout en gardant les bénéfices de l'autoload.

Utilisation de l'autoloader de ressources

Soit la structure de répertoires suivante :

  1. path/to/some/directory/
  2.     acls/
  3.         Site.php
  4.     forms/
  5.         Login.php
  6.     models/
  7.         User.php

Au sein de ce répertoire, toutes les classes sont préfixées par l'espace de noms "My_". Dans le dossier "acls", le préfixe de composant "Acl_" est ajouté, ce qui donne un nom de classe final "My_Acl_Site". Aussi, le dossier "forms" correspond à "Form_", ce qui donne "My_Form_Login". Le dossier "models" n'a pas d'espace de noms particulier, donnant donc "My_User".

Pour instancier un autoloader de ressoucres, il faut au minimum lui passer son dossier de travail (base path), et le nom de l'espace de noms correspondant :

  1. $resourceLoader = new Zend_Loader_Autoloader_Resource(array(
  2.     'basePath'  => 'path/to/some/directory',
  3.     'namespace' => 'My',
  4. ));

Note: Espace de noms de base
Dans Zend_Loader_Autoloader, vous devez spécifier le underscore final ("_") dans votre espace de noms. Zend_Loader_Autoloader_Resource suppose par contre que tout le code à auto-charger utilisera le séparateur d'espaces de noms underscore. Ainsi, vous n'avez pas besoin de le préciser avec l'autoloader de ressources.

Maintenant que notre autoloader est configuré, nous pouvons ajouter des composants à auto-charger. Ceci se fait via la méthode addResourceType(), qui accepte 3 arguments : un "type" de ressource, utiliser en interne comme nom de référence ; le sous dossier dans lequel la ressource en question est logé, et l'espace de noms du composant à rajouter à l'espace de noms général. Voici un exemple :

  1. $resourceLoader->addResourceType('acl', 'acls/', 'Acl')
  2.                ->addResourceType('form', 'forms/', 'Form')
  3.                ->addResourceType('model', 'models/');

Aussi, vous auriez pu effectuer la même action avec un tableau PHP. addResourceTypes() est alors appropriée :

  1. $resourceLoader->addResourceTypes(array(
  2.     'acl' => array(
  3.         'path'      => 'acls/',
  4.         'namespace' => 'Acl',
  5.     ),
  6.     'form' => array(
  7.         'path'      => 'forms/',
  8.         'namespace' => 'Form',
  9.     ),
  10.     'model' => array(
  11.         'path'      => 'models/',
  12.     ),
  13. ));

Enfin, vous pouvez spécifier tout cela d'un seul coup avec des tableaux nichés. La clé doit alors être "resourceTypes" :

  1. $resourceLoader = new Zend_Loader_Autoloader_Resource(array(
  2.     'basePath'      => 'path/to/some/directory',
  3.     'namespace'     => 'My',
  4.     'resourceTypes' => array(
  5.         'acl' => array(
  6.             'path'      => 'acls/',
  7.             'namespace' => 'Acl',
  8.         ),
  9.         'form' => array(
  10.             'path'      => 'forms/',
  11.             'namespace' => 'Form',
  12.         ),
  13.         'model' => array(
  14.             'path'      => 'models/',
  15.         ),
  16.     ),
  17. ));

L'autoloader de ressource Module

Zend Framework fournit une implémentation concrète de Zend_Loader_Autoloader_Resource qui contient des correspondances de ressources pour mettre en avant la structure modulaire par défaut que propose le Zend Framework dans ses applications MVC. Ce chargeur, Zend_Application_Module_Autoloader, propose le mapping suivant :

  1. forms/       => Form
  2. models/      => Model
  3.     DbTable/ => Model_DbTable
  4.     mappers/ => Model_Mapper
  5. plugins/     => Plugin
  6. services/    => Service
  7. views/
  8.     helpers  => View_Helper
  9.     filters  => View_Filter

Par exemple, avec un module dont le préfixe est "Blog_", le chargement de la classe "Blog_Form_Entry" mènerait au chargement du fichier "forms/Entry.php".

En utilisant les bootstraps de modules avec Zend_Application, une instance de Zend_Application_Module_Autoloader sera crée pour chaque module utilisé.

Utiliser les autoloaders de ressources comme fabriques d'objets

Référence de l'autoloader de ressources


L'autoloader

Comments

Ive noticed a problem coming up between two servers I am using to develop an application.

I add a resource to the resource autoloader like in the examples above. for my example I will use form.

$resourceLoader->addResourceType('form', 'forms/', 'Form');

On my local machine my directory can look like the following example, and can auto load the files without error given that the class name follows the directory.

forms/
- Login.php (Form_Login)
- Signup.php (Form_Signup)
- Admin/
- - News.php (Form_Admin_News)
- - User.php (Form_Admin_User)


But on my remote test server the auto loader fails and returns an error:

Fatal error: Class 'Form_Admin_News' not found in /application/controllers/AdminController.php on line 53
i have the same problem here witd a Model.

on my Dev System (ZendserverCE on MAC) al walks fine, but on my production system with ubuntu 8.04 it fail:


Fatal error: Class 'Media_Model_DbTable_Sources' not found in /www/projectname/application/modules/media/controllers/SourcesController.php on line 20


I can not find a solution. :(

d
I believe that MAC is case insensitive whereas Ubuntu, it is not. Check your spelling.
I don't get it.
I'm using this:

      $resourceLoader = new Zend_Loader_Autoloader_Resource(array(
          'basePath'      => 'path/to/some/directory',
          'namespace'     => 'My',
          'resourceTypes' => array(
              'acl' => array(
                  'path'      => 'acls/',
                  'namespace' => 'Acl',
              ),
              'form' => array(
                  'path'      => 'forms/',
                  'namespace' => 'Form',
              ),
              'model' => array(
                  'path'      => 'models/',
              ),
          ),
      ));

It's copied from this tutorial.
I'm getting an Exception:


Fatal error: Uncaught exception 'Zend_Loader_Exception' with message 'Initial definition of a resource type must include a namespace' in C:\Program Files\Zend\ZendServer\share\ZendFramework\library\Zend\Loader\Autoloader\Resource.php:276 Stack trace: #0
...


Why?!
We are having the same error, class not found. We have tried several porible solutions but, nothing.
If you receive the error 'Initial definition of a resource type must include a namespace' from the examples on this page, you need to ensure that each resource type declaration has a namespace key. Some of the examples on this page omit this key. For example, this:

      $resourceLoader = new Zend_Loader_Autoloader_Resource(array(
          'basePath'      => 'path/to/some/directory',
          'namespace'     => 'My',
          'resourceTypes' => array(
              'acl' => array(
                  'path'      => 'acls/',
                  'namespace' => 'Acl',
              ),
              'form' => array(
                  'path'      => 'forms/',
                  'namespace' => 'Form',
              ),
              'model' => array(
                  'path'      => 'models/',
              ),
          ),
      ));

Note the missing namespace in the 'model' resource type. That example should actually be:

      $resourceLoader = new Zend_Loader_Autoloader_Resource(array(
          'basePath'      => 'path/to/some/directory',
          'namespace'     => 'My',
          'resourceTypes' => array(
              'acl' => array(
                  'path'      => 'acls/',
                  'namespace' => 'Acl',
              ),
              'form' => array(
                  'path'      => 'forms/',
                  'namespace' => 'Form',
              ),
              'model' => array(
                  'path'      => 'models/',
                  'namespace' => 'Model',
              ),
          ),
      ));
This might help others as I was stuck with this for a while.
Even if you set things up as shown in the above example don't forget you need to include the namespaces names in your class names too!

So if you have:
$user = new My_Model_User();
and this refers to the User.php file sat under application_directory/models/User.php
you still must make sure that the user class name is actually My_Model_User

class My_Model_User {

//code

}

Zend do this themselves too. For example if you load the config.php class in the Zend library directory via the autoloader you will see that the class name in that file is Zend_Config.php

If you would name the class:
class User {
}
then you will get the "class not found" error.

This may seem obvious to many but it had me baffled when I started out using the Zend Framework in the MVC style.

I think Zend could give more detailed examples as that would help.
Todavia no entiendo en que archivo/s se ponen los autoloaders
Alguien me explica?
Thank you so much for that last comment.
Indeed, I was struggling to solve the 'Class Model_Users' not found error to finally realize that the mistake was because the file was wrongly named 'Model_Users.php' and not 'Users.php' as expected.

Cheers!
Thanksssssssssssssssssssssssssssssssssssssssssssssssss really thank you I was stuck in this point for hours:):)
I'm trying to use ZendX components in my modules. Not working as the modulename is used a prefix within a module for each class the Resource Autoloader tries to load. Now ZendX components definitely not start with my module names at their names.

Any idea how to resolve this?
If you are like me skipping another night over this... pay attention to to FILE NAMES



path/to/some/directory/
acls/
Site.php (ENSURE YOUR class's filename starts with UPPER CASE)
forms/
Login.php (ENSURE YOUR class's filename starts with UPPER CASE)
models/
User.php (ENSURE YOUR class's filename starts with UPPER CASE)

Zend_Loader_Autoloader works Capitalized!!

My_Acl_Site points to -->
/acls/Site.php NOT /acls/site.php
I was running into an issue with autoloaders similar to dan where it was working on my Mac, but as soon as I uploaded to Ubuntu, it failed. I checked my casing and I had a lower case folder I was referencing uppercase. I changed to folder to uppercase and all was well on Ubuntu. Thanks Kai!
Hi,

I'm new to Zend Framework, and i'm trying to understand something, what are the benefits of using the Zend_Application_Module_Autoloader and the namespace "My_" when im using the modules structure. Why not simply call the controller and classes by its names. What am I trying to avoid when using those tools?

+ Add A Comment

Please do not report issues via comments; use the ZF Issue Tracker.

If you have a JIRA/Crowd account, we suggest you login first before commenting.

  • BBCode is allowed in the comment markup

  • Select a Version

    Languages Available

    Components

    Search the Manual