## Règles de résolutions 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`. L'espace de noms `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 se traduisent toujours par les noms sans le séparateur de namespace. Par exemple, `\A\B` se traduit par `A\B`.
2. Tous les noms qui ne sont pas absolus sont traduit avec le `namespace` remplacé par le namespace courant. Si le nom apparait dans le namespace global, le préfixe `namespace\` est retiré. Par exemple `namespace\A` dans le namespace `X\Y` se traduit par `X\Y\A`. Le même nom dans le namespace global se traduit par `A`.
3. Pour les noms absolus, le premier segment est traduit en accord avec la class/namespace de la table d'importation. 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 absolus, si aucune règle d'import ne s'applique, le namespace courant est préfixé par le 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 absolus, le nom est traduit en lien avec la table courante d'importation pour le type de symbol 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 relatifs, 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 relatifs, 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, the nom est résolu par l'exécution. Supposons que le code est dans le namespace `A\B`, voici comme un appel à la fonction `foo()` est résolu :
   1. Il recherche une fonction dans l'espace de noms 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 l'espace de noms "A"
// puis appelle la fonction globale "foo"
\foo(); // appelle la fonction "foo" définie dans l'espace de noms global
my\foo(); // appelle la fonction "foo" définie dans l'espace de noms "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érence de classes references
new B(); // crée un objet de la classe "B" définie dans l'espace de noms "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 l'espace de noms "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 l'espace de noms "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 l'espace de noms 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 l'espace de noms 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 l'espace de noms 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" de l'espace de noms "A\B"
B::foo(); // appelle la méthode "foo" de la classe "B" définie dans l'espace de noms "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"
?>`