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?
-
\$\begingroup\$ Any particular reason why you're not using namespaces? \$\endgroup\$Jack– Jack2012年11月20日 23:21:16 +00:00Commented 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– bear2012年11月20日 23:23:06 +00:00Commented Nov 20, 2012 at 23:23
1 Answer 1
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.