Zend_Loader, horrible. Doesn't care about other autoloaders

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Zend_Loader, horrible. Doesn't care about other autoloaders

Post by Chris Corbyn »

It appears the in ZF, Zend_Loader just goes ahead and turns any class name into a path then tries to include() the file without even checking if the file exists.

This means that you cannot use spl_autoload_register() to add your own autoload logic. Am I missing something or is this as stupid as it sounds? The whole point of spl_autoload_register() was to allow multiple implementations unlike the initial __autoload() incarnation.


From my email exchange:
I've just looked at the code for Zend_Loader. That's horrible, it just tries to include anything that is passed to it without any regard for other autoloaders.

The only real workaround would be to include Swift's swift_required.php file *before* loading Zend_Loader. This seems like a terrible oversight of Zend... what's the point of spl_autoload_register() if they're going to break the fact you can use multiple autoloaders?

Sigh.


On 19/02/2009, at 2:01 AM, Brandon! wrote:


That would appear to be the case. I verified that this still exists
even in the ZF trunk.

Is there a way we can work around this limitation?

Brandon

On Feb 17, 4:55 pm, Chris Corbyn <ch...@w3style.co.uk> wrote:
That's not too good, it looks like zend's autoloader tries to include
classes before checking they exist.

I'll check this further shortly, but it's either a bug in zf or a
misconfiguration in the bootstrap. You didn't by any chance add swift
mailer to the include path did you?

Sent from my iPhone

On 18/02/2009, at 5:42 AM, "Brandon!" <bran...@mens...store.com>
wrote:



I am trying to use this package in an application where another
autoload function are already in use. When I simply include the
swift_required.php file, I receive a few PHP warning messages:
Warning [2] Zend_Loader::include_once(Swift/DependencyContainer.php)
[<a href='zend-loader.include-once'>zend-loader.include-once</a>]:
failed to open stream: No such file or directory
Error on line 83 in file /home/httpd/vhosts/.../httpdocs/lib/Zend/
Loader.php
Warning [2] Zend_Loader::include_once() [<a
href='function.include'>function.include</a>]: Failed opening 'Swift/
DependencyContainer.php' for inclusion (include_path='.:/usr/local/
lib/
php:/home/httpd/vhosts/.../httpdocs:/home/httpd/vhosts/.../httpdocs/
app:/home/httpd/vhosts/.../httpdocs/lib')
Error on line 83 in file /home/httpd/vhosts/.../httpdocs/lib/Zend/
Loader.php
Warning [2] Zend_Loader::include_once(Swift/Preferences.php) [<a
href='zend-loader.include-once'>zend-loader.include-once</a>]: failed
to open stream: No such file or directory
Error on line 83 in file /home/httpd/vhosts/.../httpdocs/lib/Zend/
Loader.php
Warning [2] Zend_Loader::include_once() [<a
href='function.include'>function.include</a>]: Failed opening 'Swift/
Preferences.php' for inclusion (include_path='.:/usr/local/lib/php:/
home/httpd/vhosts/.../httpdocs:/home/httpd/vhosts/.../httpdocs/app:/
home/httpd/vhosts/.../httpdocs/lib')
Error on line 83 in file /home/httpd/vhosts/.../httpdocs/lib/Zend/
Loader.php

Registered autoloaders are:
Array
(
[0] => Array
(
[0] => MUS_Loader
[1] => autoload
)
[1] => swift_autoload
)

Do I have to do something special to get this autoloader to play well
with others? Do I need to tweak my autoloader to work with swift?

Here's my MUS_Loader just in case its relevant:
class MUS_Loader extends Zend_Loader {
public static function autoload($class) {
$response = parent::autoload($class); //trap the response
/* snipped */
return $response;
}
}

Using Swiftmailer 4.0.0-b5 and Zend 1.5.3
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Swift Mailer" group.
To post to this group, send email to swiftmailer@googlegroups.com
To unsubscribe from this group, send email to swiftmailer+unsubscribe@googlegroups.com
For more options, visit this group at http://groups.google.com/group/swiftmailer?hl=en
-~----------~----~----~----~------~----~------~--~---
User avatar
Eran
DevNet Master
Posts: 3549
Joined: Fri Jan 18, 2008 12:36 am
Location: Israel, ME

Re: Zend_Loader, horrible. Doesn't care about other autoloaders

Post by Eran »

spl_autoload operates by the order the autoload stack, and unfurtunately Zend's autoloader is greedy. You might want to file a bug report on that.

