I'm actually trying to create a MVC framework for my own, however I'm having troubles with the Autoload. It's not a problem actually, but I'd like to ask the gurus, how are they using the spl_autoload_register
function when there are different directories.
Lets say we have the following directories:
Controllers
Libs
Models
Each folder contains different classes, like:
Controllers:
Main.php
File.php
About.php
Libs:
Main.php
Front_controller.php
Models:
Index.php
File.php
Login.php
You can notice that some file names might be found with the same name in different directories. Okay, so this is what I've tried so far:
spl_autoload_register(function ($class) {
$pathContorllers = 'Controllers/' . $class . '.php';
$pathLibs = 'Libs/' . $class . '.php';
$pathModels = 'Models/' . $class . '.php';
if (file_exists($pathContorllers)) {
require_once $pathContorllers;
} elseif (file_exists($pathLibs)) {
require_once $pathLibs;
} elseif (file_exists($pathModels )) {
require_once $pathModels ;
}
});
It is working well, however I'm sure that there is another way to make everything simpler. Can anyone suggest me how can I make this code better or simpler / what are gurus using in this situation?
Updated Answer
The PHP-FIG has officially deprecated the PSR-0 standard in favor of the alternative autoloader, PSR-4. Although the two are similar in some aspects they are also very different in others. (E.g.: the handling of underscores in class names.)
You may be thinking to yourself -- "I use PSR-0 now and it works fine." The truth of the matter is that PSR-0 will still work fine for certain projects. This is especially true when backwards compatibility with a package that doesn't use namespaces is concerned. PSR-0 is still a decent autoloading principle, but it has its own shortcomings.
Of course, if there is one thing that is a constant with programming, it is that code eventually changes and programming techniques continue to evolve. You can do yourself a favor today by preparing yourself for tomorrow. Therefore, if you are just starting a project or are trying to port a project to a newer version of PHP that can use namespaces, you should seriously consider using the PSR-4 autoloader.
It is also worth noting that if you are developing a project that does not use namespaces then PSR-4 does not apply to you. In this case PSR-0 or your own custom autoloader applies.
Original Answer
If you want to go with namespaces in your classes, then the PSR-0 route is a pretty good way to autoload. Basically your namespace represents you directory structure and classes can be loaded based on a convention.
If the PSR-0 method doesn't meet all your needs (or doesn't play nice with existing code) you can still add more functions with
spl_autoload_register
and PHP will go through them one by one in an attempt to load classes.Example usage:
First thing is first, if you aren't familiar with namespaces in PHP then you will benefit from checking out the PHP manual on the subject. They can be a bit confusing at first, but their benefits are worth the initial confusion.
So I said that PSR-0 works by associating your namespaces with your directory structure. Let's use your directories for an example. You have in your root folder (wherever it may be) the following:
Now let's take a look at your controller
Main.php
. Two things to keep in mind is that the class name needs to be the name of the file and the namespace for that class is the directory path to that file. SoMain.php
should look something like this:You would do the same thing for your your
Login
modelNow in your
index.php
file (out in the root directory -MyProject
) you would make your call to thespl_autoload_register
and give it the PSR-0 autoloader.Hopefully that helps make better sense of it, and again, if you don't want to use namespaces you can always just keep adding closures into the SPL autoload stack. You can have 10 different autoloaders in there if you want and PHP will go through them one by one (in the order you defined them) using each function to try and load a class. However, a couple convention based autoloaders is a bit cleaner and more of a preferred method. Also keep in mind that the autoloader translates both namespace separators
\
and underscores_
as a directory separator. So yourFront_controller.php
would not autoload as you would expect.