Semaine 4 - Jour 3 : Namespaces et Autoload

Aujourd'hui, nous apprenons à organiser notre code PHP avec les namespaces et à charger automatiquement nos classes avec l'autoloading, en suivant le standard PSR-4.

1. Pourquoi les Namespaces ?

Le problème : Conflits de noms

<?php // Fichier1.php class Database { public function connect() { return "Connexion MySQL"; } } // Fichier2.php (librairie externe) class Database { // ❌ ERREUR : Classe déjà déclarée ! public function connect() { return "Connexion PostgreSQL"; } } ?>

Problème : Impossible d'avoir deux classes avec le même nom dans le même projet !

Solution : Les Namespaces

<?php // src/MonApp/Database.php namespace MonApp; class Database { public function connect() { return "Connexion MySQL"; } } // vendor/Librairie/Database.php namespace Librairie; class Database { // ✅ OK : Namespace différent ! public function connect() { return "Connexion PostgreSQL"; } } ?>

2. Déclarer et utiliser des Namespaces

Syntaxe de base

<?php // src/Models/Utilisateur.php // Déclarer le namespace (TOUJOURS en premier, après <?php) namespace Models; class Utilisateur { private $nom; public function __construct($nom) { $this->nom = $nom; } public function getNom() { return $this->nom; } } ?>

Utiliser une classe avec namespace

<?php // index.php require 'src/Models/Utilisateur.php'; // Méthode 1 : Nom complet qualifié (FQCN) $user1 = new \Models\Utilisateur("Jean"); // Méthode 2 : Utiliser 'use' pour importer use Models\Utilisateur; $user2 = new Utilisateur("Marie"); // Méthode 3 : Utiliser un alias use Models\Utilisateur as User; $user3 = new User("Paul"); echo $user1->getNom() . "<br>"; echo $user2->getNom() . "<br>"; echo $user3->getNom(); ?>

Résultat :

Jean
Marie
Paul

3. Organisation du code avec Namespaces

Structure recommandée

projet/ │ ├── src/ │ ├── Controllers/ │ │ ├── HomeController.php // namespace Controllers; │ │ └── UserController.php // namespace Controllers; │ │ │ ├── Models/ │ │ ├── User.php // namespace Models; │ │ └── Article.php // namespace Models; │ │ │ ├── Views/ │ │ └── home.php │ │ │ └── Database/ │ ├── Connection.php // namespace Database; │ └── QueryBuilder.php // namespace Database; │ ├── public/ │ └── index.php │ └── vendor/ // Bibliothèques tierces (Composer)

Exemple complet avec sous-namespaces

<?php // src/Models/User.php namespace Models; class User { public $nom; } // src/Controllers/UserController.php namespace Controllers; use Models\User; // Importer la classe User class UserController { public function index() { $user = new User(); $user->nom = "Jean Dupont"; return $user; } } // public/index.php use Controllers\UserController; $controller = new UserController(); $user = $controller->index(); echo $user->nom; ?>

4. Autoloading avec spl_autoload_register()

Le problème des require multiples

<?php // ❌ MAUVAIS : Trop de require manuels ! require 'src/Models/User.php'; require 'src/Models/Article.php'; require 'src/Models/Comment.php'; require 'src/Controllers/HomeController.php'; require 'src/Controllers/UserController.php'; // ... et 50 autres fichiers ?>

Solution : Autoloader automatique

<?php // autoload.php - Charger automatiquement les classes spl_autoload_register(function ($class) { // Exemple : $class = "Models\User" // Remplacer les \ par / pour le chemin de fichier $class = str_replace('\\', '/', $class); // Résultat : "Models/User" // Construire le chemin du fichier $file = __DIR__ . '/src/' . $class . '.php'; // Résultat : "/chemin/projet/src/Models/User.php" // Charger le fichier s'il existe if (file_exists($file)) { require $file; } }); // Maintenant, plus besoin de require ! use Models\User; use Controllers\UserController; $user = new User(); // ✅ Chargé automatiquement ! $controller = new UserController(); // ✅ Chargé automatiquement ! ?>

5. PSR-4 : Standard d'autoloading

Qu'est-ce que PSR-4 ?

PSR-4 (PHP Standards Recommendation 4) est un standard qui définit comment organiser vos classes et namespaces.

Règle simple : Le namespace doit correspondre à la structure des dossiers.

