(PHP 5 >= 5.3.0, PHP 7, PHP 8)
En el contexto de las reglas de resolución, hay varias definiciones importantes:
Esto es un identificador que no contiene un separador de espacio de nombres.
Por ejemplo: Foo
Esto es un identificador que contiene un separador de espacio de nombres.
Por ejemplo: Foo\Bar
Esto es un identificador que comienza con un separador de espacio de nombres.
Por ejemplo: \Foo\Bar. El espacio de nombres Foo
también es un nombre absoluto.
Es un identificador que comienza con namespace, como
namespace\Foo\Bar.
Los nombres se resuelven siguiendo las siguientes reglas:
Los nombres absolutos siempre se traducen a nombres sin el separador de namespace.
Por ejemplo, \A\B se traduce a A\B.
Todos los nombres que no son absolutos se traducen con
namespace reemplazado por el namespace actual.
Si el nombre aparece en el namespace global, el prefijo
namespace\ se elimina. Por ejemplo namespace\A
en el namespace X\Y se traduce a X\Y\A.
El mismo nombre en el namespace global se traduce a A.
Para los nombres absolutos, el primer segmento se traduce
de acuerdo con la clase/namespace de la tabla de importación.
Por ejemplo, si el namespace A\B\C se importa como C, el nombre C\D\E se traduce a A\B\C\D\E.
Para los nombres absolutos, si ninguna regla de importación
se aplica, el namespace actual se prefiere al nombre.
Por ejemplo, el nombre C\D\E en el namespace A\B,
se traduce a A\B\C\D\E.
Para los nombres absolutos, el nombre se traduce en relación con la tabla actual de importación para el tipo de símbolo respectivo.
Esto significa que un nombre que se asemeja a una clase se traduce de acuerdo con la tabla de importación de
class/namespace, los nombres de funciones utilizando la
tabla de importación de funciones, y las constantes utilizando la tabla de importación de constantes.
Por ejemplo, después
use A\B\C; un uso como new C() corresponde al nombre
A\B\C(). De manera similar, después de use function A\B\foo; un uso
como foo() corresponde al nombre A\B\foo.
Para los nombres relativos, si ninguna regla se aplica, y el nombre
hace referencia a una clase, el namespace actual sirve como prefijo.
Por ejemplo new C() en el namespace
A\B corresponde al nombre A\B\C.
Para los nombres relativos, si ninguna regla se aplica, y el nombre
hace referencia a una función o constante, y el código está
fuera del namespace global, el nombre se resuelve durante la ejecución.
Supongamos que el código está en el namespace
A\B, aquí es cómo se resuelve una llamada a la función foo():
Busca una función en el espacio de nombres actual:
A\B\foo().
Intenta encontrar y llamar a la función global
foo().
Ejemplo #1 Ejemplos de resolución de espacios de nombres
<?php
namespace A;
use B\D, C\E as F;
// llamadas de funciones
foo(); // intenta llamar a la función "foo" en el espacio de nombres "A"
// luego llama a la función global "foo"
\foo(); // llama a la función "foo" definida en el espacio de nombres global
my\foo(); // llama a la función "foo" definida en el espacio de nombres "A\my"
F(); // intenta llamar a la función "F" definida en el espacio "A"
// luego intenta llamar a la función global "F"
// referencias de clases
new B(); // crea un objeto de la clase "B" definida en el espacio de nombres "A"
// si no se encuentra, intenta el autocargado en la clase "A\B"
new D(); // crea un objeto de la clase "D" definida en el espacio de nombres "B"
// si no se encuentra, intenta el autocargado en la clase "B\D"
new F(); // crea un objeto de la clase "E" definida en el espacio de nombres "C"
// si no se encuentra, intenta el autocargado en la clase "C\E"
new \B(); // crea un objeto de la clase "B" definida en el espacio de nombres global
// si no se encuentra, intenta el autocargado en la clase "B"
new \D(); // crea un objeto de la clase "D" definida en el espacio de nombres global
// si no se encuentra, intenta el autocargado en la clase "D"
new \F(); // crea un objeto de la clase "F" definida en el espacio de nombres global
// si no se encuentra, intenta el autocargado en la clase "F"
// métodos estáticos y funciones de espacio de nombres de otro espacio
B\foo(); // llama a la función "foo" del espacio de nombres "A\B"
B::foo(); // llama al método "foo" de la clase "B" definida en el espacio de nombres "A"
// si la clase "A\B" no se encuentra, intenta el autocargado en la clase "A\B"
D::foo(); // llama al método "foo" de la clase "D" definida en el espacio de nombres "B"
// si la clase "B\D" no se encuentra, intenta el autocargado en la clase "B\D"
\B\foo(); // llama a la función "foo" del espacio de nombres "B"
\B::foo(); // llama al método "foo" de la clase "B" ubicada en el espacio de nombres global
// si la clase "B" no se encuentra, intenta el autocargado en la clase "B"
// métodos estáticos y funciones de espacio de nombres del espacio actual
A\B::foo(); // llama al método "foo" de la clase "B" del espacio de nombres "A\A"
// si la clase "A\A\B" no se encuentra, intenta el autocargado en la clase "A\A\B"
\A\B::foo(); // llama al método "foo" de la clase "B" del espacio de nombres "A"
// si la clase "A\B" no se encuentra, intenta el autocargado en la clase "A\B"