include path and the __autoload function in php

cskwrd picture cskwrd · Jul 21, 2010 · Viewed 10.5k times · Source

I am trying to convert several php scripts to use the __autoload function. Right now I can use the include and require functions like this:

require_once('path/to/script.php');

But inside of the __autoload function, I can't use the line above. I have to use this:

require_once('absolute/path/to/script.php');

Why does it seem as though the __autoload function doesn't use the include path I have specified in php.ini?

Answer

ircmaxell picture ircmaxell · Jul 21, 2010

Don't use __autoload... It has a few drawbacks (including limiting yourself to one per execution). Use instead spl_autoload_register if you're on 5.2+.

So what I typically do, is have a class:

class AutoLoader {
    protected static $paths = array(
        PATH_TO_LIBRARIES,
    );
    public static function addPath($path) {
        $path = realpath($path);
        if ($path) {
            self::$paths[] = $path;
        }
    }
    public static function load($class) {
        $classPath = $class; // Do whatever logic here
        foreach (self::$paths as $path) {
            if (is_file($path . $classPath)) {
                require_once $path . $classPath;
                return;
            }
        }
    }
}
spl_autoload_register(array('AutoLoader', 'load'));

That way, if you add a library set, you can just "add it" to your paths by calling AutoLoader::AddPath($path);. This makes testing with your autoloader a LOT easier (IMHO).

One other note. Don't throw exceptions from the autoload class unless absolutely necessary. The reason is that you can install multiple autoloaders, so if you don't know how to load the file, another one may exist to load it. But if you throw an exception, it'll skip the other one...

Personally, I don't ever like to use relative paths with includes. Especially with multiple include directories (like pear), it makes it very difficult to know exactly which file is being imported when you see require 'foo/bar.php';. I prefer to define the absolute path in the beginning of the file set define('PATH_ROOT', dirname(__FILE__));, and then define all my other useful paths off of that directory (PATH_LIBRARIES, PATH_TEMPLATES, etc...). That way, everything is absolutely defined... And no need to deal with relative paths (like the issue you're having now)...