Domanda

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 :

enter image description here

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 ?

È stato utile?

Soluzione

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();

Altri suggerimenti

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.

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.

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;
}

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.

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top