问题
I'm working on the development of a custom framework. And I have encountered an issue when I tried to dynamise the calling of my classes.
This is a visual of my files :
So I decided to create a different function for each folder (libs, controllers et modeles):
function autoloadLibs($class) {
//require the general classes
require 'libs/' . $class . '.php';
}
function autoloadModels($class) {
//require the models classes
require 'models/' . $class . '.php';
}
function autoloadControllers($class) {
//require the controllers classes
require 'controllers/' . $class . '.php';
}
spl_autoload_register ('autoloadLibs');
spl_autoload_register ('autoloadControllers');
spl_autoload_register ('autoloadModels');
Nevertheless I have this message : Warning: require(libs/admin.php): failed to open stream, of cours it's not the good folder. But I don't know how to fix that. Is there a good way to optimise my classes calls ?
回答1:
After few tests, I found this solution for my case :
set_include_path(implode(PATH_SEPARATOR, array(get_include_path(), './libs', './controllers', './models')));
spl_autoload_register();
回答2:
You need to check the file exists first with is_file() before you attempt to require it.
When using spl_autoload_register(), I've found it's generally better to register one method to include the files. The fact that you can bing multiple functions I believe is to make interoperability with different libraries easy (so they don't clobber __autoload()). It will also save you having to write the code out multiple times to check for the file's existent, map _ to directory separator (if you do that), etc.
So, assuming you change your filenames to suit the convention of Underscore_Separated_Name, e.g. Controller_Admin_Dashboard, you could use...
function autoload($className) {
$path = SYSPATH .
str_replace("_", DIRECTORY_SEPARATOR, strtolower($className)) .
".php";
if (is_file($path)) {
require $path;
}
}
The first time you instantiate Controller_Admin_Dashboard, PHP may include a file such as /app/controller/admin/dashboard.php.
回答3:
If you have multiple spl_autoload_register calls you need to make sure you don't use the require keyword to include the files, because this means "include the file or die if it can't".
Personally I disagree with others about only having one autoload function, especially if you are including classes from different locations, such as a controllers versus some library directory. I also check if the file exists first, then include it.
tl;dr version: Don't allow spl_autoload_register calls to block each other.
回答4:
your answer is here. when you are registering multiple autoloaders, php try to load a class by anyone of those autoloaders, Then, php calls those autoloaders from the first registered to the last. Then, in anyone of those autoloaders you should check that file_exists or not, else, php try to include it and throws an error if that file does not exist. Then, before inclusion, check existance of file. Change Your Autoloaders To:
function autoloadLibs($class)
{
#require the general classes
$file = 'libs/' . $class . '.php';
if(file_exists($file))
require $file;
}
function autoloadModels($class)
{
#require the models classes
$file = 'models/' . $class . '.php';
if(file_exists($file))
require $file;
}
function autoloadControllers($class)
{
#require the controllers classes
$file = 'controllers/' . $class . '.php';
if(file_exists($file))
require $file;
}
回答5:
You should check class names before requiring the file, for example:
function autoloadControllers($class) {
//require the controllers classes
if( substr( $class, -10) == 'Controller')){
require 'controllers/' . $class . '.php';
}
}
I find it correct to cause error if class cannot be loaded, but you should make sure that require is called only on correct path.
回答6:
Note that spl_autoload_register provides a third parameter (prepend). You can set this to true if you wish to place a specific autoload function on top of the autoload stack. This means that this specific function will then be called first.
Example:
spl_autoload_register(array('My_Class', 'My_Method'), true, true);
http://www.php.net/manual/en/function.spl-autoload-register.php
来源:https://stackoverflow.com/questions/12914195/multiple-spl-autoload-register-issue