PHP multiple __autoload functions *without* the use of spl_register_autoload?
I'm an author of a growing library of PHP + QuickBooks related code. I'd like to utilize PHPs __autoload() function, however my code is a library that other people can include() into their own applications, so I can't rely on __autoload() being not already defined.
Is there a way to have multiple __autoload() functions?
I saw spl_autoload_register() 开发者_如何学Cin the PHP manual, but not all of my users have the SPL extension installed, so I can't rely on that. If there was a way to fall-back to using this and use normal require/include statements by default, I might consider that.
Does anyone else have any other clever solutions to this issue? It seems like a glaring oversight to only be able to have a single __autoload() function...
I saw spl_autoload_register() in the PHP manual, but not all of my users have the SPL extension installed, so I can't rely on that.
Ignore them, it's compiled in by default and can't even be disabled in 5.3.0. Don't sacrifice your framework to please the minority.
I have decided that the way to go about this and also preserve backward compatibility is to write my own "Loader" class.
Instead of using require_once 'TheFile.php', I now use Loader::load('TheFile.php');. The Loader::load() method does the following:
if ( the function spl_autoload_register exists )
register an autoloader
return true
else
check if the file has already been included (static array var with a list of files)
if not included yet
require $file
return true
This gives me the flexibility to use the autoloader if their PHP installation supports it, and otherwise fall back to just doing normal require $file; type stuff.
You could write an __autoload function that simply loops over an array of callbacks that do the actual class loading until the class has been found or until the list has been exhausted.
function loader1 ($className)
{
if (is_file ('foo/' . $clasName))
{
include ('foo/' . $className);
return (true);
}
}
function loader2 ($className)
{
if (is_file ('bar/' . $clasName))
{
include ('bar/' . $className);
return (true);
}
}
function loader3 ($className)
{
if (is_file ('baz/' . $clasName))
{
include ('baz/' . $className);
return (true);
}
}
function __autoload ($className)
{
$autoloaders = array (
'loader1',
'loader2',
'loader3'
);
foreach ($autoloaders as $loader)
{
if ($loader ($className))
return (true);
}
throw new Exception ('Failed to find class ' . $className);
}
NOTE: This is "off the cuff", I've not tested it.
精彩评论