W3docs

Comprendre les espaces de noms PHP

Les espaces de noms PHP permettent d'encapsuler des éléments tels que des classes, des fonctions et des constantes dans une structure logique.

Un espace de noms est une façon de regrouper des classes, des interfaces, des fonctions et des constantes liées sous un nom logique unique. Pensez-y comme à des dossiers sur votre disque : deux fichiers nommés index.php peuvent coexister à condition de se trouver dans des dossiers différents. De la même façon, deux classes nommées User peuvent coexister à condition de se trouver dans des espaces de noms différents.

Sans espaces de noms, tous les noms partagent un seul espace global. Dès que votre projet et une bibliothèque tierce définissent tous les deux une classe appelée Logger ou Router, PHP déclenche une erreur fatale Cannot declare class. Les espaces de noms sont la solution standard à ce problème, et ils constituent le fondement du chargement automatique Composer (la norme PSR-4) utilisé par pratiquement tous les packages PHP modernes.

Pourquoi les espaces de noms sont importants

  • Éviter les conflits de noms. Deux morceaux de code peuvent utiliser le même nom de classe ou de fonction à condition de se trouver dans des espaces de noms différents, de sorte que votre code n'entre jamais en conflit avec le code d'une bibliothèque.
  • Organiser les grandes bases de code. Les espaces de noms reflètent votre structure de dossiers, ce qui permet de savoir clairement où se trouve une classe (App\Service\Mailer se trouve dans app/Service/Mailer.php).
  • Permettre le chargement automatique. PSR-4 associe un préfixe d'espace de noms à un répertoire, ce qui permet à Composer de charger les classes à la demande sans instructions require manuelles.

Déclarer un espace de noms

Déclarez un espace de noms avec le mot-clé namespace. Il doit être la toute première instruction dans le fichier (seule une ligne declare(strict_types=1) peut le précéder). Les noms d'espaces de noms utilisent une barre oblique inverse (\) pour séparer les niveaux :

<?php
namespace App\Service;

class Mailer
{
    public function send(string $to): string
    {
        return "Mail sent to {$to}";
    }
}

Tout ce qui est déclaré sous la ligne namespace — la classe Mailer — réside désormais dans App\Service. Son nom complètement qualifié est App\Service\Mailer.

Référencer des éléments avec espace de noms

Il existe trois façons de faire référence à un nom depuis un autre espace de noms.

Un nom complètement qualifié commence par un \ en tête et désigne l'élément depuis la racine globale — il est non ambigu partout :

<?php
$mailer = new \App\Service\Mailer();

Un nom qualifié est relatif à l'espace de noms courant, donc Service\Mailer à l'intérieur de l'espace de noms App est résolu en App\Service\Mailer. Un nom sans barre oblique inverse est non qualifié et est d'abord recherché dans l'espace de noms courant.

Importer avec use

Écrire le chemin complet à chaque fois est fastidieux. Le mot-clé use importe un nom dans le fichier courant afin que vous puissiez y faire référence par son nom court :

<?php
use App\Service\Mailer;

$mailer = new Mailer();   // resolves to App\Service\Mailer

Créer un alias avec as

Lorsque deux classes importées partagent un nom court, donnez-en un alias à l'une avec as pour lever l'ambiguïté :

<?php
use App\Service\Mailer;
use Vendor\Mail\Mailer as VendorMailer;

$a = new Mailer();        // App\Service\Mailer
$b = new VendorMailer();  // Vendor\Mail\Mailer

Importer des fonctions et des constantes

use importe des classes par défaut. Pour importer une fonction ou une constante, ajoutez le mot-clé function ou const :

<?php
use function App\Helpers\format_price;
use const App\Config\TAX_RATE;

Attention : les fonctions intégrées nécessitent une barre oblique inverse en tête

À l'intérieur d'un espace de noms, un nom de fonction ou de classe non qualifié est d'abord résolu dans l'espace de noms courant. Pour les fonctions intégrées, PHP revient automatiquement à la version globale, mais pour les classes intégrées, ce n'est pas le cas. Il faut donc préfixer les classes de base comme Exception, DateTime ou PDO d'une barre oblique inverse en tête (ou utiliser une instruction use) :

<?php
namespace App\Service;

// Wrong: PHP looks for App\Service\Exception, which doesn't exist.
// throw new Exception('boom');

// Right: leading backslash points to the global class.
throw new \Exception('boom');

Un motif courant et lisible consiste à importer la classe de base en haut du fichier à la place :

<?php
namespace App\Service;

use Exception;

throw new Exception('boom');   // now the short name works

Un exemple complet

Ce script unique et exécutable définit deux espaces de noms et les utilise tous les deux — montrant comment le même nom de classe court peut exister à deux endroits sans conflit :

<?php
namespace App\Billing {
    class Invoice
    {
        public function label(): string
        {
            return 'Billing invoice';
        }
    }
}

namespace App\Shipping {
    class Invoice
    {
        public function label(): string
        {
            return 'Shipping invoice';
        }
    }
}

namespace Main {
    use App\Billing\Invoice;
    use App\Shipping\Invoice as ShippingInvoice;

    $billing  = new Invoice();
    $shipping = new ShippingInvoice();

    echo $billing->label() . "\n";
    echo $shipping->label() . "\n";
}

Résultat :

Billing invoice
Shipping invoice

La syntaxe namespace Foo { ... } entre accolades est utilisée uniquement pour placer plusieurs espaces de noms dans un même fichier (pratique pour un exemple autonome). Dans les projets réels, on place un seul espace de noms par fichier et on s'appuie sur le chargement automatique de Composer.

Espaces de noms et chargement automatique (PSR-4)

En pratique, vous écrivez rarement les limites des espaces de noms à la main pour chaque fichier — Composer s'occupe du câblage. Un mappage PSR-4 dans composer.json lie un préfixe d'espace de noms à un dossier :

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

Avec ceci en place, la classe App\Service\Mailer est automatiquement chargée depuis src/Service/Mailer.php la première fois que vous y faites référence — aucun include ou require manuel n'est nécessaire.

Résumé

  • Un espace de noms regroupe des classes, des interfaces, des fonctions et des constantes pour éviter les conflits de noms et organiser le code.
  • Déclarez-le avec namespace App\Service; comme première instruction dans le fichier.
  • Faites référence aux éléments par leur nom complètement qualifié (\App\Service\Mailer) ou, plus couramment, importez-les avec use et utilisez le nom court.
  • Créez des alias pour les noms en conflit avec as, et n'oubliez pas de préfixer les classes globales comme \Exception d'une barre oblique inverse à l'intérieur d'un espace de noms.
  • Le chargement automatique PSR-4 associe un préfixe d'espace de noms à un répertoire, ce qui est la façon dont chaque package Composer est chargé.

Pratique

Pratique
Quels sont les objectifs des espaces de noms PHP ?
Quels sont les objectifs des espaces de noms PHP ?
Was this page helpful?