What is Autoloading; How do you use spl_autoload, __autoload and spl_autoload_register?

102,906

Solution 1

spl_autoload_register() allows you to register multiple functions (or static methods from your own Autoload class) that PHP will put into a stack/queue and call sequentially when a "new Class" is declared.

So for example:

spl_autoload_register('myAutoloader');

function myAutoloader($className)
{
    $path = '/path/to/class/';

    include $path.$className.'.php';
}

//-------------------------------------

$myClass = new MyClass();

In the example above, "MyClass" is the name of the class that you are trying to instantiate, PHP passes this name as a string to spl_autoload_register(), which allows you to pick up the variable and use it to "include" the appropriate class/file. As a result you don't specifically need to include that class via an include/require statement...

Just simply call the class you want to instantiate like in the example above, and since you registered a function (via spl_autoload_register()) of your own that will figure out where all your class are located, PHP will use that function.

The benefit of using spl_autoload_register() is that unlike __autoload() you don't need to implement an autoload function in every file that you create. spl_autoload_register() also allows you to register multiple autoload functions to speed up autoloading and make it even easier.

Example:

spl_autoload_register('MyAutoloader::ClassLoader');
spl_autoload_register('MyAutoloader::LibraryLoader');
spl_autoload_register('MyAutoloader::HelperLoader');
spl_autoload_register('MyAutoloader::DatabaseLoader');

class MyAutoloader
{
    public static function ClassLoader($className)
    {
         //your loading logic here
    }


