Menu

Namespace PHP : namespace, use et alias

Un namespace PHP regroupe classes, fonctions et constantes sous un préfixe : namespace App\Models; en haut d'un fichier, puis use App\Models\User; ailleurs pour désigner la classe par son nom court. Noms pleinement qualifiés, alias use ... as, use function, la barre oblique inverse initiale pour les classes globales, et l'autoloading PSR-4.

Cette page contient des éditeurs exécutables - modifiez, exécutez et voyez la sortie instantanément.

Un namespace PHP place des classes, des fonctions et des constantes sous un préfixe pour que leurs noms ne puissent pas entrer en conflit avec ceux de quelqu'un d'autre. Vous le déclarez avec namespace App\Models; comme première instruction d'un fichier, et les autres fichiers désignent la classe par \App\Models\User, ou l'importent avec use App\Models\User; et écrivent simplement User.

Dans le namespace, User signifie App\Models\User. User::class donne le nom complet sous forme de chaîne sans rien créer, ce qui est pratique pour les logs et les autoloaders.

Deux namespaces dans un fichier

Un vrai projet met un namespace par fichier. Pour une démo autonome, un fichier peut contenir plusieurs namespaces si chacun est entouré d'accolades. Le code qui n'appartient à aucun namespace va dans namespace { } :

Deux classes nommées Order cohabitent car leurs noms complets diffèrent. C'est exactement le problème que résolvent les namespaces une fois que vous installez des bibliothèques : votre Order, l'Order d'une bibliothèque de paiement et l'Order d'une bibliothèque PDF n'entrent plus en conflit.

Importer avec use, et créer un alias avec as

Écrire \Shop\Order partout est lourd. use en haut d'un fichier (ou d'un bloc de namespace) importe un nom pour que vous puissiez utiliser la forme courte. Quand deux imports aboutiraient au même nom court, as donne un autre nom à l'un d'eux :

use ne crée qu'un nom court pour le reste du fichier. Il ne charge aucun fichier, n'exécute aucun code, et fonctionne de la même façon que la classe existe déjà ou non. Les imports groupés sont aussi permis : use Shop\{Order, Invoice};.

use function et use const

Les fonctions et constantes d'un namespace s'importent avec use function et use const :

Les classes globales demandent une barre oblique inverse

Dans un namespace, un nom de classe non qualifié est résolu par rapport à ce namespace, donc new DateTime() dans namespace App; cherche App\DateTime. Les fonctions et les constantes sont différentes : si App\strlen n'existe pas, PHP se rabat sur le strlen global. Les classes ne se rabattent jamais.

Le catch (\Error $e) avait besoin d'une barre oblique inverse pour la même raison : sans elle, PHP chercherait App\Error, ne correspondrait jamais à la vraie erreur, et le script s'arrêterait sur une Error non interceptée. Corrigez-le avec une barre oblique inverse initiale, comme ci-dessus, ou avec use DateTime; en haut du fichier. C'est pareil pour \Exception, \Throwable et toutes les autres classes natives ; voir try catch pour les intercepter.

Autoloading et PSR-4

Dans un projet, chaque classe vit dans son propre fichier, et le chemin du fichier suit le namespace. PSR-4 est la convention : un préfixe de namespace correspond à un dossier de base, et le reste du nom devient le chemin. Un autoloader enregistré avec spl_autoload_register() charge alors le fichier d'une classe la première fois que la classe est utilisée. Ce bloc écrit deux fichiers de classes sur le disque et les charge automatiquement :

Chaque fichier de classe est chargé une fois, au moment où la classe est nécessaire pour la première fois. Dans les vrais projets, vous n'écrivez pas cette fonction vous-même : Composer la génère à partir de quelques lignes dans composer.json :

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

Après composer dump-autoload, un seul require __DIR__ . '/vendor/autoload.php'; au début de votre script d'entrée charge chaque classe App\... à la demande.

Les règles de namespace qui provoquent des erreurs

  • namespace doit être la première instruction du fichier. Seuls declare(strict_types=1); et des commentaires peuvent le précéder.
  • Les imports use valent par fichier. Importer une classe dans index.php ne fait pas fonctionner le nom court dans un fichier inclus ; chaque fichier a besoin de ses propres lignes use.
  • use se place au niveau principal du fichier ou du bloc de namespace. Dans le corps d'une classe, use signifie autre chose : il importe un trait.
  • Les chaînes ne sont jamais résolues : $class = 'User'; new $class(); cherche le User global. Stockez le nom complet, idéalement avec User::class.

La dernière mérite une vérification rapide :

Questions fréquentes

Qu'est-ce qu'un namespace en PHP ?

Un préfixe qui regroupe des classes, interfaces, fonctions et constantes liées, comme un dossier pour les noms. namespace App\Models; en haut d'un fichier place sa classe User à App\Models\User, si bien qu'elle ne peut pas entrer en conflit avec le User d'une autre bibliothèque.

Que fait use en PHP ?

use App\Models\User; en haut d'un fichier permet d'écrire User au lieu du nom complet \App\Models\User dans ce fichier. Il ne charge ni n'inclut rien ; charger le fichier de la classe est le travail de l'autoloader. use ... as Alias; choisit un autre nom court.

Pourquoi ai-je Class not found dans un namespace ?

Dans namespace App;, un nom de classe simple est résolu par rapport au namespace, donc new DateTime() cherche App\DateTime. Écrivez new \DateTime() ou ajoutez use DateTime; en haut. Les fonctions et les constantes se rabattent automatiquement sur le namespace global, pas les classes.

À quoi sert la barre oblique inverse devant un nom de classe en PHP ?

Une barre oblique inverse initiale rend le nom pleinement qualifié, en partant du namespace global : \Exception est toujours l'Exception native de PHP, quel que soit le namespace du code. Sans elle, le nom est résolu par rapport au namespace courant et aux imports use.

Quel est le lien entre namespaces, dossiers et PSR-4 ?

PHP lui-même ne lie pas les namespaces aux dossiers. PSR-4 est la convention qui le fait : un préfixe comme App\ correspond à un dossier comme src/, donc App\Models\User se trouve dans src/Models/User.php. L'autoloader de Composer la suit, c'est pourquoi les deux correspondent en général.

Illustration des langages de programmation de Coddy

Apprendre à coder avec Coddy

COMMENCER