Los espacios de nombresIntroducción a los espacios de nombresIntroducción
¿Qué son los espacios de nombres? En su definición más amplia, representan
un medio para encapsular elementos. Esto puede concebirse como un concepto
abstracto, por varias razones. Por ejemplo, en un sistema de archivos, los
directorios representan un grupo de archivos asociados y sirven como espacio de nombres
para los archivos que contienen. Un ejemplo concreto es que el archivo
foo.txt puede existir en ambos directorios
/home/greg y /home/other, pero que
las dos copias de foo.txt no pueden coexistir
en el mismo directorio. Además, para acceder al archivo foo.txt
desde fuera del directorio /home/greg, es necesario especificar
el nombre del directorio utilizando un separador de directorios, como
/home/greg/foo.txt. El mismo principio se aplica a los
espacios de nombres en el mundo de la programación.
En el mundo de PHP, los espacios de nombres están diseñados para resolver dos problemas
que enfrentan los autores de bibliotecas y aplicaciones al reutilizar elementos
como clases o bibliotecas de funciones:
Colisiones de nombres entre el código que se crea, las clases, funciones
o constantes internas de PHP, o las de bibliotecas de terceros.
La capacidad de crear alias o acortar nombres como Nombres_Extremadamente_Largos
para ayudar a resolver el primer problema y mejorar la legibilidad
del código.
Los espacios de nombres de PHP proporcionan un medio para agrupar clases, interfaces,
funciones o constantes. Aquí hay un ejemplo de sintaxis de los espacios de nombres de PHP:
Ejemplo de sintaxis de espacios de nombres
]]>
Los nombres de espacios de nombres no son sensibles a mayúsculas/minúsculas.
Los espacios de nombres PHP, así como los nombres compuestos
que comienzan con estos nombres (como PHP\Classes)
están reservados para el uso interno del lenguaje y no deben usarse
en el código del espacio de usuario.
Definición de espacios de nombresEspacios de nombres
Aunque el código PHP válido puede contenerse en un espacio de nombres,
solo los siguientes tipos de código pueden verse afectados por los espacios de nombres:
las clases (incluyendo las abstractas, los traits y los enums), las interfaces,
las funciones y las constantes.
Los espacios de nombres se declaran con la palabra clave namespace.
Un archivo que contiene un espacio de nombres debe declarar el espacio al principio
del archivo, antes de cualquier otro código, con una sola excepción: la palabra
clave .
Declaración de un espacio de nombres
]]>
Los nombres completamente calificados (es decir, los nombres que comienzan con un backslash)
no están autorizados en las declaraciones de espacios de nombres, ya que tales
construcciones se interpretan como expresiones de espacio de nombres relativo.
El único elemento autorizado antes de la declaración de espacio de nombres es la instrucción
declare, para definir la codificación del archivo fuente. Además,
ningún código no-PHP puede preceder a la declaración de espacio de nombres, incluyendo
espacios:
Error de declaración de un espacio de nombres
]]>
Además, a diferencia de otras estructuras de PHP, el mismo espacio de nombres puede
definirse en varios archivos, lo que permite dividir el contenido de un
espacio de nombres en varios archivos.
Declaración de un subespacio de nombresSubespacio de nombres
Al igual que con los archivos y los directorios, los espacios de nombres también
son capaces de especificar una jerarquía de espacios de nombres. Por lo tanto,
un nombre de espacio de nombres puede definirse con sus subniveles:
Declaración de un espacio de nombres con jerarquía
]]>
En el ejemplo anterior, se crean la constante MonProjet\Sous\Niveau\CONNEXION_OK,
la clase MonProjet\Sous\Niveau\Connexion y la función
MonProjet\Sous\Niveau\connecte.
Definición de varios espacios de nombres en el mismo archivoDefinición de varios espacios de nombres en el mismo archivo
También pueden declararse varios espacios de nombres en el mismo archivo.
Hay dos sintaxis autorizadas.
Declaración de varios espacios de nombres, sintaxis de combinación simple
]]>
Esta sintaxis no se recomienda para combinar espacios de nombres
en un solo archivo. En su lugar, se recomienda utilizar
la sintaxis de llaves.
Declaración de varios espacios de nombres, sintaxis de llaves
]]>
Se recomienda encarecidamente, como práctica de codificación, no mezclar
varios espacios de nombres en el mismo archivo. El uso recomendado es combinar
varios scripts PHP en el mismo archivo.
Para combinar varios códigos sin espacios de nombres en código con espacio de nombres,
solo se admite la sintaxis de llaves. El código global debe estar encerrado por un
espacio de nombres sin nombre, como este:
Declaración de varios espacios de nombres con un espacio sin nombre
]]>
No puede existir ningún código PHP fuera de las llaves del espacio de nombres,
excepto para abrir una nueva instrucción declare.
Declaración de varios espacios de nombres con un espacio sin nombre (2)
]]>
Uso de espacios de nombres: introducciónIntroducción
Antes de discutir el uso de espacios de nombres, es importante comprender
cómo PHP deduce qué espacio de nombres está utilizando su código. Puede hacerse
una analogía simple entre los espacios de nombres de PHP y un sistema de archivos.
Hay tres formas de acceder a un archivo en un sistema de archivos:
Un nombre de archivo relativo, como foo.txt. Esto se resuelve
en dossiercourant/foo.txt donde dossiercourant es el
directorio de trabajo. Si el directorio actual es /home/foo,
este nombre se resuelve en /home/foo/foo.txt.
Una ruta relativa, como sub-dossier/foo.txt. Esto se
resuelve en dossiercourant/sub-dossier/foo.txt.
Una ruta absoluta, como /main/foo.txt. Esto se resuelve
en /main/foo.txt.
El mismo principio puede aplicarse a los espacios de nombres de PHP.
Por ejemplo, puede hacer referencia a una clase de tres maneras:
Un nombre sin calificador, o una clase sin prefijo, como
$a = new foo(); o
foo::methodestatique();. Si el espacio de nombres actual
es espacedenomscourant, esto se resuelve en
espacedenomscourant\foo. Si el espacio de nombres es
global, es decir, el espacio de nombres sin nombre, esto se convierte en foo.
Una advertencia: los nombres sin calificador para funciones y constantes
se tomarán del espacio de nombres global, si la función
no está definida en el espacio de nombres actual. Ver
Uso de espacios de nombres:
retorno al espacio de nombres global para funciones y constantes para
más detalles.
Un nombre calificado, o una clase con prefijo como
$a = new sousespacedenoms\foo(); o
sousespacedenoms\foo::methodestatique();. Si el espacio de nombres actual
es espacedenomscourant, esto se convierte
en espacedenomscourant\sousespacedenoms\foo. Si
el código es global, es decir, el espacio de nombres sin nombre,
esto se convierte en sousespacedenoms\foo.
Un nombre absoluto, o un nombre con prefijo con un operador global como
$a = new \espacedenomscourant\foo(); o
\espacedenomscourant\foo::methodestatique();. Esto siempre
hace referencia al nombre literal especificado en el código: espacedenomscourant\foo.
Aquí hay un ejemplo de las tres sintaxis, en código real:
file1.php
]]>
file2.php
]]>
Tenga en cuenta que para acceder a cualquier clase, función o constante
global, puede utilizarse un nombre absoluto, como
\strlen o \Exception o
\INI_ALL.
Acceso a clases, funciones y constantes globales desde un espacio de nombres
]]>
Espacios de nombres y lenguaje dinámicoEspacios de nombres y lenguaje dinámico
La implementación de espacios de nombres de PHP está influenciada por su naturaleza
dinámica como lenguaje de programación. Por lo tanto, para convertir código como el
del siguiente ejemplo en un espacio de nombres:
Acceso dinámico a elementosexample1.php:
]]>
Es necesario utilizar un nombre absoluto (el nombre de la clase, con su prefijo de espacio de nombres).
Tenga en cuenta que no hay diferencia entre un nombre absoluto y un nombre calificado
en un nombre de clase, función o constante dinámica, lo que hace que el backslash
inicial no sea necesario.
Acceso dinámico a espacios de nombres
]]>
Se recomienda leer la nota sobre la protección de espacios de nombres en cadenas.
El comando namespace y la constante __NAMESPACE__Comando namespace y __NAMESPACE__
PHP admite dos medios para acceder de manera abstracta a los elementos
en el espacio de nombres actual, a saber, la constante mágica
__NAMESPACE__ y el comando namespace.
El valor de __NAMESPACE__ es una cadena que contiene el nombre
del espacio de nombres actual. En el espacio global, sin nombre, contiene
una cadena vacía.
Ejemplo con __NAMESPACE__, en un código con espacio de nombres
]]>
Ejemplo con __NAMESPACE__, en un código con espacio de nombres global
]]>
La constante __NAMESPACE__ es útil para construir
dinámicamente nombres, como:
Uso de __NAMESPACE__ para una construcción dinámica de nombres
]]>
El comando namespace también puede usarse para
solicitar explícitamente un elemento del espacio de nombres actual, o de un
subespacio. Es el equivalente para los espacios de nombres del operador
self de las clases.
El operador namespace, en un espacio de nombres
]]>
El operador namespace, en el espacio de nombres global
]]>
Uso de espacios de nombres: importación y aliasImportación y alias
La capacidad de hacer referencia a un nombre absoluto con un alias o importando
un espacio de nombres es estratégica. Es un beneficio similar a los enlaces
simbólicos en un sistema de archivos.
PHP puede crear alias(/importar) constantes, funciones, clases, interfaces,
traits, enumeraciones y espacios de nombres.
Un alias se crea con el operador use.
Aquí hay un ejemplo que presenta los cinco tipos de importación:
Importación y alias con el operador use
]]>
Tenga en cuenta que para los nombres con ruta (los nombres absolutos que contienen
separadores de espacios, como Foo\Bar, en comparación con
los nombres globales, como FooBar, que no los contienen),
el backslash inicial no es necesario y no se recomienda, ya que los nombres importados
deben ser absolutos y no se resuelven relativamente al espacio de nombres actual.
Además, PHP admite atajos prácticos, como las instrucciones use múltiples.
Importación y alias múltiples con el operador use
]]>
La importación se realiza durante la compilación, por lo que no afecta
a las clases, funciones y constantes dinámicas.
Importación y nombres de espacios dinámicos
]]>
Además, la importación solo afecta a los nombres sin calificación. Los nombres
absolutos siguen siendo absolutos y no se modifican por una importación.
Importación y nombres de espacios absolutos
]]>
Reglas de contexto para la importación
La palabra clave use debe declararse en el contexto más
externo de un archivo (el contexto global) o en las declaraciones de espacio
de nombres. Esto se debe a que la importación se realiza durante la compilación
y no durante la ejecución, por lo que no se pueden apilar los contextos. El ejemplo
siguiente muestra usos incorrectos de la palabra clave use:
Reglas de importación incorrectas
]]>
Las reglas de importación se basan en archivos, lo que significa que los archivos
incluidos no heredarán PAS las reglas de importación del archivo padre.
Declaración del grupo use
Las clases, funciones y constantes importadas desde
el mismo &namespace; pueden agruparse en una
sola instrucción &use.namespace;.
Espacio de nombres globalGlobal
Sin ninguna definición de espacio de nombres, todas las clases y las funciones
se colocan en el espacio de nombres global: como en PHP antes de que los espacios
de nombres fueran introducidos. Al prefijar un nombre con un backslash
\, se puede solicitar el uso del espacio de nombres
global, incluso en un contexto de espacio de nombres específico.
Especificación de espacio de nombres global
]]>
Uso de espacios de nombres: retorno al espacio global para funciones y constantesRetorno al espacio global
En un espacio de nombres, cuando PHP encuentra un nombre sin calificación,
ya sea una clase, una función o una constante, lo resuelve con diferentes
prioridades. Los nombres de clases siempre se resuelven con el espacio de nombres actual.
Para acceder a clases internas o a clases que no están en
un espacio de nombres, es necesario representarlas con su nombre absoluto, como:
Acceso a clases globales desde un espacio de nombres
]]>
Para las funciones y constantes, PHP las buscará en el espacio
global si no puede encontrarlas en el espacio de nombres actual.
Acceso a funciones y constantes globales en un espacio de nombres
]]>
Reglas de resolución de nombresReglas de resolución de nombres
En el contexto de las reglas de resolución, hay varias definiciones importantes:
Definiciones para espacios de nombresnombre no calificado
Esto es un identificador que no contiene un separador de espacio de nombres.
Por ejemplo: Foonombre calificado
Esto es un identificador que contiene un separador de espacio de nombres.
Por ejemplo: Foo\BarNombre 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:
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 globalfoo().
Ejemplos de resolución de espacios de nombres
]]>
Preguntas frecuentes: lo que debe saber sobre espacios de nombresPreguntas frecuentes
Esta FAQ se divide en dos secciones: las preguntas comunes,
y los puntos particulares de la implementación, que pueden ser
útiles para la comprensión global.
Primero, las preguntas comunes.
Si no utilizo espacios
de nombres, ¿debo preocuparme por ellos?
¿Cómo utilizar una clase
global o interna desde un espacio de nombres?
¿Cómo utilizar las clases
de espacios de nombres, las funciones o las constantes en su propio espacio?
¿Cómo se resuelve un nombre como \mon\nom o
\nom?
¿Cómo se resuelve un nombre
como mon\nom?
¿Cómo se resuelve un nombre de clase
sin calificación, como nom?
¿Cómo se resuelve una función sin
calificación o una constante de nombre nom?
Aquí están los puntos particulares de la implementación, que pueden ser
útiles para la comprensión global.
Los nombres importados no deben
entrar en conflicto con las clases definidas en el mismo archivo
Los espacios de nombres anidados
están prohibidos
Los nombres de espacios de nombres
dinámicos deben proteger el backslash
Las constantes no definidas
referenciadas con un backslash producen un error fatal
Imposible reemplazar
constantes especiales como &null;, &true; o &false;
Si no utilizo espacios de nombres, ¿debo preocuparme por ellos?
No, los espacios de nombres no afectan el código existente, de una
manera u otra, ni el código que se producirá y que no utiliza
espacios de nombres. Puede escribir esto si lo desea:
Acceso a una clase global desde fuera de un espacio de nombres
]]>
Es una funcionalidad equivalente a:
Acceder a clases globales fuera de un espacio de nombres
]]>
¿Cómo utilizar una clase global o interna desde un espacio de nombres?Acceso a clases internas desde un espacio de nombres
]]>
¿Cómo utilizar las clases de espacios de nombres, las funciones o
las constantes en su propio espacio?
Acceso a clases, funciones y constantes internas en un espacio de nombres
]]>
¿Cómo se resuelve un nombre como \mon\nom o
\nom?
Los nombres que comienzan con \ siempre se resuelven como son,
por lo que \mon\nom es en realidad
mon\nom, y \Exception es
Exception.
Nombres de espacios absolutos
]]>
¿Cómo se resuelve un nombre como mon\nom?
Los nombres que contienen un backslash pero no comienzan con un
backslash, como mon\nom pueden resolverse de dos maneras
diferentes.
Si ha habido una instrucción de importación que hace un alias de
mon, entonces el alias importado se aplica en lugar
de mon, y el espacio de nombres se convierte en mon\nom.
De lo contrario, el espacio de nombres actual se agrega antes del camino de la clase
mon\nom.
Nombres calificados
]]>
¿Cómo se resuelve un nombre de clase
sin calificación, como nom?
Los nombres de clases que no contienen backslash como
nom pueden resolverse de dos maneras diferentes.
Si hay una instrucción de importación que define un alias para nom,
entonces se aplica el alias.
De lo contrario, se utiliza el espacio de nombres actual y se prefiere a
nom.
Clases sin calificación
]]>
¿Cómo se resuelve una función sin calificación o una constante
de nombre nom?
Las funciones y constantes que no tienen backslash en su nombre
como nom se resuelven de dos maneras diferentes:
Primero, se prefiere el espacio de nombres actual a nom.
Luego, si la constante o función nom no existe
en el espacio de nombres actual, se utiliza la versión global de la constante o la
función nom.
Funciones y constantes sin espacio de nombres
]]>
Los nombres importados no deben
entrar en conflicto con las clases definidas en el mismo archivo
La siguiente combinación de scripts es válida:
file1.php
]]>
another.php
]]>
file2.php
]]>
No hay conflicto de nombres, incluso si la clase MaClasse existe
en el espacio de nombres mes\trucs, ya que la definición de
MaClasse está en un archivo separado. Sin embargo, el siguiente
ejemplo produce un error fatal debido a un conflicto de nombres, ya que
MaClasse se define en el mismo archivo que la instrucción
use.
]]>
Los espacios de nombres anidados están prohibidos
PHP no permite anidar espacios de nombres.
]]>
Sin embargo, es fácil simular espacios de nombres anidados,
como esto:
]]>
Los nombres de espacios de nombres dinámicos deben proteger el backslash
Es muy importante darse cuenta de que, como los backslash se utilizan como
caracteres de escape en las cadenas, siempre deben duplicarse
para poder usarlos en una cadena. De lo contrario, existe el riesgo de uso
inesperado:
Peligros de usar espacios de nombres en una cadena
]]>
En una cadena de comillas dobles, la secuencia de escape es mucho más
segura de usar, pero aún se recomienda proteger siempre los backslashs en una cadena que contiene un espacio de nombres.
Constantes no definidas referenciadas con un backslash producen un error fatal
Cualquier constante no definida que no tenga calificador como
FOO producirá una advertencia: PHP asumía que
FOO era el valor de la constante. Cualquier constante,
calificada parcialmente o totalmente, que contenga un backslash, producirá
un error fatal si no está definida.
Constantes no definidas
]]>
Imposible reemplazar constantes especiales como &null;, &true; o &false;
Cualquier intento en un espacio de nombres de reemplazar las constantes
nativas o especiales, produce un error fatal.
Constantes que no pueden ser redefinidas
]]>