    public static function LibraryLoader($className)
    {
         //your loading logic here
    }

With regards to spl_autoload, the manual states:

This function is intended to be used as a default implementation for __autoload(). If nothing else is specified and spl_autoload_register() is called without any parameters then this functions will be used for any later call to __autoload().

In more practical terms, if all your files are located in a single directory and your application uses not only .php files, but custom configuration files with .inc extensions for example, then one strategy you could use would be to add your directory containing all files to PHP's include path (via set_include_path()).
And since you require your configuration files as well, you would use spl_autoload_extensions() to list the extensions that you want PHP to look for.

Example:

set_include_path(get_include_path().PATH_SEPARATOR.'path/to/my/directory/');
spl_autoload_extensions('.php, .inc');
spl_autoload_register();

Since spl_autoload is the default implementation of the __autoload() magic method, PHP will call spl_autoload when you try and instantiate a new class.

Hope this helps...

Solution 2

Since PHP 5.3, you can use spl_autoload_register() with namespaces, which means that you can organize your project and autoload your php classes without any require or include and without redefining an __autoload() function.

To demonstrate this behaviour, just create a file called index.php :

<?php
spl_autoload_register();
var_dump(new Main\Application);

Then create a folder named Main located right next to the index.php file. Finally, creates a file called Application.php located into Main and paste the following code into it :

<?php namespace Main;
class Application{}

Solution 3

Here is the way I do use Autoload. In the given example I wanto to load classes form 3 diferent directories.

function namespaceAutoload($rawClass){

$class = str_replace('\\', DIRECTORY_SEPARATOR, $rawClass);

$possiblePaths[] = '..\sys\class\file.php';
$possiblePaths[] = '..\sys\class\lib\file.php';
$possiblePaths[] = '..\sys\class\class.file.inc.php';

foreach ($possiblePaths as $templatePath) {
    $path = str_replace(["\\", "file"], [DIRECTORY_SEPARATOR, $class], $templatePath);
    if (file_exists($path)) {
        require_once "$path";
        break;
    }
} spl_autoload_register("namespaceAutoload"); 

I the given example, the PHP will look for the namespace\class in these three directories using these three different filename formats.

Share:
102,906

Related videos on Youtube

Anton
Author by

Anton

Learn new things every day about anything Thanks for visiting my profile. Top 100 SO users in India

Updated on August 01, 2020

Comments

  • Anton
    Anton over 3 years

    I am learning advanced PHP standards and trying to implement new and useful methods. Earlier I was using __autoload just to escape including multiple files on each page, but recently I have seen a tip on __autoload manual

    spl_autoload_register() provides a more flexible alternative for autoloading classes. For this reason, using __autoload() is discouraged and may be deprecated or removed in the future.

    but I really can't figure out how to implement spl_autoload and spl_autoload_register

  • Just Plain High
    Just Plain High over 10 years
    This may be one of the best answers in the history of answers ever. Respect. I had one of those "OMG! It all makes sense now!" moments because of you, my good man. I think I might just start a fan club.
  • Just Plain High
    Just Plain High over 10 years
    A note from my fiddling with all this: spl_autoload() - and thus spl_autoload_register() - converts filenames to lowercase (despite bug reports, pleas and furious voting). This means you might be looking for "Main\Application" but spl_autoload is looking for "main\application". If you like camels, like I do, you're going to have to write your own function. There is a nice starter example here: github.com/ircmaxell/PHP-CryptLib/blob/…
  • Just Plain High
    Just Plain High over 10 years
    To make this the best answer of all answers ever even in alternate universes, please add that spl_autoload very, um, "helpfully" (?) converts all filenames to lowercase (see my comment to @user below). Can't use spl_autoload_register() vanilla if you like your CapitalLettersAndStuff.
  • kyle
    kyle almost 10 years
    @Just Plain High I'm not having that issue and all of my class files are camelcased. BTW, this is a wonderful answer. It helped me get my head around a simple concept that I could just not understand until I read this post! My 85(and growing) line include file that includes all my class files is now 7 lines!
  • SiXoS
    SiXoS almost 10 years
    This is indeed a good answer but I'm missing one thing. What is the actual default functionality? With classes I know, it uses the namespace as path and class name as file name. Although I can't figure out how it works with functions.
  • frozenjim
    frozenjim over 9 years
    In addition to the "camelBack" bug, I have found two details that are required for success: 1)that your included class names must have a single separator or SPL_autoload fails. For example, I was using inc\class.myclass.php when I was using __autoload. Once I switched to SPL_autoload I had to remove the leading "class.". 2) It was not obvious to me that set_include_path() requires an ABSOLUTE path, not relative. So setting it to "inc\" failed as it needed to be "\home\username\projects\thisproject\inc".
  • TommyAutoMagically
    TommyAutoMagically about 9 years
    Isn't one of the huge benefits to using spl_autoload_register() (and __autoload() in general) that it lazy loads include files/classes? This is implied by the answer, but not explicitly stated. To me, this is critical information that would be perfect for inclusion in your answer! :)
  • henrywright
    henrywright almost 9 years
    Just wanted to point out case sensitivity. $className = strtolower( $className ); may come in handy if your file names are lowecase.
  • azerafati
    azerafati almost 9 years
    but then we would require a single include to the MyAutoloader.php in every file, right??
  • stamster
    stamster over 7 years
    Pros: spl_autoload_register() is the fastest method of autoloading Cons: it will work only with lowercase files/classes, and namespaces too, which at this day and age just sux big time (no option to tell it to use CamelCase etc.). But if you can live with namespace/classname.php structure, don't look any further.
  • Mentakatz
    Mentakatz about 7 years
    Thank you for such a clear answer. The official docs were not as good explaining the parameter passed to spl_autoload_register. It makes a lot more sense now.
  • stamster
    stamster over 6 years
    spl_autoload_register() default implementation is unable to find inherited classes. So using defaults, lowercase files and directories reflecting namespace path, everything works fine unless I have a class which extends another class (parent). PHP then throws error that it cannot find that parent class, even they're all in the same directory/namespace! What is confusing is that literally only first level classes are found, so I had to put another spl_autoload_register() with anonymous function rule just after 1st one in order o manually include missing parent / inherited classes.
  • Robo Robok
    Robo Robok over 6 years
    Should you always do "soft including" in spl_autopload_register? Like, you assume that there might be more autoloaders, so just using include will raise a warning every time your autoloader happens to be before some other one, which is valid for some class. By "soft including" I mean checking if file exists first.
  • EternalHour
    EternalHour over 6 years
    @azerafati - That is correct. Wasted some time finding that out for myself when I feel it should have been included (no pun intended) in the answer.
  • Amarjit
    Amarjit over 5 years
    A little late but make sure that the new extension string parameter for spl_autoload_extensions() contains no spaces. spl_autoload_extensions('.php,.inc')