Un plugin WordPress peut faire appel à de nombreuses class qu’il faudra inclure via autant de require ou include. C’est long, fastidieux et potentiellement source d'erreurs. Pourquoi s’embêter avec ça quand PHP peut le faire pour nous ?
En bon codeur respecteux des standards, on part du principe que toutes nos class sont regroupées dans un même dossier et que les fichiers sont nommés selon ce modèle : class-nomdemaclass.php Si toutes nos class sont regroupées dans un dossier includes, on obtient quelque chose ressemblant à ceci :

Nous allons créer notre autoloader. Et vous savez quoi ? Ce sera lui aussi une… class. Dans le dossier includes de notre plugin, on crée un fichier class-rrphf-myplugin-autoloader.php et on y rédige le code suivant :
<?php defined( 'ABSPATH' ) || exit;
/**
* Project: RRPhF MyPlugin
* File: class-rrphf-myplugin-autoloader.php
* User: reskator
* Author: RR PhF
*
* @Description Class autoloader for RRPhF MyPlugin plugin
* @since 1.0.0
*/
if ( ! class_exists( 'RRPhF_MyPlugin_autoloader' ) ) :
class RRPhF_MyPlugin_autoloader {
/**
* Singleton
*
* @var null Single instance
*/
private static $_instance = null;
/**
* RRPhF_MyPlugin_autoloader constructor.
*
*/
private function __construct() {
spl_autoload_register( [$this, 'load'] );
}
/**
* Singleton method
*
* If it has not already been done, creates and return an instance of the class
*
* @author RR PhF
* @since 1.0.0
*
* @static
* @return \RRPhF_MyPlugin_autoloader
*/
public static function get_instance() {
if ( ! self::$_instance ) {
self::$_instance = new self();
}
return self::$_instance;
}
/**
* Class loader
*
* Converts the name of the class to a file name and includes the class file.
*
* @author RR PhF
* @since 1.0.0
*
* @param string $class_name - class to load
*/
public function load( $class_name ) {
//Converts the class name to a file name
$class_file = str_replace( '_', '-', strtolower( $class_name ) );
$class_file = 'class-' . $class_file;
$class_file = __DIR__ . '/' . $class_file;
// do the autoloading
spl_autoload( $class_file, '.php' );
}
}
/**
* Make sure an instance can't be cloned
*
* @author RR PhF
* @since 1.0.0
*
*/
private function __clone() {
// do nothing
}
}
RRPhF_MyPlugin_autoloader::get_instance();
endif;
Notre class est instanciée à la ligne 81. par l'appel de la méthode… get_intance()
RRPhF_MyPlugin_autoloader::get_instance();
Le fait d'instancier la class fait que PHP cherche si un constructeur est présent dans la class et l'exécute automatiquement. Ça tombe bien notre class en comporte un :
private function __construct() {
spl_autoload_register( [$this, 'load'] );
}
Pour schématiser, spl_autoload_register() permet d'indiquer à PHP la fonction (méthode) qu'il devra utiliser lorsqu'il découvrira une nouvelle class durant l'exécution de notre plugin. En bonus, il se chargera de transmettre à notre méthode le nom de la class concernée. Dans le cas présent, comme vous pouvez le voir, nous lui indiquons d’utiliser la méthode load :
*/
public function load( $class_name ) {
//Converts the class name to a file name
$class_file = str_replace( '_', '-', strtolower( $class_name ) );
$class_file = 'class-'. $class_file;
$class_file = __DIR__ .'/'. $class_file;
// do the autoloading
spl_autoload( $class_file, '.php' );
}
La méthode load dispose de l'argument $class_name. C'est cet argument qui reçoit le nom de la class ayant déclenché l'appel _autoload. Après avoir converti le nom de la class en nom de fichier (mais sans l'extension), on appelle la méthode PHP spl_autoload() avec, en 1er argument, le path du fichier à charger (toujours sans l'extension), et en deuxième argument, l'extension. Notez que notre class est particulièrement ‘verrouillée’ :
$_instance est déclarée private et static ;__constructor est déclaré private ;get_instance() fait sont possible pour ne déclarer qu'une instance.Je dis qu'il fait son possible car il ne peut empêcher que l'instance soit… clonée :/ D'où la dernière méthode de notre class :
private function __clone() {
// do nothing
}
Dans le cas où l'on tenterait de cloner l'instance de cette class, la méthode __clone() sera appelée… mais ne fera rien : plus de clonage possible.
L'autoloader étant en place, il nous faut l'implémenter dans notre plugin :
<?php defined( 'ABSPATH' ) || exit;
/*
Plugin Name: RRPhF MyPlugin
Plugin URI: https://www.reskator.fr
Description: The best plugin in the world that everyone expected
Version: 1.0.0
Author: Reskator
Author URI: https://www.reskator.fr
Text Domain: rrphfmyplugin
Domain Path: /languages
License: GPLv2 or later
*/
if ( ! defined( 'RRPHF_MYPLUGIN_FILE' ) ) {
define( 'RRPHF_MYPLUGIN_FILE', __FILE__ );
}
if ( ! class_exists( 'RRPhFMyPlugin_autoloader' ) ) {
include_once __DIR__ .'/includes/class-rrphfmyplugin-autoloader.php';
}
// Calls plugin's main class
$myplugin = new RRPhF_MyPlugin();
Et voilà ! On n'a désormais qu'un seul et unique include pour charger toutes nos class 🙂 Et on peux voir la 'magie' opérer dès l'instruction suivante qui instancie la class principale du plugin. Sans autoloader, on a tendance à inclure TOUTES les class. Or, il se peut qu'elles ne soient pas toutes requises à chaque fois. Avec un autoloader, PHP ne chargera que les class nécessaires, libérant ainsi des ressources (mémoire, accès disques, etc.).