Why and How to use spl_autoload_register?

|
| By Webner

Purpose and Usage of spl_autoload_register with example

__autoload is an older method. This method was first introduced in PHP 5 as a magic function but now this method is deprecated as of PHP version 7.2.0. If we want our code to be compatible with the future versions of PHP then we should not use it in our code. We should start using the new method spl_autoload_register which has more flexibility then __autoload function. We should only use __autoload method when you know that your current PHP version does not support spl_autoload_register method.
Note : The __autoload() function can also be used for autoloading classes and interfaces but its preferred to use the spl_autoload_register() function. This is because it is a more flexible alternative (enabling for any number of autoloaders to be specified in the application, such as third party libraries).

Advantages

Any number of autoloaders can be enabled in the applications.
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.
spl_autoload_register() is called without any parameters.
spl_autoload_register() is the fastest method of autoloading.

Disadvantage

It will work only with lowercase files/classes, and namespaces too (no option to tell it to use CamelCase etc.).
spl_autoload_register() default implementation is unable to find inherited classes.

Parameters

Autoload_function
If no parameter is provided, then the default implementation of spl_autoload() will be registered.

Throw
To throw exceptions when the autoload_function cannot be registered.

Prepend
If true, spl_autoload_register() will prepend the autoloader on the autoload queue instead of appending it.

Returns TRUE on success or FALSE on failure.

There is an examples for the benefit of developers.

When using autoloaders with SPL autoload register function first of all when we run the script it produces fatal error , which says class hello not found as you can see here:

<?php
$Hello = new Hello();
$Word  = new World();
$World = new MyController();
?>

Output:-

Fatal error: Uncaught Error: Class ‘Hello’ not found in C:\xampp\htdocs\test\classes_and_objects\autoloading\example.php:2 Stack trace: #0 {main} thrown in C:\xampp\htdocs\test\classes_and_objects\autoloading\example.php on line 2

This is because we didn’t include autoloader which could find it and include it for us. So let’s try to add these classes manually in our script and now it works perfectly fine as you can see by the output. All classes are successfully loaded and can be used.

Example:-

<?php

require_once '../autoloading/classes/class_hello.php';
require_once '../autoloading/classes/templates/main/class_world.php';
require_once '../autoloading/classes/controllers/class_my_controller.php';

$Hello = new Hello();
$World = new World();
$World = new MyController();
?>

Output:-
Hello class is load.
World class is load.
Controller class is load.

Problem in above method:- It creates a PHP resource file per class definition that is the standard practice for the developers who are writing object-oriented applications. So you have to write the required list at the beginning of every script and the list can be different in several scripts. You will need to find out that every time what you have written is correct and you have to manage it. This is where SPL register function comes to the rescue. So, now in this example we are using autoloader and as you can see it still shows the same output that means all classes are loaded.

<?php
if (!isset($_SERVER["REMOTE_ADDR"]) || $_SERVER["REMOTE_ADDR"] == 'localhost') {
    define("_CLIENT_PATH", 'C:/xampp/htdocs/test');
} else {
    define("_CLIENT_PATH", 'C:/xampp/htdocs/test/');
}
spl_autoload_register(function($className)
{
    //example: "MyController" is converted to "my_controller"  
    $fileName = strtolower(preg_replace('/(?<!^)[A-Z]/', '_$0', $className));
    //by our convention all class are looking like this "class_my_contoller.php"
    $fileName = "class_" . $fileName . ".php";
    $paths    = array(
        '',
        'templates',
        'templates/main',
        'templates/list',
        'Controllers'
    );
    foreach ($paths as $path) {
        $curPath = _CLIENT_PATH . "classes_and_objects/autoloading/classes/" . $path . "/" . $fileName;
        
        if (file_exists($curPath)) {
            //echo $curPath;
            require_once($curPath);
            break;
        }
    }
});

//all our classes are using CamelCase naming convention such as “MyController”
$Hello = new Hello();
$World = new World();
$World = new MyController();

Output
Hello class is load
World class is load
Controller class is load

Discussion:-
Let’s discuss how SPL autoload function works when it is used. You add your own autoloader function which will automatically load classes for you. All you need to do is to decide which kind of convention you want to follow when naming your classes and how these classes will get stored in the folders of your file system.

Here we define our own autoloader which is represented by an anonymous function that is registered as an autoloader by SPL autoload register function. As you can see, we have passed anonymous function as argument to SPL autoload register function and our convention here is that all the classes use camelcase naming convention.

For example, if we have a class “my controller” then its name will be like “myController”. This is a camel case style class name. On the other hand classes can be named by this pattern “my_controller.php” (using underscore symbol for name separation).

Further, as in above code’s functionality, the class name that is currently following the Camel case is converted to class name that is Underscore separated, and will implement these to all the controller names. (i.e. all controller names will be lowercase and names separated with underscore).

Also, it will go through all the paths that we have mentioned, and will find the controller classes (stored in controllers folder) and will change them as per the underscore convention, as explained in above paragraph. Other than controller classes, if we have provided path for templates folder, it will do the same for them as well.

So, here class name will be converted from camelcase to underscores correspondingly and it is also our responsibility to make sure that file with such name exists. It will also check if the classes exist for the given path, so it is our responsibility to provide correct paths for error free processing.

If the path entered is correct, that means, controllers or templates directory contains the class, it will add them one by one through loop, and rules will be performed on them automatically.

Leave a Reply

Your email address will not be published. Required fields are marked *