ZF-10836: ZLAutoloader_Resource should check its constructors params order to make sure "namespace" is handled before "resourceTypes"

Description

Assuming such a completely valid code :


$data = array('basePath' => '/foo', 'resourceTypes' => array(/* my stuff */), 'namespace' => 'Foo');
new Zend_Loader_Autoloader_Resource($data);

That wont work as you could imagine. The constructor invoke setters, but in $data input, setResourceTypes() will be treated before setNamespace(). The fact is that resourceTypes make use of the namespace, not set yet; the behavior is not what expected as resourceTypes will use a completly wrong namespace and autoloading will fail

A simple ksort() on the input array could sort the keys such that 'namespace' is beeing handled before 'resourceTypes'

Comments

Interesting find! I've attached a patch which reproduces the issue, and a possible fix. Essentially I updated Zend_Loader_Autoloader_Resource::setOptions to shift the 'namespace' key to the beginning of the array, so that it is processed first. This should be a more robust solution than sorting the keys. Comments?


// If namespace key exists, shift it to be beginning of the options array
// so that it is processed first
// @see ZF-10836
$namespaceIndex = array_search('namespace', array_keys($options));
if ( $namespaceIndex !== false )
{
    $namespace = $options['namespace'];
    unset($options['namespace']);
    $options = array('namespace'=>$namespace) + $options;
}

@Adam I think that could be but simple


if (array_key_exists('namespace', $options)) {
    $this->setNamespace($options['namespace']);
    unset($options['namespace']);
}

Thanks advance

@Ramon Thanks! That is much simpler. I've updated my patch with your code.

Removed @ from @see comment in patch, as it wasn't in a docblock. Changed array_key_exists to isset (namespace can't be null, and isset is faster)

Fixed a typo

Applied to trunk in r23567, merged to release branch 1.11 in r23568.