PHP Autoloading Class Files
spl_autoload_register() function.It is good practice to keep each PHP class in a separate file. Also, the name of the class should be the same as the file name. For example, the Contact.php file should contain the Contact class.
Before using a class, you need to:
- First, define the class in a file.
- Second, load it using the
require,require_once,include, orinclude_oncestatement.
Suppose that you have the following project directory structure:
.
├── index.php
└── models
└── Contact.phpCode language: CSS (css)
The models directory has the Contact.php file that contains the following Contact class:
class Contact
{
private $email;
public function __construct(string $email)
{
$this->email = $email;
}
public function getEmail()
{
return $this->email;
}
}
Code language: HTML, XML (xml)
From the index.php file, you can load the models/Contact.php file and use the Contact class as follows:
require_once 'models/Contact.php';
$contact = new Contact('john.doe@example.com');
Code language: HTML, XML (xml)
This solution works fine if you have a small number of files. When the number of files grows, the require_once statement doesn’t scale well.
To resolve it, you can define a function that takes a class name as an argument and includes the file that contains the class definition. For example:
function load_model($class_name)
{
$path_to_file = 'models/' . $class_name . '.php';
if (file_exists($path_to_file)) {
require $path_to_file;
}
}
Code language: HTML, XML (xml)
The load_class() function looks for the class file in the models directory and includes it if the file exists. And you can place the load_model() function in the functions.php file:
.
├── functions.php
├── index.php
└── models
└── Contact.phpCode language: plaintext (plaintext)
To use the load_model() function in the index.php file, you can include the functions.php file and call the load_model() function:
require_once 'functions.php';
load_model('Person');
$person = new Person();
Code language: HTML, XML (xml)
Autoloader with spl_autoload_register() function
PHP 5.1.2 introduced the spl_autoload_register() function that automatically loads a class file whenever you use a class that has not been loaded yet.
PHP 7.2.0 deprecated the __autoload() magic function and recommended to use the spl_autoload_register() function instead.
When you use a class that has not been loaded, PHP will automatically look for spl_autoload_register() function call.
The spl_autoload_register() function accepts a callback function and calls it when you attempt to create use a class that has not been loaded.
To use the spl_autoload_register() function, you can pass the load_model function to it as follows:
function load_model($class_name)
{
$path_to_file = 'models/' . $class_name . '.php';
if (file_exists($path_to_file)) {
require $path_to_file;
}
}
spl_autoload_register('load_model');
Code language: HTML, XML (xml)
And from the index.php file, you don’t need to call the load_model() function whenever you use a class in the models directory:
require 'functions.php';
$contact = new Contact('john.doe@example.com');
Code language: HTML, XML (xml)
Multiple autoload functions
The spl_autoload_register() function allows you to use multiple autoloading functions. The spl_autoload_register() function will create a queue of autoloading functions and runs through each of them in the order that they are defined.
For example:
spl_autoload_register('autoloader1');
spl_autoload_register('autoloader2');
spl_autoload_register('autoloader3');
Code language: HTML, XML (xml)
In this example, PHP will run the autoloader1, autoload2, and autoloader3 sequentially to load the class files.
To demonstrate this, let’s create a new directory called services that stores service class files and create an Email.php file inside the services directory.
The following defines the Email class:
class Email
{
public static function send($contact)
{
return 'Sending an email to ' . $contact->getEmail();
}
}
Code language: HTML, XML (xml)
The project directory now looks like this:
.
├── functions.php
├── index.php
├── models
│ └── Contact.php
└── services
└── Email.phpCode language: plaintext (plaintext)
In the functions.php file, you can define a function that loads the classes from the services directory and pass the function name to the spl_autoload_register() function like this:
function load_model($class_name)
{
$path_to_file = 'models/' . $class_name . '.php';
if (file_exists($path_to_file)) {
require $path_to_file;
}
}
function load_service($service_name)
{
$path_to_file = 'services/' . $service_name . '.php';
if (file_exists($path_to_file)) {
require $path_to_file;
}
}
spl_autoload_register('load_model');
spl_autoload_register('load_service');
Code language: HTML, XML (xml)
From the index.php, you can use the Contact and Email classes as follows:
require 'functions.php';
$contact = new Contact('john.doe@example.com');
echo Email::send($contact);
Code language: HTML, XML (xml)
Output:
Sending an email to john.doe@example.comCode language: plaintext (plaintext)
Like classes, you can also load the interfaces and traits using same autoloading function.
Summary
- An autoloading function loads a class, an interface, or a trait from a PHP file.
- Use the
spl_autoload_register()function to autoload the classes, interfaces, and traits.