How to Use PHP Autoload in WordPress Theme or Plugin

When you use Object-Oriented Programming in your WordPress theme or plugin it will become large and complicate after a while, in this situation the role of PHP Autoload in WordPress be prominent. PHP autoload is a method in PHP for automatically including the class files in your project. In large PHP object-oriented projects there are many class files that including manually by include or require statements are so time consuming and complex that caused the maintainability of the project is reduced. Therefore, any developer need to load the classes before using them in a reliable way. in this article from Emoweb, you will be understand what is autoload, why we use it, and how to implement it in a WordPress project.

What is PHP Autoload?

In large PHP or WordPress project there are several classes that if you want to load them manually , your code would be like below:

functions.php
<?php

// load the whole project class files manually
require_once __DIR__.'/src/ClassFile_1.php';
require_once __DIR__.'/src/ClassFile_2.php';
require_once __DIR__.'/src/ClassFile_3.php';
require_once __DIR__.'/src/ClassFile_4.php';
require_once __DIR__.'/src/ClassFile_5.php';
require_once __DIR__.'/src/ClassFile_6.php';
require_once __DIR__.'/src/ClassFile_7.php';
require_once __DIR__.'/src/ClassFile_8.php';
require_once __DIR__.'/src/ClassFile_9.php';
require_once __DIR__.'/src/ClassFile_10.php';
// ... a hundred more times

$object_1 = new ClassFile_1();

This is so confusing and unmaintainable but, PHP suggested a solution by introducing spl_autoload_register() which register given function as __autoload() implementation. Indeed, when PHP interpreter faced with a called function or class that is not defined before it check the search the called function or class based on the path rule that defined in the spl_autoload_register() function. You can get more detail about it from here.

Furthermore of the mentioned way, composer offers a robust autoloading feature that adheres to the PSR-4 standard, making it easier to manage and organize your code. Composer is a dependency management tool for PHP projects, allowing you to declare the libraries your project depends on and it will manage (install/update) them for you. To use the composer autoload you should consider some rules in naming the files and directories that we will describe it a little later. So, before using the autoload feature you must install composer on your machine and then initialize it to your WordPress them or plugin directory. To install composer you could study its installation instruction from here. After the installation of the Composer, you will be ready to use it.

Utilizing of Composer on the Project

To start using Composer in your WordPress theme or plugin, you need to initialize it in your project directory. All the Composer needs to start is composer.json file. This file contain all metadata of the project like dependencies, development dependencies, project name, authors’ information, and also autoload information.

The composer.json file typically should be on the root of you WordPress theme or plugin.

There are two common ways to create composer.json file and set it up to the project. The former is to create the composer.json file in the root of plugin or theme at first:

composer.json
{
    "autoload": {
        "psr-4": {
            "YourNamespace\\": "src/"
        }
    }
}

Replace YourNamespace with your actual namespace and src/ with the directory where your classes are located. Then write the following command into the terminal or command line:

Bash
composer dump-autoload

This command will generate the necessary files for autoloading. The later way is to use composer init command. For doing this at first in the root of the project run the below command:

Bash
composer init

Then it ask you some question about the project like the below:

Bash

  Welcome to the Composer config generator



This command will guide you through creating your composer.json config.

Package name (<vendor>/<name>) [emoweb/project]: #Pakage name
Description []: # Tne Description of the package also, you can leave it empty
Author [emoweb <info@emoweb.dev>, n to skip]: #Author name and email of the package.
Minimum Stability []: #Value for the minimum-stability field.
Package Type (e.g. library, project, metapackage, composer-plugin) []: # Type of package.
License []: #License of package.

Define your dependencies.

Would you like to define your dependencies (require) interactively [yes]? #if you hint the Enter it will ask you the name of dependency that you want to install. For escaping this stage please type no and hint the Enter
Would you like to define your dev dependencies (require-dev) interactively [yes]? #if you hint the Enter it will ask you the name of development dependency that you want to install. For escaping this stage please type no and hint the Enter.
Add PSR-4 autoload mapping? Maps namespace "EMOWEB\PROJECT" to the entered relative path. [src/, n to skip]: # If you want to set up the autoload and configure it you can type the name of the directory where your classes located. 
# the preview of composer.json content
{
    "name": "emoweb/project",
    "type": false,
    "autoload": {
        "psr-4": {
            "EMOWEB\\PROJECT\\": "src/" 
        }
    },
    "authors": [
        {
            "name": "emoweb",
            "email": "ingfo@emoweb.dev"
        }
    ],
    "require": {}
}

