Introduction

With some examples, this tutorial post will teach the PHP autoloader and namespace concepts.

What is Autoloading in PHP

PHP autoload’s primary function is to load PHP files into the application context. The import statement is the default method to include PHP file into context.

However, we may avoid the issue by using the PHP autoload capability to autoload essential PHP files, which keeps your code clean and composable.

Why do we need auto loading

When creating object-oriented applications, many developers create one PHP source file per class declaration. One of the major inconveniences is having to start each script with a huge list of required includes.

Autloading allows us to include an arbitrary number of PHP files in the application context if they aren’t already included by other include statements.

PHP Autoloading Methods

PHP uses two functions; one is the magic method spl_autoload_register and the other is __autoload.

NOTE: Although __autoload has been DEPRECATED as of PHP 7.2.0, and REMOVED as of PHP 8.0.0, relying on this function is highly discouraged.

Whenever PHP encounters an instantiation of a class, it triggers the autoloading function by providing it as a parameter.

You can also define the path of the class and include it in context within the atoloading method.

What is difference between __autoload and sp_autload_resgister function

Because the _autoload method is a magic method, you can only declare it once. As a result, you’d just need one logic to incorporate PHP class files.

spl_autoload_register, on the other hand, takes a function as a parameter, which we can use to create the specific logic for including the PHP file.

With the help of spl_autoload_register, we can have multiple implementations of the inclusion of PHP files.

Example

<?php

/**
 * autoload method
 */
function __autoload($class)
{
  require $class.'.php';
}

//spl_autoload_register

/**
 * autoload method one
 */
function autoloadOne($class)
{
  require "/dir-one/".$class.".php";
}

/**
 * autoload method two
 */
function autoloadTwo($class)
{
  require "/dir-two/".$class.".php";
}

//register auto loader
spl_autoload_register("autoloadOne");
spl_autoload_register("autoloadTwo");

What exactly is namespace

In most cases, PHP won’t let you have two classes with the same name. However, in version 5.3, the idea of namespace was added, which created class ownership, allowing two classes with the same name but distinct ownership to exist.

What is the importance of namespace in autloading

Namespaces were created to solve the problem of name clashes and to allow extra-long class names to be shortened.

Namespaces are a technique of encapsulating objects in the broadest sense.

Namespaces in PHP allow you to organise related classes, interfaces, methods, and constants together.

For example

<?php

namespace Module\User\Controller;
namespace Module\User\Entity;
namespace Module\User\Form;
namespace Module\User\Validator;

If we autoload the above class, we will get the whole namespace of that class along with the class name.

 namespace_autoload.php
<?php

spl_autoload_register(function ($class_name) {

  echo "class path = ".$class;
  die ;
}

new \Module\User\Controller();

// it will print
// class path = Module\User\Controller

With the help of this information, we can organize classes according to our project directory structure.

Let’s say you have the following project structure.

project
 |__Module
      |__User
          |__Controller
          |__Entity
          |__Form
 |
 |__autoload.php

Then you can create PHP classes with a namespace as

 project
 |__Module
     |__User
   |__Controller   \\ class : IndexController , namespace Module\User\Controller
          |__Entity   \\ class : User , namespace Module\User\Entity
          |__Form  \\ class : UserForm , namespace Module\User\Form
 |
 |__autoload.php

file: autoload.php

<?php

//include namespace

use Module\User\Controller\IndexController;
use Module\User\Entity\User;
use Module\User\Form\UserForm;

/**
 * Autload project files
 */
spl_autoload_register(function ($class_name) {

  echo $class;
  require $class;
}

// instantiate classes
$controller = new IndexController();
//(it will print)  Module\User\Controller\IndexController and load this class

$user = new User();
//(it will print)  Module\User\Entity\User  and load this class

$userForm = new UserForm();
//(it will print) Module\User\Form\UserForm  and load this class

As you can see, namespaces aid in the organisation of the project structure and the autoloading of classes.

What is the difference between the following two sets of statements?

Namespace autloading Direct include files
use Module\User\Controller\IndexController; require “Module\User\Controller\IndexController”;
use Module\User\Entity\User; require “Module\User\Entity\User”;
use Module\User\Form\UserForm; require “Module\User\Form\UserForm”;

The main difference is that the require statement accepts the full directory path, whereas with namespace we can set logic to autoload PHP files with different directory structures and minimise the namespace length.

Let’s see the following example. Suppose you have the following directory for your project library files.

project
|
|__vendor
|
|__lib
 |
 |__src
  |
  |__components
   |
   |__HTTP  //Request, Response classes
   |
   |__Controller  //BaseController classes
   |
   |__Form //BaseForm classes
..... many more files

You write the following code to use the require statement.

<?php

 require "/vendor/lib/src/components/HTTP/Request";
 require "/vendor/lib/src/components/HTTP/Response";
 require "/vendor/lib/src/components/Controller/BaseController";
 require "/vendor/lib/src/components/Form/BaseForm";

We can reduce the above class path and organize the structure much more properly with the help of autoload and namespace as follows.

<?php

define("LIB_PATH", "/vendor/lib/src/components");

use HTTP\Request;
use HTTP\Response;
use Controller\BaseController;
use Form\BaseForm;

/**
 *  autoload lib class files
 */
spl_autoload_register(function ($class_name) {

  // set class path
  $class_path = LIB_PATH.$class;

  //include class file
  echo $class_path;
  require $class_path;
}

$request = new Request;
// (it will print)  /vendor/lib/src/components/HTTP/Request

$controller = new BaseController;
// (it will print)  /vendor/lib/src/components/Controller/BaseController

Conclusion

  • An autoload helps load all the PHP classes of a PHP project.
  • The combination of autoload and namespace standardises the organisation and loading of PHP projects.
  • Namespace helps organise your PHP classes.