Règles de résolution de noms

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

Dans le cadre des règles de résolution, il y a plusieurs définitions importantes :

Définitions pour les espaces de noms
nom non qualifié

Ceci est un identifiant ne contenant pas un séparateur d'espace de noms. Par exemple : Foo

nom qualifié

Ceci est un identifiant contenant un séparateur d'espace de noms. Par exemple : Foo\Bar

Nom absolu

Ceci est un identifiant qui commence par un séparateur d'espace de noms. Par exemple : \Foo\Bar. le namespace Foo est aussi un nom absolu.

Nom Relatif

C'est un identifiant commençant par namespace, tel que namespace\Foo\Bar.

Les noms sont résolus en suivant les règles suivantes :

  1. Les noms absolus sont toujours résolus en le nom sans le séparateur de namespace initial. Par exemple, \A\B est résolu en A\B.
  2. Les noms relatifs sont toujours résolus en remplaçant namespace par le namespace courant. Si le nom apparaît dans le namespace global, le préfixe namespace\ est retiré. Par exemple, namespace\A dans le namespace X\Y est résolu en X\Y\A. Le même nom dans le namespace global est résolu en A.
  3. Pour les noms qualifiés, le premier segment est traduit en accord avec la table d'importation des class/namespace. Par exemple, si le namespace A\B\C est importé comme C, le nom C\D\E est traduit par A\B\C\D\E.
  4. Pour les noms qualifiés, si aucune règle d'import ne s'applique, le namespace courant est préfixé au nom. Par exemple le nom C\D\E dans le namespace A\B, est traduit par A\B\C\D\E.
  5. Pour les noms non qualifiés, le nom est traduit en lien avec la table courante d'importation pour le type de symbole respectif. Cela signifie qu'un nom ressemblant à une classe est traduit en accord avec la table d'importation des class/namespace, les noms de fonctions en utilisant la table d'importation des fonctions, et les constantes en utilisant la table d'importation des constantes. Par exemple, après use A\B\C; un usage tel que new C() correspond au nom A\B\C(). De la même manière, après use function A\B\foo; un usage tel que foo() correspond au nom A\B\foo.
  6. Pour les noms non qualifiés, si aucune règle ne s'applique, et que le nom fait référence à une classe, le namespace courant sert de préfixe. Par exemple new C() dans le namespace A\B correspond au nom A\B\C.
  7. Pour les noms non qualifiés, si aucune règle ne s'applique, et que le nom fait référence à une fonction ou une constante, et que le code est en dehors du namespace global, le nom est résolu à l'exécution. Supposons que le code est dans le namespace A\B, voici comment un appel à la fonction foo() est résolu :
    1. Il recherche une fonction dans le namespace courant : A\B\foo().
    2. Il essaie de trouver et appeler la fonction globale foo().

Exemple #1 Exemples de résolutions d'espaces de noms

<?php
namespace A;
use
B\D, C\E as F;

// appels de fonctions

foo(); // tente d'appeler la fonction "foo" dans le namespace "A"
// puis appelle la fonction globale "foo"

\foo(); // appelle la fonction "foo" définie dans le namespace global

my\foo(); // appelle la fonction "foo" définie dans le namespace "A\my"

F(); // tente d'appeler la fonction "F" définie dans l'espace "A"
// puis tente d'appeler la fonction globale "F"

// références de classes

new B(); // crée un objet de la classe "B" définie dans le namespace "A"
// si non trouvé, il essaie l'autochargement sur la classe "A\B"

new D(); // crée un objet de la classe "D" définie dans le namespace "B"
// si non trouvé, il essaie l'autochargement sur la classe "B\D"

new F(); // crée un objet de la classe "E" définie dans le namespace "C"
// si non trouvé, il essaie l'autochargement sur la classe "C\E"

new \B(); // crée un objet de la classe "B" définie dans le namespace global
// si non trouvé, il essaie l'autochargement sur la classe "B"

new \D(); // crée un objet de la classe "D" définie dans le namespace global
// si non trouvé, il essaie l'autochargement sur la classe "D"

new \F(); // crée un objet de la classe "F" définie dans le namespace global
// si non trouvé, il essaie l'autochargement sur la classe "F"

// méthodes statiques et fonctions d'espace de noms d'un autre espace

B\foo(); // appelle la fonction "foo" du namespace "A\B"

B::foo(); // appelle la méthode "foo" de la classe "B" définie dans le namespace "A"
// si la classe "A\B" n'est pas trouvée, il essaie l'autochargement sur la classe "A\B"

D::foo(); // appelle la méthode "foo" de la classe "D" définie dans l'espace de noms "B"
// si la classe "B\D" n'est pas trouvée, il essaie l'autochargement sur la classe "B\D"

\B\foo(); // appelle la fonction "foo" de l'espace de noms "B"

\B::foo(); // appelle la méthode "foo" de la classe "B" située dans l'espace de noms global
// si la classe "B" n'est pas trouvée, il essaie l'autochargement sur la classe "B"

// méthodes statiques et fonctions d'espace de noms de l'espace courant

A\B::foo(); // appelle la méthode "foo" de la classe "B" de l'espace de noms "A\A"
// si la classe "A\A\B" n'est pas trouvée, il essaie l'autochargement sur la classe "A\A\B"

\A\B::foo(); // appelle la méthode "foo" de la classe "B" de l'espace de noms "A"
// si la classe "A\B" n'est pas trouvée, il essaie l'autochargement sur la classe "A\B"
?>