Summary: in this tutorial, you will learn how to organize your class files and load them automatically using PHP 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_once
statement.
Suppose that you have the following project directory structure:
.
├── index.php
└── models
└── Contact.php
Code language: CSS (css)
The models
directory has the Contact.php
file that contains the following Contact
class:
<?php
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:
<?php
require_once 'models/Contact.php';
$contact = new Contact('[email protected]');
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:
<?php
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.php
Code 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:
<?php
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:
<?php
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:
<?php
require 'functions.php';
$contact = new Contact('[email protected]');
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:
<?php
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:
<?php
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.php
Code 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:
<?php
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:
<?php
require 'functions.php';
$contact = new Contact('[email protected]');
echo Email::send($contact);
Code language: HTML, XML (xml)
Output:
Sending an email to [email protected]
Code 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.