L'autoloader

Résumé Support Quiz

Dans ce chapitre, nous allons continuer le travail commencé avec les namespaces en découvrant l'autoloading avec Composer. L'objectif est de ne plus avoir à écrire manuellement tous les require dès que l'on veut utiliser une classe.

Avec les namespaces, on importe déjà les classes avec use. Si on doit en plus inclure les fichiers à la main, on se retrouve à faire deux fois le travail. L'autoloading permet de résoudre ce problème.

Le principe de l'autoloading

L'autoloading consiste à charger automatiquement le fichier qui contient une classe au moment où PHP en a besoin.

À terme, on ne veut donc plus écrire un require pour chaque classe. On inclut seulement l'autoloader au début de l'application, puis il s'occupe du reste. Pour que cela fonctionne, il faut aider PHP en organisant les classes dans une structure cohérente. Les namespaces doivent correspondre aux dossiers du projet.

Organiser les classes avec les namespaces

Si une classe est dans le namespace suivant :

namespace App\Guestbook;

alors elle doit être rangée dans un dossier qui reflète cette structure :

class/ └── Guestbook/ └── Message.php

Une classe Message du formulaire de contact sera placée dans un autre namespace :

namespace App\Contact;

et donc dans un autre dossier :

class/ └── Contact/ └── Message.php

Cette correspondance entre namespaces et dossiers permet à l'autoloader de retrouver les fichiers automatiquement.

Utiliser Composer

On pourrait écrire soi-même un autoloader, mais dans la pratique on ne le fait quasiment jamais et on se repose sur un outil incontournable Composer.

Il sert à télécharger et gérer des bibliothèques externes, mais il permet aussi de générer un autoloader pour notre propre code. Pour l'installation vous pouvez suivre les instruction de la documentation.

Initialiser un projet Composer

La première étape dans un projet est d'initialiser Composer.

php composer.phar init

Composer pose alors plusieurs questions qui lui serviront à construire le fichier composer.json qui nous servira à déclarer l'autoloading.

Dans composer.json, on ajoute une clé autoload, puis une configuration psr-4.

{ "autoload": { "psr-4": { "App\\": "class/" } } }

Cette configuration indique à Composer que toutes les classes du namespace App\ se trouvent dans le dossier class/.

Dans un fichier JSON, l'antislash doit être échappé. C'est pour cela qu'on écrit `App\\` et non simplement `App\`.

On crée ainsi une correspondance entre un namespace et un dossier physique du projet.

Générer l'autoloader

Une fois le fichier composer.json configuré, on demande à Composer de générer l'autoloader.

php composer.phar dump-autoload

Composer lit la configuration et crée un dossier vendor contenant notamment :

vendor/autoload.php

C'est ce fichier que l'on va inclure dans l'application.

require 'vendor/autoload.php';

À partir de là, il n'est plus nécessaire d'inclure chaque classe à la main. On garde les use pour indiquer quelles classes on utilise, et l'autoloader retrouve les fichiers correspondants.

Utiliser les classes après l'autoload

Dans un fichier comme index.php, on commence par inclure l'autoloader.

require 'vendor/autoload.php'; use App\Guestbook\Guestbook; use App\Guestbook\Message;

Ensuite, on peut instancier les classes normalement.

$guestbook = new Guestbook(); $message = new Message();

Si une classe se trouve dans un autre dossier, il suffit que son namespace corresponde à sa position. Par exemple :

src/ └── Blog/ └── Article/ └── Demo.php

correspond au namespace :

namespace App\Blog\Article; class Demo { }

Le namespace doit toujours refléter la structure des dossiers.

Utiliser ::class

Quand une méthode attend le nom complet d'une classe sous forme de chaîne, on peut écrire le namespace directement :

$posts = $query->fetchAll(PDO::FETCH_CLASS, 'App\Post');

Mais on peut aussi utiliser la syntaxe ::class.

use App\Post; $posts = $query->fetchAll(PDO::FETCH_CLASS, Post::class);

Post::class retourne une chaîne qui contient le nom complet de la classe. L'avantage est que l'on peut profiter des imports et de l'autocomplétion de l'éditeur.

Le réflexe à prendre

À partir de maintenant, au démarrage d'un projet PHP, on peut prendre le réflexe suivant :

  • lancer composer init.
  • définir une structure de dossiers pour les classes.
  • configurer l'autoload PSR-4 dans composer.json.
  • lancer composer dump-autoload.
  • inclure vendor/autoload.php au début de l'application.

Ensuite, on range les classes dans des dossiers qui correspondent à leurs namespaces. Composer pourra alors résoudre automatiquement les fichiers qui contiennent les définitions des classes.

Ce système rend les namespaces beaucoup plus agréables à utiliser. On garde une organisation claire, on évite les require partout, et l'éditeur peut aider à importer les bonnes classes automatiquement.

Ressources