ZF-10136: Wrong arrays union in Zend_Loader_Autoloader::getClassAutoloaders

Description

Wrong arrays union in Zend_Loader_Autoloader::getClassAutoloaders, if $autoloaders isn't empty array. See last comment at http://php.net/manual/en/… Example:

<?php

include "Zend/Loader/Autoloader.php";

$zend_loader = Zend_Loader_Autoloader::getInstance();

class Loader implements Zend_Loader_Autoloader_Interface
{
    public function autoload($class)
    {
         /* do something */
    }
}


$zend_loader->
    registerNamespace('Test')->
    pushAutoloader(new Loader());

var_dump(count($zend_loader->getClassAutoloaders('Test_Class')));

Output (only Zend_Loader_Autoloader instance):

 
int(1)

Must be (Zend_Loader_Autoloader and Loader instances):

 
int(2)

Patch for fix:

 
--- Autoloader.php      2010-07-12 14:13:33.000000000 +0700
+++ Autoloader.new.php  2010-07-12 14:14:12.000000000 +0700
@@ -338,7 +338,7 @@
             }
             if (0 === strpos($class, $ns)) {
                 $namespace   = $ns;
-                $autoloaders = $autoloaders + $this->getNamespaceAutoloaders($ns);
+                $autoloaders = array_merge($autoloaders, $this->getNamespaceAutoloaders($ns));
                 break;
             }
         }
@@ -353,7 +353,7 @@
         }
 
         // Add non-namespaced autoloaders
-        $autoloaders = $autoloaders + $this->getNamespaceAutoloaders('');
+        $autoloaders = array_merge($autoloaders, $this->getNamespaceAutoloaders(''));
 
         // Add fallback autoloader
         if (!$namespace && $this->isFallbackAutoloader()) {

Comments

This issue still exists in ZF 1.10.8 and even on trunk today.

Maintainers, please commit this patch.

This issue actually also exists in the 1.11 RC1 release. The effective result of this bug is that it is not possible to register multiple autoloaders with either the same namespace or namespaces with the same starting string (e.g. 'account' and 'accountAdmin').

the patch supplied for the fix, however, is slightly incorrect in that it does not remove the break on line 342 so the foreach on line 335 doesn't loop and fill additional autoloaders into the array.

additional patch:

--- Autoloader.php      2010-07-12 14:13:33.000000000 +0700
+++ Autoloader.new.php  2010-07-12 14:14:12.000000000 +0700
@@ -338,7 +338,7 @@
             }
             if (0 === strpos($class, $ns)) {
                 $namespace   = $ns;
                $autoloaders = array_merge($autoloaders, $this->getNamespaceAutoloaders($ns));
 -                break;
             }
         }

That's not all.

The effective result of this bug is also that you cannot chain an autoloader for an empty namespace.

To reproduce: 1. Register 'My_' namespace with the autoloader. 2. Invoke pushAutoloader for an empty namespace. 3. Try to autoload a class that starts with 'My_'.

Result: The autoloader pushed in 2. is not added to the list of tried autoloaders.

This bug still exists in 1.11.2.

Exists a problem with array_merge and numeric indexes see: http://pastebin.com/0CHBYRSj, by this that this solution work fine.

Attach a patch with tests.

Greetings Ramon

Fix in trunk r23907 merged to branch release 1.11 r23908 - thanks.