ZF-8364: Zend_Loader_Autoloader_Resource::autoload() should return false if no match is found

Issue Type: Bug Created: 2009-11-20T14:09:18.000+0000 Last Updated: 2009-11-25T00:37:50.000+0000 Status: Resolved Fix version(s): - 1.9.6 (24/Nov/09)

Reporter: Adam Jensen (jazzslider) Assignee: Marco Kaiser (bate) Tags: - Zend_Loader

Related issues: Attachments: - library.diff


Currently (r19141 of the standard trunk), the resource autoloader can produce some unexpected PHP warnings if it accidentally attempts to autoload something that doesn't exist. E.g.:

  1. Create and configure an instance of the resource autoloader; for example:

     require_once 'Zend/Loader/Autoloader.php';
     require_once 'Zend/Loader/Autoloader/Resource.php';
     $autoloader = new Zend_Loader_Autoloader_Resource(array(
         'namespace' => 'My',
         'basePath' => '/path/to/my',
     ));$autoloader->addResourceType('resource', 'resources', 'Resource');
  2. Attempt to instantiate a class that doesn't exist, but would be in the configured namespace:

     $obj = new My_Resource_DoesNotExist();

At this point you'll get two PHP errors. The first is an E_WARNING message indicating that you tried to include a file that doesn't exist; the second is an E_FATAL message indicating that you tried to instantiate a class that doesn't exist.

However, if the behavior of Zend_Loader_Autoloader::autoload() is any indicator, Zend_Loader_Autoloader_Resource::autoload() should instead return false if the expected class cannot be found. This will get rid of the first E_WARNING message and enable a bit more flexible error handling.

For an example of why this would be helpful, please take a look at : Doctrine has a feature that will generate a certain class on the fly if it can't be autoloaded; if the current ZF resource autoloader is registered, this will still work correctly ...but not without generating the E_WARNING message mentioned earlier.

Thanks! Adam


Posted by Adam Jensen (jazzslider) on 2009-11-20T14:18:28.000+0000

On further inspection, I realized it's not the return value of autoload() that's causing this fact, it's returning false for classes-not-found, just as documented.

However, I do think it would be worth avoiding the E_WARNING messages. Developers will still get enough error information out of the E_FATAL message that follows it when a non-existing class is being instantiated ...and in the meantime, other situations (like Doctrine's use of class_exists()) would still function gracefully without emitting any errors.

I should be attaching a patch shortly; if this sounds like a good idea, it'd be a pretty easy fix.

Thanks! Adam

Posted by Adam Jensen (jazzslider) on 2009-11-20T14:23:47.000+0000

OK, I've attached my patch ...I made this from the library dir of the standard trunk; is that the right way to do that?

In any case, this should prevent any superfluous E_WARNINGs by avoiding the include call unless the path is valid.

Thanks! Adam

Posted by Adam Jensen (jazzslider) on 2009-11-20T14:44:56.000+0000

Found a couple of other issues that seem to be related to the same problem:

If my patch is accepted here, it may be worth double-checking if those two issues are resolved as well; I believe they will be.

Posted by Adam Jensen (jazzslider) on 2009-11-20T17:55:25.000+0000

Better patch my first version, I rather unthinkingly left it calling getClassPath() twice; this one doesn't make that mistake.

Posted by Adam Jensen (jazzslider) on 2009-11-20T21:26:32.000+0000

Turns out the previously-attached patch didn't really solve the problem, because getClassPath() is apparently only returning false when the class name isn't in any of the autoloader's registered namespaces still doesn't check to see if the file actually exists.

Seems this could be resolved by adding a file_exists() or Zend_Loader::isReadable() call at the end of getClassPath(); that way, the autoloader can simply fail silently for any files it can't figure out, allowing other autoloaders to take care of it if they can ...and if no registered autoloaders can handle it, the standard E_FATAL "class does not exist" error will still be emitted.

I've attached a fresh patch that should accomplish all this nicely enough.

Thanks! Adam

Posted by Marco Kaiser (bate) on 2009-11-23T00:03:36.000+0000

fixed in r19187 please check an close if finally fixed

Posted by Erik Wegner (eman) on 2009-11-23T02:28:50.000+0000

Maybe the wrong variable name is used in line 195? It currently reads

return $path;

but shouldn't it be

return $classPath;


Posted by Erik Wegner (eman) on 2009-11-23T02:31:35.000+0000

see comment

Posted by Daniel Berstein (danielb) on 2009-11-23T03:32:01.000+0000

Please commit Erik's patch, as it currently stands ZF autoloader is broken and you get errors/warnings like these:

Notice: Undefined variable: path in .../lib/Zend/Loader/Autoloader/Resource.php on line 195

Warning: Zend_Loader_Autoloader_Resource::include() [function.include]: Failed opening '' for inclusion (include_path='.../lib:.:/usr/share/php') in .../lib/Zend/Loader/Autoloader/Resource.php on line 195

Fatal error: Class 'Default_Model_Abstract' not found in ... on line 38


Posted by Marco Kaiser (bate) on 2009-11-23T04:40:33.000+0000

fixed the small typo in r19189

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.