In the meantime, you can change yourself the order of the autoload stack by getting the registered callbacks using spl_autoload_functions(), unregistering those and then re-registering with yours first in the stack.
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Re: Zend_Loader, horrible. Doesn't care about other autoloaders

Post by Chris Corbyn »

pytrin wrote:spl_autoload operates by the order the autoload stack, and unfurtunately Zend's autoloader is greedy. You might want to file a bug report on that.

In the meantime, you can change yourself the order of the autoload stack by getting the registered callbacks using spl_autoload_functions(), unregistering those and then re-registering with yours first in the stack.
I'll give that a go, cheers.

I'm still quite annoyed that something as "get out of the way" as ZF would have such a crap autoloader. I think I know why they can't check file_exists() or anything now though... they rely on include_path settings and there's no such function along the lines of (file_on_inclide_path()) that I'm aware of anyway.
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Re: Zend_Loader, horrible. Doesn't care about other autoloaders

Post by Chris Corbyn »

That fixes one problem, thanks :) But now I have another (urelated) ZF autoloader problem.

It wants to include parent.php due to my use of "parent" inside call_user_func_array().
Warning: Zend_Loader::include_once(parent.php) [zend-loader.include-once]: failed to open stream: No such file or directory in /WebDev/swiftmailer/library/Zend/Loader.php on line 83
That seems like madness.

a) The autoloader should not be triggered on the user of "parent"
b) ZF's autoloader should not be trying to include a file that doesn't exist

I'd rather get a "Class not found" error than a failed include_once() call.
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Re: Zend_Loader, horrible. Doesn't care about other autoloaders

Post by Chris Corbyn »

Using Reflection instead of call_user_func_array() fixes the autoloader being triggered for "parent". Slight overhead there but not much.
User avatar
allspiritseve
DevNet Resident
Posts: 1174
Joined: Thu Mar 06, 2008 8:23 am
Location: Ann Arbor, MI (USA)

Re: Zend_Loader, horrible. Doesn't care about other autoloaders

Post by allspiritseve »

Chris Corbyn wrote:I think I know why they can't check file_exists() or anything now though... they rely on include_path settings and there's no such function along the lines of (file_on_inclide_path()) that I'm aware of anyway.
Is there an alternative? I have been explode()ing the include path and checking each location for the file, but that doesn't seem very efficient to me. I'd love to find a better way.
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Re: Zend_Loader, horrible. Doesn't care about other autoloaders

Post by Chris Corbyn »

allspiritseve wrote:
Chris Corbyn wrote:I think I know why they can't check file_exists() or anything now though... they rely on include_path settings and there's no such function along the lines of (file_on_inclide_path()) that I'm aware of anyway.
Is there an alternative? I have been explode()ing the include path and checking each location for the file, but that doesn't seem very efficient to me. I'd love to find a better way.
I think exploding the include path would be the best way to go in terms of robustness yeah.

PHP itself has to check each location on the include path when it loads the file too.
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: Zend_Loader, horrible. Doesn't care about other autoloaders

Post by Weirdan »

allspiritseve wrote:
Chris Corbyn wrote:I think I know why they can't check file_exists() or anything now though... they rely on include_path settings and there's no such function along the lines of (file_on_inclide_path()) that I'm aware of anyway.
Is there an alternative? I have been explode()ing the include path and checking each location for the file, but that doesn't seem very efficient to me. I'd love to find a better way.
I do that a bit differently:

Code: Select all

 
function autoload($class) {
   $filename = str_replace('_', '/', $class) . '.php';
   if ($fp = @fopen($filename, 'r', true)) {
        fclose($fp);
        include $filename;
        return;
   }
}
 
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: Zend_Loader, horrible. Doesn't care about other autoloaders

Post by josh »

Check out my loader extension http://joshribakoff.com/2009/02/subclas ... w-helpers/ 2nd part of post.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Zend_Loader, horrible. Doesn't care about other autoloaders

Post by Christopher »

Chris Corbyn wrote:
allspiritseve wrote:Is there an alternative? I have been explode()ing the include path and checking each location for the file, but that doesn't seem very efficient to me. I'd love to find a better way.
I think exploding the include path would be the best way to go in terms of robustness yeah.

PHP itself has to check each location on the include path when it loads the file too.
I remember dealing with this problem too. Part of the problem is that you want your cake and eat it too -- meaning both relative paths and absolute paths to just work. I recall that I got around this by doing a file check if the path was absolute, but the main check was to do the include (which unlike require only give a Warning) and then check if the class exists. The class exists check determines success, as this is a class loader.

In general going around PHP and checking search paths sounds like a bad idea as you lose any future improvements and who know how it would work with a cache.
(#10850)
Post Reply