PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!
This is a question about __autoload() and the correct use of the function. If i had the following two pages, each containing a class and i wished to use '__autoload()' would the following code examples be the correct :
social_experiment wrote:If i had 5 pages that required both or at least one of the classes, would each of those 5 pages contain the code from the implementation excerpt?
More or less yes. I'd advise to move __autoload() definition to separate file and include it though (also rename it to something else and register with spl_autoload_register).
Thanks for the advice, I've put my __autoload() function in a seperate file, included the file, and it works a treat. I've attempted using spl_autoload_register() without success.
social_experiment wrote:Apart from what seems to be a smoother way (using spl_autoload_register()) are there any negative aspects when using __autoload()?
As long as you keep your class files named consistently and arranged in sensible folders so the autoloader doesn't have to do a bunch of random searching all over the file system it should be fine.
In my messy code there are cases where autoload has to search a dozen paths before it finds the right class file. On my test server this has no negative effects but on my severely overburdened production server it can be almost half a second to find the right file via autoload. So unfortunately I wind up always manually including the full path to the files I need specifically.
Using __autoload only allows for one autoloading function. In my experience that's been enough (as it only really has one purpose) - the issue is having multiple paths to search. You can deal with that by coding a more intelligent __autoload that looks at the include_path, which you then modify to include whatever paths to search.
But SPL's autoloader is a more flexible approach. It's quite possible that in the future you'll need a way to (a) include regular classes without any additional work, and (b) include some types of classes and then immediately "register" them somewhere (like with a plugin system). With just __autoload it would be complicated to do that, but with SPL's autoload you can have multiple autoloaders performing different actions.
To be more specific, I create one autoload function and register it with sql_autoload_register. Brief example:
function autoload($classname) {
$path = str_replace("_", DIRECTORY_SEPARATOR, $classname) . ".php";
foreach (explode(PATH_SEPARATOR, get_include_path()) as $search) {
$file = $search . "/" . $path;
if (is_file($file)) {
require_once $file;
return $file; // if autoload() is called manually, returns the filename for the class
}
}
}
spl_autoload_register("autoload");
thinsoldier wrote:As long as you keep your class files named consistently and arranged in sensible folders so the autoloader doesn't have to do a bunch of random searching all over the file system it should be fine.
That's how i normally keep things but i recently started to focus my coding style to a more object-orientated style so i will have multiple class files and i will most likely end up with a lot of 'include_once' statements(my aim is to avoid this). Thanks for the input and advice
tasairis wrote:To be more specific, I create one autoload function and register it with sql_autoload_register
The example you gave, how would i implement it (or something similar to it)? Im assuming i have to call it somewhere on the page that requires my class pages to use it, is this assumption correct? My previous attempts ended up with a exception being thrown at me.
“Don’t worry if it doesn’t work right. If everything did, you’d be out of a job.” - Mosher’s Law of Software Engineering
function autoload($classname) {
$path = str_replace("_", DIRECTORY_SEPARATOR, $classname) . ".php";
foreach (explode(PATH_SEPARATOR, get_include_path()) as $search) {
$file = $search . "/" . $path;
if (is_file($file)) {
require_once $file;
return $file; // if autoload() is called manually, returns the filename for the class
}
}
}
spl_autoload_register("autoload");
I am a little confused why you would manually search the include path, when that is exactly what require_once($path) would do? I would think that internally it would be done in a faster/optimized fashion. I must be missing something obvious.
Christopher wrote:I am a little confused why you would manually search the include path, when that is exactly what require_once($path) would do?
This code has a little subtle difference as opposed to straight require_once - it won't fail if file is not found in include_path. Basically, it's reimplementation of include_once(), but without nasty warnings when file is not found.
Also it could allow to cache class -> filename mappings, including misses (this is not done here though) to avoid repeated lstat()s. This can save you a lot of IO if some of the classes are loaded via second autoloader in chain.