This tutorial covers the following topics:
- What is autoloading
- What is autoloader
- Why use an autoloader
- PHP __autoload() function
- PHP spl_autoload_register() function
- PHP registering multiple autoloader functions
- Autoloading classes based on namespace structure
What is autoloading
Autoloading is the process of automatically loading PHP classes without explicitly loading them with the require()
, require_once()
, include()
, or include_once()
functions.
To autoload classes, you must follow two rules:
- Each class must be defined in a separate file.
- Name your class files the same as your classes. The class
Views
would be placed inViews.php
, a class calledUsers
would be stored inUsers.php
and so on.
When you use the statement new ClassName()
, if the class ClassName
doesn’t exist (because it hasn’t been included), PHP trigger an autoloader that can then load the file ClassName.php
, and the rest of the script will continue as normal without requiring to manually write the line require 'ClassName.php';
.
What is autoloader
An autoloader is a function that takes a class name as an argument and then includes the file that contains the corresponding class. The following example demonstrates how you can make an autoloader function to load classes:
<?php function my_autoloader ( $class ) { $path = $_SERVER['DOCUMENT_ROOT'] . '/classes/'; require $path . $class .'.php'; }
To implement an autoloader, PHP provides two functions:
- __autoload(), not recommended, deprecated as of PHP 7.2 and removed as of PHP 8.0.
- spl_autoload_register(), recommended.
Why use an autoloader
How often have you seen code like this at the top of your PHP files?
<?php require 'file_1.php'; require 'file_2.php'; require 'file_3.php';
All too often, right? The require()
, require_once()
, include()
, and include_once()
functions load an external PHP file into the current script, and they work wonderfully if you have only a few PHP scripts.
However, what if you need to include a hundred PHP scripts? The require()
and include()
functions do not scale well, and this is why PHP autoloaders are important. An autoloader is a strategy for finding a PHP class, interface, or trait and loading it into the PHP interpreter on-demand at run-time, without explicitly including files.
__autoload() magic function
Note: The usage of __autoload function is not recommended, it has been DEPRECATED as of PHP 7.2.0, and REMOVED as of PHP 8.0.0.
__autoload()
, a magic function, is automatically invoked by the PHP when we instantiate a class that has not already been loaded. For example:
<?php function __autoload($class) { $path = $_SERVER['DOCUMENT_ROOT'] . '/classes/'; require_once $path . $class .'.php'; } $object = new myClass(); # Loads the class stored in "/classes/myClass.php"
As of PHP 7.2.0
the __autoload()
function has been deprecated and removed since PHP 8.0.0. Now it is recommended to use the spl_autoload_register
for that purpose instead.
spl_autoload_register()
PHP 5.1.2
introduced the more flexible spl_autoload_register()
function in its SPL library which allows you to register multiple autoloader functions.
Example: spl_autoload_register()
as a replacement for the __autoload()
function:
<?php spl_autoload_register( function($class) { $path = $_SERVER['DOCUMENT_ROOT'] . '/classes/'; require_once $path . $class .'.php'; }); $object = new Home(); # Loads the class "/classes/Home.php" $object = new Template(); # Loads the class "/classes/Template.php"
Registering multiple autoloader functions for each namespace
The spl_autoload_register()
allows to create an autoload chain, a series of functions that can be called to try and load a class or interface:
<?php spl_autoload_register (function ($class) { // for BrainBell namespace require 'path/to/brainbell/classname.php'; }); spl_autoload_register(function ($class) { // for Views namespace require 'path/to/views/classname.php'; });
Example: autoloader.php
, following is the expanded version of the above code:
<?php # File name: autoloader.php # Registering for Views namespace spl_autoload_register(function ($class) { $prefix = 'Views\\'; # namespace prefix $len = strlen($prefix); if (strncmp($prefix, $class, $len) !== 0) return; # move to the next registered autoloader $relative_class = substr($class, $len); # define class files directory $base_dir = __DIR__ . '/classes/views/'; $file = $base_dir . str_replace('\\', '/', $relative_class) . '.php'; if (file_exists($file)) { require $file; } }); # Registering autoloader for BrainBell namespace spl_autoload_register(function ($class) { $prefix = 'BrainBell\\'; $base_dir = __DIR__ . '/classes/brainbell/'; $len = strlen($prefix); if (strncmp($prefix, $class, $len) !== 0) { return; } $relative_class = substr($class, $len); $file = $base_dir . str_replace('\\', '/', $relative_class) . '.php'; if (file_exists($file)) { require $file; } });
The above example is taken from https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md.
To see if the above autoloader is working properly, create two classes BrainBell\Template
and Views\Template
and save them in the directory classes/brainbell/
and classes/views/
respectively.
The classes/brainbell/Template.php file:
<?php # File name: classes/brainbell/Template.php namespace BrainBell; class Template { private $message; function __construct() { $this->message = __ClASS__; } function getMessage() { return $this->message; } function getPath() { return __DIR__; } }
The classes/view/Template.php file:
# File name: classes/view/Template.php namespace Views; class Template { private $message; function __construct() { $this->message = __ClASS__; } function getMessage() { return $this->message; } function getPath() { return __DIR__; } }
Next, include the autoloader.php in the script and reference the above classes:
<?php # File name: example.php require_once 'autoloader.php'; // Loading classes from BrainBell namespace $class = new BrainBell\Template(); echo $class->getMessage().'<br>'; # BrainBell\Template echo $class->getPath().'<br>'; # D:\xampp\htdocs\classes\brainbell // Loading classes from Views namespace $class = new Views\Template(); echo $class->getMessage().'<br>'; # Views\Template echo $class->getPath(); # D:\xampp\htdocs\classes\views
Autoloading classes based on namespace structure
PHP can autoload classes without needing an autoloader function if the directory structure containing the classes matches the namespaces of the classes.
In the following example, the spl_autoload_register()
tries to figure out the class files relative to the current directory path. So if your script (example.php
) is saved in the www
directory, it tries to load the views\home()
class from the www/views/home.php
path:
<?php # /www/example.php spl_autoload_register(); $home = new classes\home(); # Loads /www/classes/home.php $home = new views\home(); # Loads /www/views/home.php
Follow these instruction for the complete example:
- Create directories/folders on your document root:
classes
,views
andmodels
. - Create two PHP files in each folder:
home.php
andall.php
. - Create classes by writing the following code in each file:
classes/home.php
<?php namespace classes; class home { public function get(){ return 'classes/home.php'; } }
classes/all.php
<?php namespace classes; class all { public function get(){ return 'classes/all.php'; } }
models/home.php
<?php namespace models; class home { public function get(){ return 'models/home.php'; } }
models/all.php
<?php namespace models; class all { public function get(){ return 'models/all.php'; } }
views/home.php
<?php namespace views; class home { public function get(){ return 'views/home.php'; } }
classes/all.php
<?php namespace views; class all { public function get(){ return 'views/all.php'; } }
- Create a file
loader.php
at document root and write the following code:
<?php spl_autoload_register(); $home = new classes\home(); echo $home->get() . <br>; $home = new views\home(); echo $home->get(). <br>; $home = new models\home(); echo $home->get(). <br>; $all = new classes\all(); echo $all->get(). <br>; $all = new views\all(); echo $all->get(). <br>; $all = new models\all(); echo $all->get(); /*Output: classes/home.php views/home.php models/home.php classes/all.php views/all.php models/all.php*/
You can see all classes loaded without using the include
or require
keywords. 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 the require
or include
keyword.
PHP OOP Tutorials: