2
\$\begingroup\$

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?

\$\endgroup\$
2
  • \$\begingroup\$ Any particular reason why you're not using namespaces? \$\endgroup\$
    – Jack
    Commented Nov 20, 2012 at 23:21
  • \$\begingroup\$ At this moment in time, I'm not extremely comfortable using namespaces, it's something I do plan to implement. The reason I'm not comfortable is because I don't fully understand them. How would I implement it here? \$\endgroup\$
    – bear
    Commented Nov 20, 2012 at 23:23

1 Answer 1

5
\$\begingroup\$

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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.