It is recommended to use only one extension for all classes. PHP (more exactly spl_autoload) does the rest for you and is even quicker than a semantically equal self-defined autoload function like this one:

I compared them with the following setting: There are 10 folders, each having 10 subfolders, each having 10 subfolders, each containing 10 classes.

To load and instantiate these 1000 classes (parameterless no-action constructor), the user-definded autoload function approach took 50ms longer in average than the spl_autoload function in a series of 10 command-line calls for each approach.

I made this benchmark to ensure that I don't recommend something that could be called "nice, but slow" later.

When switching from using __autoload() to using spl_autoload_register keep in mind that deserialization of the session can trigger class lookups.

This works as expected: <?phpsession_start();function __autoload($class) {...}?>

This will result in "__PHP_Incomplete_Class_Name" errors when using classes deserialized from the session.<?phpsession_start();function customAutoloader($class) {...}spl_autoload_register("customAutoloader");?>

So you need to make sure the spl_autoload_register is done BEFORE session_start() is called.

If you have multiple autoloaders registered, and one (or more) throws an exception before a later autoloader loads the class, stacked exceptions are thrown (and must be caught) even though the class was loaded successfully.

What I said here previously is only true on Windows. The built-in default autoloader that is registered when you call spl_autoload_register() without any arguments simply adds the qualified class name plus the registered file extension (.php) to each of the include paths and tries to include that file.

Example (on Windows):

include paths:- "."- "d:/projects/phplib"

qualified class name to load:network\http\rest\Resource

Here's what happens:

PHP tries to load'.\\network\\http\\rest\\Resource.php'-> file not found

PHP tries to load'd:/projects/phplib\\network\\http\\rest\\Resource.php'-> file found and included

Note the slashes and backslashes in the file path. On Windows this works perfectly, but on a Linux machine, the backslashes won't work and additionally the file names are case-sensitive.

That's why on Linux the quick-and-easy way would be to convert these qualified class names to slashes and to lowercase and pass them to the built-in autoloader like so:

But this means, you have to save all your classes with lowercase file names. Otherwise, if you omit the strtolower call, you have to use the class names exactly as specified by the file name, which can be annoying for class names that are defined with non-straightforward case like e. g. XMLHttpRequest.

I prefer the lowercase approach, because it is easier to use and the file name conversion can be done automatically on deploying.

./kate.melmac.php<?phprequire_once("alf.home.php");/* * the normal way is to get ALF * and register an autoloading function */$alf = new ALF();spl_autoload_register(array($alf,'haaahaaahaaa'));$alf->haaahaaahaaa(); // ALF is from Melmac :)/* * now lets try to autoload a class */@$kate = new Kate(); // this throws a fatal error because // Kate is NOT from Melmac :)?>I am ALF from Melmac.I am Kate from Melmac.

./kate.earth.php<?phprequire_once("alf.home.php");/* * BUT what if we want to correct Kates origin ? * How can one pass parameters to an autoloading function * upon registering? * * spl_autoload_register is not suitable for that * but we can try is to define a callable during registration */spl_autoload_register(function($class){ call_user_func(array(new ALF(),'haaahaaahaaa'), $class, "Earth"); });/* * now lets try again to autoload a class * Kate will still not be found but we corrected her origin :) */@$kate = new Kate(); // Kate is from Earth :)/* * NOTE: that you cannot pass $this or another object created * outside of the callable context using the * registering way above. therefor you should swap your autoloading * function to a seperate class as done at the beginning with ALF. * * NOTE: you may not able to unregister your autoloading function * directly as an instance was created in another context */?>I am Kate from Earth.

I develop on OS X and everything was working fine. But when releasing to my linux server, none of my class files were loading. I had to lowercase all my filenames, because calling a class "DatabaseObject" would try including "databaseobject.php", instead of "DatabaseObject.php"

I think i'll go back to using the slower __autoload() function, just so i can keep my class files readable

Editorial note: The appropriate PHP bug that requests behavior this function emulates is http://bugs.php.net/bug.php?id=42823 . This function does NOT work if there has been an array($obj, 'nonStaticMethod') registered in the autoload stack--while the autoload will be removed, it will be re-registered incorrectly.

The spl_autoload_register() method registers functions in its stack in the order that spl_autoload_register() was called, and subsequently if you want an autoload function to override previous autoload functions you will either need to unregister the previous ones or change the order of the autoload stack.

For example, say in your default implementation of an autoload function you throw an exception if the class cannot be found, or perhaps a fatal error. Later on in your code you add a second implementation of an autoload function which will load a library that the previous method would fail on. This will not call the second autoloader method first, but rather will continue to error out on the first method.

As previously mentioned, you can unregister the existing autoloader that errors out, or you can create a mechanism for unregistering and re-registering the autoloaders in the order you want.

Here is a sample/example of how you might consider re-registering autoloaders so that the newest autoloader is called first, and the oldest last:

<?php

// Editorial notes: Small bug and compatibility fixes
// added to the function

It is never a good idea and a unconscienable concept to create the classes in the autoload function via eval. It should be a nice feature with these Exception, but i think anyone is able to handle it without this method although. Atm i dont realize for what this is good for...

As i might note, class_exists() will ever define the classes u only want to check for existance, and will therefor ever return true:<?phpfunction EvalIsEvil($class) { eval('class '.$className.'{}');}spl_autoload_register('EvalIsEvil');if (class_exists($s="IsMyModuleHere")) {// this is no module, but get there with eval()...return new $s();}?>

// Looping through each directory to load all the class files. It will only require a file once. // If it finds the same class in a directory later on, IT WILL IGNORE IT! Because of that require once!foreach( $dirs as $dir ) { if (file_exists($dir.'class.'.strtolower($class_name).'.php')) { require_once($dir.'class.'.strtolower($class_name).'.php'); return; } } });

if you have a dir-structure like "/abc/def/ghi", your index.php lies in the top directory, but you want to use namespaces starting with "def" or "ghi":

you can switch the namespace root directory of php with e.g. set_include_path(__DIR__ . '/abc') and afterwards define + use your namespaces with the simple spl_autoload_register() function without any arguments supplied.

I've made a little function that makes and registers a loader that seems to be safe and reliable although I'm not sure but it feels like a good idea to share, it took me some time to come up with it I hope it saves someone some time,

if you have a file system exactly like your directory tree this function works perfectly, I haven't tested it on unix, but on windows, the default loader fails when your webpage isn't in the root directory, this makes sure that it won't cause a problem if your webpage is on a subdir too just pass ../ or more drived ../../ as root and it will work like a charm, note that i couldn't use anonymous functions because then the $root variable wouldn't have the same scope as the Loader function, so the function must be created on the fly. this is a good example of this functions usage

your class:root/classes/support/classic.php<?php

namespace classes/support;

class classic {// class def}

?>

root/support/index.php<?php

Loader('../');

use classes/support/classic;

$cls = new classic();//use $cls?>

the loader will make a function like this:<?php

function($class) { include "../$class.php";}

//when and when the class is needed this will run the script which is indeed what we need: