ZF-8205: Zend_Loader_Autoloader_Resource Namespace Separator

Issue Type: Improvement Created: 2009-11-02T08:24:35.000+0000 Last Updated: 2011-01-08T08:25:16.000+0000 Status: Open Fix version(s): Reporter: Keith Pope (mute) Assignee: Matthew Weier O'Phinney (matthew) Tags: - Zend_Loader

Related issues: - ZF-9016

Attachments: - Resource.diff


Add getter / setter for the namespace separator in the Zend_Loader_Autoloader_Resource class, this then makes it easy to switch to loading 5.3 namespaced resources.

This would help with Doctrine 2 integration as it loads 5.3 namespaced entities.


Posted by Keith Pope (mute) on 2009-12-22T09:30:12.000+0000


I am attaching a prototype patch for this, this is only a very quick first implementation so see what you think. I may need to expand the tests etc...



Posted by Andrea Turso (trashofmasters) on 2010-03-06T19:17:10.000+0000


I tried to roll my own patch to Zend_Loader_Autoloader_Resource when I found this report and then applied the diff to avoid reinventing the proverbial wheel.

With the files successfully patched, loading namespaced classes is working as expected, although the resource loader doesn't seem to be able to load class files

For instance, in a module bootstrap file:

<pre class="highlight">
$moduleLoader = new Zend_Application_Module_Autoloader(
        'namespace' => 'Forum',
        'basePath' => __DIR__,
$moduleLoader->addResourceType('entity', 'models', 'Model');

<pre class="highlight">
$autoloader = $this->getInvokeArg('bootstrap')

// tries to load \Forums_Model\Post, fail!

// tries to load \Forums\Model\Post, which is okay, however raises the error
// Class '\Forums\Model\Post' not found in /usr/local/lib/php/Zend/Loader/Autoloader/Resource.php

We should find a way to make the two implementation to cooperate when PHP5.3 namespaced classes are requested together with classic namespaced classes.

When I was brainstorming for the patch a solution that popped in my mind was:

<pre class="highlight">
// Explicitly tells the loader to use PHP5.3 namespace
$moduleLoader->addResourceType('resorurceName', 'resourceFolder', '\Resource');

// Triggers the classic loader. Which results in a #epic fail#
$moduleLoader->addResourceTYpe('resourceName', 'resourceFolder', 'Resource');

The first call will load \Forums\Resource\ when the second will load Forums_Resource_.

The patch could do something like this:

In Zend_Loader_Autoloader_Resource#addResourceType * Check if the $namespace has the heading \ ** Remove the heading \ in order return to the classic $namespace ** Mark the $resource as namespaced

<pre class="highlight">
+ if ('\\' == substr($namespace, 0, 1)) {
+     $this->_namespacedResources = ...
+ }

In Zend_Loader_Autoloader_Resource#load * Before instantiating the the resource check if it's namespaced ** Alter the $class name to reflect the Fully Qualified Name.

<pre class="highlight">
+ if () {
+    $klass = '\\' . str_replace('_', '\\', $class);
+    $this->_resources[$class] = new $klass;
+ } else {
     $this->_resources[$class] = new $class;
+ }

With this trick the autoloader will autoload the file in the classical way because the class is underscored and the namespace is only "unveiled" when instantiating the resource. For instance:

<pre class="highlight">
$resourceLoader->addResourceType('entities', 'folder/entities', '\Entity');
$resourceLoader->addResourceType('models', 'folder/models', 'Model');

// Will autoload MyApp/folder/entities/User.php and instantiates MyApp\Entity\User class

// Will autoload MyApp/folder/models/Post.php and instantiates MyApp_Model_Post class

What do you think about it?

Posted by Andrea Turso (trashofmasters) on 2010-03-07T07:58:25.000+0000

This is a naïve implementation of my solution, it does compose the namespace in the correct class path and does tell namespaced resources apart although it cannot autoload the file and therefore instantiate the Fully Qualified Name class.

Posted by Andrea Turso (trashofmasters) on 2010-03-07T08:14:18.000+0000

I had to hardcode a call to Zend_Loader_Autoloader_Resource#autoload($class) to load the required file and then instantiate the FQN class.

I attached the file Resource.diff, it contains all the changes I made to the Zend_Loader_Autoloader_Resource class, the test is in the previous ResourceTest.diff file. The ResourceTest has just one more test method I'm no Test-Driven so if you find this solution appropriate I suggest you to write another bunch of tests, just to be sure that the patch works with a wide range of use-cases.


Posted by Andrea Turso (trashofmasters) on 2010-03-09T11:50:38.000+0000

As I said in my previous comments, my patch doesn't seem to be able to autoload classes when instantiated directly, for example:

<pre class="highlight">
// Autoload correcly the class contained in application/modules/forums/models/Post.php
$myPost = new \Forums\Model\Post();

ended in Fatal Error: class \Forums\Model\Post not found ... while loading it with the load($resource, $class) worked.

I hacked the Zend_Loader_Autoloader and found out that applying the following patch made the Autoloader autoload my classes flawlessly.

<pre class="highlight">
---   library/Zend/Loader/Autoloader.php    2010-01-06 03:05:09.000000000 +0100
+++   /usr/lib/php/Zend/Loader/Autoloader.php   2010-03-09 20:35:44.000000000 +0100
@@ -115,6 +115,10 @@
         $self = self::getInstance();
+   if (false !== strpos($class, '\\')) {
+       $class = str_replace('\\', '_', $class);
+   }
         foreach ($self->getClassAutoloaders($class) as $autoloader) {
             if ($autoloader instanceof Zend_Loader_Autoloader_Interface) {
                 if ($autoloader->autoload($class)) {

I wouldn't rely on my previous patch to Zend/Loader/Autoloader/Resource.php as it was just a proof of concept to test resource loading.

I'd like to hear your opinions and if I'm heading the right way.


Posted by Dmitry (dv) on 2011-01-08T08:25:16.000+0000

I'm pretty sure there is no need to "hack" Zend_Loader_Autoloader.

Just use your custom autoloader. Also don't forget about resource autoloader for accessing classes with "Application_Model" into directory "applicatiom/models".

<pre class="highlight">
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap

    protected function _initAutoload()
        $applicationAutoloader = new Zend_Application_Module_Autoloader(array(
            'namespace' => 'Application_',
            'basePath'  => dirname(__FILE__),

        $autoloader = Zend_Loader_Autoloader::getInstance();
        $autoloader->pushAutoloader(array('Bootstrap', 'modelsAutoload'), 'Application\\Model\\');

    static public function modelsAutoload($className)
        Zend_Loader_Autoloader::autoload(str_replace('\\', '_', $className));


Have you found an issue?

See the Overview section for more details.


© 2006-2018 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.