Autoloading classes

As you already know, in order to use a class, you need to include the file that defines it. So far, we have been including the files manually, as we only had a couple of classes and used them in one file. But what happens when we use several classes in several files? There must be a smarter way, right? Indeed there is. Autoloading to the rescue!

Autoloading is a PHP feature that allows your program to search and load files automatically given some set of predefined rules. Each time you reference a class that PHP does not know about, it will ask the autoloader. If the autoloader can figure out which file that class is in, it will load it, and the execution of the program will continue as normal. If it does not, PHP will stop the execution.

So, what is the autoloader? It is no more than a PHP function that gets a class name as a parameter, and it is expected to load a file. There are two ways of implementing an autoloader: either by using the __autoload function or the spl_autoload_register one.

Using the __autoload function

Defining a function named __autoload tells PHP that the function is the autoloader that it must use. You could implement an easy solution:

function __autoload($classname) {
    $lastSlash = strpos($classname, '') + 1;
    $classname = substr($classname, $lastSlash);
    $directory = str_replace('', '/', $classname);
    $filename = __DIR__ . '/' . $directory . '.php';
    require_once($filename);
}

Our intention is to keep all PHP files in src, that is, the source. Inside this directory, the directory tree will emulate the namespace tree of the classes excluding the first section BookStore, which is useful as a namespace but not necessary as a directory. That means that our Book class, with full class name BookStoreDomainBook, will be in src/Domain/Book.php.

In order to achieve that, our __autoload function tries to find the first occurrence of the backslash with strpos, and then extracts from that position until the end with substr. This, in practice, just removes the first section of the namespace, BookStore. After that, we replace all by / so that the filesystem can understand the path. Finally, we concatenate the current directory, the class name as a directory, and the .php extension.

Before trying that, remember to create the src/Domain directory and move the two classes inside it. Also, to make sure that we are testing the autoloader, save the following as your init.php, and go to http://localhost:8000/init.php:

<?php

use BookstoreDomainBook;
use BookstoreDomainCustomer;

function __autoload($classname) {
    $lastSlash = strpos($classname, '') + 1;
    $classname = substr($classname, $lastSlash);
    $directory = str_replace('', '/', $classname);
    $filename = __DIR__ . '/src/' . $directory . '.php'
    require_once($filename);
}

$book1 = new Book("1984", "George Orwell", 9785267006323, 12);
$customer1 = new Customer(5, 'John', 'Doe', '[email protected]');

The browser does not complain now, and there is no explicit require_once. Also remember that the __autoload function has to be defined only once, not in each file. So from now on, when you want to use your classes, as soon as the class is in a namespace and file that follows the convention, you only need to define the use statement. Way cleaner than before, right?

Using the spl_autoload_register function

The __autoload solution looks pretty good, but it has a small problem: what if our code is so complex that we do not have only one convention, and we need more than one implementation of the __autoload function? As we cannot define two functions with the same name, we need a way to tell PHP to keep a list of possible implementations of the autoloader, so it can try all of them until one works.

That is the job of spl_autoload_register. You define your autoloader function with a valid name, and then invoke the function spl_autoload_register, sending the name of your autoloader as an argument. You can call this function as many times as the different autoloaders you have in your code. In fact, even if you have only one autoloader, using this system is still a better option than the __autoload one, as you make it easier for someone else who has to add a new autoloader later:

function autoloader($classname) {
    $lastSlash = strpos($classname, '') + 1;
    $classname = substr($classname, $lastSlash);
    $directory = str_replace('', '/', $classname);
    $filename = __DIR__ . '/' . $directory . '.php';
    require_once($filename);
}
spl_autoload_register('autoloader');
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.74.231