Programmer's Reference Guide

Der Autoloader

Ressource Autoloader

Ressource Autoloader sind dazu gedacht Namespaced Bibliothekscode zu Managen der den Coding Standard Richtlinien vom Zend Framework folgt, welche aber kein 1:1 Mapping zwischen dem Klassennamen und der Verzeichnis Struktur haben. Ihr primärer Zweck ist es als Autoloader Anwendungs-Ressource Code zu arbeiten, wie z.B. für Anwendungs-spezifische Modelle, Formen, und ACLs.

Ressource Autoloader werden mit dem autoloader bei der Instanziierung registriert, und zwar mit dem Namespace mit dem Sie assoziiert sind. Das erlaubt es Code in speziellen Verzeichnissen zu namespacen, und trotzdem die Vorteile des Autoloadings zu nutzen.

Verwendung von Ressource Autoloadern

Nehmen wir die folgende Verzeichnis Struktur an:

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

In diesem Verzeichnis hat jeder Code ein Präfix mit dem Namespace "My_". Im Unterverzeichnis "acls" ist der Komponentenpräfix "Acl_" hinzugefügt, was letztendlich zu einem Klassennamen von "My_Acl_Site" führt. So ähnlich mappt das Unterverzeichnis "forms" auf "Form_", was zu "My_Form_Login" führt. Das Unterverzeichnis "models" hat keinen Komponenten Namespace, was zu "My_User" führt.

Man kann einen Ressource Autoloader verwenden um diese Klassen automatisch zu laden. um den Ressource Autoloader zu instanziieren ist es mindestens notwendig den Basispfad und den Namespace für die Ressourcen zu übergeben für die er verantwortlich ist:

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

Hinweis: Basis Namespace
In Zend_Loader_Autoloader wird erwartet das man den endenden Unterstrich ("_") im Namespace angibt wenn der eigene Autoloader verwendet wird um den Namespace zu suchen. Zend_Loader_Autoloader_Resource nimmt an das alle Codes die man automatisch laden will ein Unterstrich Trennzeichen zwischen Namespace, Komponente und Klasse verwenden. Als Ergebnis, muß man den endenen Unterstrich nicht verwenden wenn ein Ressource Autoloader registriert wird.

Jetzt da wir den Basis Ressource Autoloader eingerichtet haben, können wir einige Komponenten zu Ihm hinzufügen um die automatisch zu Laden. Das wird mit der addResourceType() Methode getan, welche drei Argumente akzeptiert: einen Ressource "type", der intern als Referenzname verwendet wird; den Pfad des Unterverzeichnisses unter dem Basispfad in dem diese Ressource existiert; und den Namespace der Komponente die dem Basis Namespace hinzugefügt wird. Als Beispiel fügen wir jeden unserer Ressource Typen hinzu.

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

Alternativ können diese als Array an addResourceTypes() übergeben werden; das folgende ist äquivalent zu dem obigen:

  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. ));

Letztendlich kann alles davon spezifiziert werden wenn das Objekt instanziiert wird indem einfach ein "resourceTypes" Schlüssel in den Optionen spezifiziert und übergeben wird, sowie eine Struktur wie anbei:

  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. ));

Der Modul Ressource Autoloader

Zend Framework wird mit einer konkreten Implementation von Zend_Loader_Autoloader_Resource ausgeliefert die Ressourcen Typen enthält welche den notwendigen Standard Verzeichnisstrukturen für Zend Framework MVC Anwendungen entsprechen. Diese Lader, Zend_Application_Module_Autoloader, kommt mit den folgenden Mappings:

  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

Wenn man, als Beispiel, ein Modul mit dem Präfix "Blog_" hat, und die Klasse "Blog_Form_Entry" instanziieren will, würde diese in den Ressourcen Verzeichnis "forms/" im Unterverzeichnis nach einer Datei die "Entry.php" heißt suchen.

Wenn Modul Bootstraps mit Zend_Application verwendet werden, wird standardmäßig eine Instanz von Zend_Application_Module_Autoloader für jede eigene Modul erstellt, was es erlaubt Modul Ressource automatisch zu laden.

Verwendung von Ressource Autoloadern als Objekt Factories

Referenz zu den Ressource Autoloadern


Der 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