Namespace Chemin du fichier
Models\User src/Models/User.php
Controllers\UserController src/Controllers/UserController.php
Database\MySQL\Connection src/Database/MySQL/Connection.php

Autoloader conforme PSR-4

<?php // autoload-psr4.php spl_autoload_register(function ($class) { // Préfixe de namespace de base $prefix = ''; // Répertoire de base pour le préfixe de namespace $baseDir = __DIR__ . '/src/'; // Obtenir le nom de classe relatif $relativeClass = $class; // Remplacer le namespace par le séparateur de répertoire $file = $baseDir . str_replace('\\', '/', $relativeClass) . '.php'; // Si le fichier existe, le charger if (file_exists($file)) { require $file; } }); ?>

6. Introduction à Composer

Qu'est-ce que Composer ?

Gestionnaire de dépendances : Composer installe et gère les bibliothèques PHP de votre projet, comme npm pour Node.js.

Autoloader intégré : Composer génère automatiquement un autoloader PSR-4 pour vous ! Plus besoin d'écrire votre propre autoloader.

Fichier composer.json

{ "name": "monprojet/monapp", "description": "Mon application PHP", "autoload": { "psr-4": { "": "src/" } }, "require": { "php": ">=7.4" } }

Utiliser l'autoloader de Composer

<?php // public/index.php // Charger l'autoloader généré par Composer require_once __DIR__ . '/../vendor/autoload.php'; // Maintenant toutes vos classes sont chargées automatiquement ! use Models\User; use Controllers\UserController; $user = new User(); $controller = new UserController(); ?>

Commandes Composer essentielles :

  • composer install : Installer les dépendances
  • composer require vendor/package : Ajouter une bibliothèque
  • composer dump-autoload : Régénérer l'autoloader
  • composer update : Mettre à jour les dépendances

7. Exemple complet

Structure du projet

monprojet/ │ ├── src/ │ ├── Models/ │ │ └── User.php // namespace Models; │ ├── Controllers/ │ │ └── UserController.php // namespace Controllers; │ └── Database/ │ └── Connection.php // namespace Database; │ ├── public/ │ └── index.php │ ├── autoload.php └── composer.json

Code complet

<?php // autoload.php spl_autoload_register(function ($class) { $file = __DIR__ . '/src/' . str_replace('\\', '/', $class) . '.php'; if (file_exists($file)) { require_once $file; } }); // public/index.php require_once __DIR__ . '/../autoload.php'; use Controllers\UserController; use Database\Connection; $controller = new UserController(); $user = $controller->show(1); echo "Utilisateur : " . htmlspecialchars($user->getNom()) . "<br>"; $db = new Connection(); echo $db->connect(); ?>

Résultat :

Utilisateur : Jean Dupont
Connexion établie
Froggiesplaining :


Objectifs de ce cours :
✅ Comprendre le problème des conflits de noms de classes
✅ Déclarer et utiliser des namespaces
✅ Organiser le code selon le standard PSR-4
✅ Créer un autoloader avec spl_autoload_register()
✅ Utiliser Composer pour l'autoloading automatique

Points clés à retenir :
Namespaces = Quartiers de la mare (MareNord\Froggie vs MareSud\Froggie)
use = Raccourci pour importer une classe sans écrire le chemin complet
Autoloading = Majordome magique qui charge les classes automatiquement
PSR-4 = Standard qui fait correspondre namespace et structure de dossiers
spl_autoload_register() = Fonction PHP pour créer un autoloader custom
Composer = Super majordome qui gère tout (classes + bibliothèques tierces)
• Un seul require 'vendor/autoload.php' et tout est chargé automatiquement
• Organisation: namespace Models; dans src/Models/User.php

Exercice pratique :
1. Créer la structure: src/Models/, src/Controllers/, src/Views/
2. Créer Models\User.php avec namespace Models;
3. Créer Controllers\UserController.php avec namespace Controllers;
4. Créer un autoload.php avec spl_autoload_register()
5. Dans index.php, require l'autoload puis use Models\User;
6. Instancier un User sans require manuel du fichier
7. Bonus: Installer Composer et configurer composer.json avec PSR-4
8. Conseil de Froggie: Utilise Composer dès que possible ! C'est comme avoir un GPS dans la mare, tu ne te perds jamais.

Froggie explain

GitHub - eCrea