-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Do not exit from loadClass() early #5783
Do not exit from loadClass() early #5783
Conversation
In loadClass(), if the namespace/prefix matches, but the classfile is not found, we were returning a boolean false immediately. However, if a more specific namespace/prefix matches, but is later in the stack, we're essentially ignoring it, making the class unreachable. This patch removes the `return false` line in the `foreach` loop, allowing a namespace registered later to match and potentially fulfill the autoloading. There _will_ be a performance impact, which means it's always better to register the more specific namespace earlier.
$loader = new StandardAutoloader(); | ||
$loader->registerNamespace('ZendTest\Loader\TestAsset\Parent', __DIR__ . '/TestAsset/Parent'); | ||
$loader->registerNamespace('ZendTest\Loader\TestAsset\Parent\Child', __DIR__ . '/TestAsset/Child'); | ||
$loader->autoload('ZendTest\Loader\TestAsset\Parent\Child\Subclass'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you assert on the return value? Can't really know if it was autoloaded by a different loader, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fact that no PHP errors are raised is indicative of the fact that it did not attempt to include
a file it could not. However, I can likely do an assertion against !== false
to validate; will update with that shortly.
Just to clarify here for anyone who references back to this PR later, the performance impact mentioned by @weierophinney is only applicable if you fall into this scenario where you do in fact have a more specific, overlapping namespace registered later. This is a very, very specific edge-case and unlikely to affect any current applications in practice (they would have simply ran into this bug). 😄 |
Merge branch 'hotfix/standard-autoloader-stack' of git://github.com/weierophinney/zf2 into weierophinney-hotfix/standard-autoloader-stack * 'hotfix/standard-autoloader-stack' of git://github.com/weierophinney/zf2: [#5783] Assertion on return value Do not exit from loadClass() early
Merge branch 'weierophinney-hotfix/standard-autoloader-stack' into develop * weierophinney-hotfix/standard-autoloader-stack: [#5783] Assertion on return value Do not exit from loadClass() early
Merge branch 'hotfix/standard-autoloader-stack' of git://github.com/weierophinney/zf2 into weierophinney-hotfix/standard-autoloader-stack * 'hotfix/standard-autoloader-stack' of git://github.com/weierophinney/zf2: [zendframework/zendframework#5783] Assertion on return value Do not exit from loadClass() early
Merge branch 'weierophinney-hotfix/standard-autoloader-stack' into develop * weierophinney-hotfix/standard-autoloader-stack: [zendframework/zendframework#5783] Assertion on return value Do not exit from loadClass() early
In loadClass(), if the namespace/prefix matches, but the classfile is not
found, we were returning a boolean false immediately. However, if a more
specific namespace/prefix matches, but is later in the stack, we're
essentially ignoring it, making the class unreachable.
This patch removes the
return false
line in theforeach
loop, allowing anamespace registered later to match and potentially fulfill the autoloading.
There will be a performance impact, which means it's always better to
register the more specific namespace earlier.