Improving my PHP autoloader I'd like to improve my router.

This is the current code for my autoloading action within my MVC application:

spl_autoload_register(function ($className) {
if (file_exists(ROOT . DS . 'library'  . DS . 'intranet'  . DS  . 'classes' . DS .strtolower($className) . '.php')){
    require_once(ROOT . DS . 'library'  . DS . 'intranet'  . DS  . 'classes' . DS .strtolower($className) . '.php');
} else if (file_exists(ROOT . DS . 'application' . DS . 'controller' . DS . strtolower($className) . '.php')) {
    require_once(ROOT . DS . 'application' . DS . 'controller' . DS . strtolower($className) . '.php');
} else if (file_exists(ROOT . DS . 'application' . DS . 'model' . DS . strtolower($className) . '.php')) {
    require_once(ROOT . DS . 'application' . DS . 'model' . DS . strtolower($className) . '.php');
} else if (file_exists(ROOT . DS . 'application' . DS . 'view' . DS . strtolower($className) . '.php')) {
    require_once(ROOT . DS . 'application' . DS . 'view' . DS . strtolower($className) . '.php');
} else {
throw new exception("$className" class failed to load: file not found");
});


It is looking for the class file in different folder, requiring it. If that fails, an exception is thrown.

It doesn't seem flexible, and I doubt that it'll play well with other libraries and autoloaders that are introduced as the project goes.

How could I improve my existing autoloader?
What you've written is more or less the standard implementation of spl_autoload().

This is an equivalent approach:

$paths = array(
    get_include_path(),
    ROOT . DS . 'library'  . DS . 'intranet'  . DS  . 'classes',
    ROOT . DS . 'application' . DS . 'controller',
    ROOT . DS . 'application' . DS . 'model',
    ROOT . DS . 'application' . DS . 'view',
);

// help system to find your classes
set_include_path(join(PATH_SEPARATOR, $paths));

// use standard auto loader
spl_autoload_register();


Using namespaces in your application would help a lot as well; for instance, in each of your controller classes you simply add:

namespace controller;


When you take a similar approach for models and views as well, you reduce above code to this:

$paths = array(
    get_include_path(),
    ROOT . DS . 'library'  . DS . 'intranet'  . DS  . 'classes',
    ROOT . DS . 'application',
);

set_include_path(join(PATH_SEPARATOR, $paths));

// use standard auto loader
spl_autoload_register();

// ...
$x = new controller\something();


Namespaces are converted to directories by spl_autoload() so you only need to set the application directory to make it work.