Do you confirm generation [yes]?
Generating autoload files
Generated autoload files
PSR-4 autoloading configured. Use "namespace Ebi3102\Test;" in src/
Include the Composer autoloader with: require 'vendor/autoload.php';

You can also change the name of maps namespace when the composer.json is created. for example I want to change it to “EMOPLUGIN” like this:

composer.json
{
    "name": "emoweb/project",
    "type": false,
    "autoload": {
        "psr-4": {
            "EMOPLUGIN\\": "src/" 
        }
    },
    "authors": [
        {
            "name": "emoweb",
            "email": "ingfo@emoweb.dev"
        }
    ],
    "require": {}
}

After changing the file, by entering the following command in the terminal, the changes will be executed

Bash
composer dump-autoload

Once composer initialized it create vendor directory and locate all its files on to it. For rename this directory you can add the following configuration to the composer.json

composer.json
{
    "name": "emoweb/project",
    "type": false,
    "autoload": {
        "psr-4": {
            "EMOPLUGIN\\": "src/" 
        }
    },
    "authors": [
        {
            "name": "emoweb",
            "email": "ingfo@emoweb.dev"
        }
    ],
    "config": {
        "vendor-dir": "composer_directory_name"
    },
    "require": {}
}

Replace composer_directory_name with your desired name.

All installed PHP packages and also autoload files are saved in the composer_directory_name. Please notice the composer dependencies are most likely used during runtime therefore, be ensure to not exclude composer_directory_name directory from you theme or plugin when you want install it on WordPress.

How to Use Autoload in WordPress Theme and Plugin

As we mentioned above composer uses PSR-4 standard to implement its autoload. In fact, this PSR standard helps by specifying some rules that classes are automatically recognized and loaded through their file paths.

In PSR-4 a class name has some prefix that define its path. The structure of class name is look like:

PHP
 \<NamespaceName>(\<SubNamespaceNames>)*\<ClassName>

The “ClassName” refer to the name of the class that its file also must has this name like ClassName.php

The “NamespaceName” defined in the composer.json previously which shows the root directory of classes. “SubNamespaceNames” refer to the directories path of class file form the root. Imagine our plugin has the following folder structures:

Bash
emo-plugin
|
|-- src
|    |
|    |-- Controllers
|    |    |
|    |    `-- User_Role_Checker.php
|    |
|    `-- Templates
|         |
|         `-- User_Template.php
|
`-- my-plugin.php

The full class name is:

PHP
 \EMOPLUGIN\Controllers\User_Role_Checker

In this specification the name of directories and class files must be as same as the namespaces. After this introduction, we go to the main question that is about the use of autoloader. The following steps describe this job:

1- Include the Composer autoload file:

In your theme’s functions.php or your plugin’s main file, add the following line:

functions.php
require_once __DIR__ . '/composer_directory_name/autoload.php';
my-plugin.php
require_once __DIR__ . '/composer_directory_name/autoload.php';

2- Defining a Namespace in class file:

In each class you must defined its namespace based on the aforementioned rules

User_Template.php
namespace EMOPLUGIN\Controllers;

class User_Role_Checker
{
  // Class codes
}

3- Use your classes:

Now you can use the classes from your src/ directory without manually including them:

User_Template.php
namespace EMOPLUGIN\Templates\User_Template;

use EMOPLUGIN\Controllers\User_Role_Checker;

class User_Template
{
  public function user_template()
  {
      $checker = new User_Role_Checker();
  }
}

Namespaces and the use keyword make it clear where a class is coming from, which is especially useful in larger projects with many dependencies.

By leveraging Composer and autoloading, you can streamline your WordPress development process, manage dependencies more efficiently, and organize your codebase following modern PHP standards.

An important question arises here, based on the WordPress documentation, class names should be capitalized words and separated by underscore while class file names should begin with class- term and the underscore in the class name must be replaced with dash. For example, the name of the User_Template class must be class-user-template.php. Actually, WordPress does not meet the PSR-4 standard, so what to do now? I will prepare another article as soon as possible and put its link here to teach you how to do it. But if you know another way to implement autoloading for WordPress please tell me in the comments.

Leave a Reply

Your email address will not be published. Required fields are marked *