Reglas de resolución de nombres

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

En el contexto de las reglas de resolución, hay varias definiciones importantes:

Definiciones para espacios de nombres
nombre no calificado

Esto es un identificador que no contiene un separador de espacio de nombres. Por ejemplo: Foo

nombre calificado

Esto es un identificador que contiene un separador de espacio de nombres. Por ejemplo: Foo\Bar

Nombre absoluto

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.

Nombre Relativo

Es un identificador que comienza con namespace, como namespace\Foo\Bar.

Los nombres se resuelven siguiendo las siguientes reglas:

  1. Los nombres absolutos siempre se traducen a nombres sin el separador de namespace. Por ejemplo, \A\B se traduce a A\B.
  2. 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.
  3. 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.
  4. 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.
  5. 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.
  6. 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.
  7. 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():
    1. Busca una función en el espacio de nombres actual: A\B\foo().
    2. 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"
?>