1
0
mirror of https://github.com/php/doc-es.git synced 2026-03-24 07:22:16 +01:00
Files
archived-doc-es/language/namespaces.xml
Gina Peter Banyard 54d93097df Apply revchecked skipped commit c60943fefc4ff8950460e76d714a463437cf0eb2
Replace PHP_INI_* with INI_* constants
2024-01-26 13:53:49 +00:00

1610 lines
54 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<!-- EN-Revision: e52f86cf48f181cefa150a4d89c90a8a8a5c6bad Maintainer: seros Status: ready -->
<!-- Reviewed: no Maintainer: seros -->
<chapter xml:id="language.namespaces" xmlns="http://docbook.org/ns/docbook"
version="1.1">
<title>Espacios de nombres</title>
<sect1 xml:id="language.namespaces.rationale">
<title>Resumen de los espacios de nombres</title>
<?phpdoc print-version-for="namespaces"?>
<simpara>
¿Qué son los espacios de nombres? En su definición más aceptada, los espacios de nombres son una manera
de encapsular elementos. Se pueden ver como un concepto abstracto en muchos aspectos. Por ejemplo, en cualquier
sistema operativo, los directorios sirven para agrupar ficheros relacionados, actuando así como espacios de nombres
para los ficheros que contienen. Como ejemplo, el fichero <literal>foo.txt</literal> puede
existir en los directorios <literal>/home/greg</literal> y <literal>/home/otro</literal>,
pero no pueden coexistir dos copias de <literal>foo.txt</literal> en el mismo directorio.
Además, para acceder al fichero <literal>foo.txt</literal> fuera del
directorio <literal>/home/greg</literal>, se debe anteponer el nombre del directorio al nombre
del fichero, empleando el separador de directorios para así obtener <literal>/home/greg/foo.txt</literal>.
Este mismo principio se extiende a los espacios de nombres en el mundo de la programación.
</simpara>
<para>
<informaltable>
<tgroup cols="2">
<thead>
<row>
<entry>&Version;</entry>
<entry>&Description;</entry>
</row>
</thead>
<tbody>
<row>
<entry>7.0.0</entry>
<entry>
Añadidas las Declaraciones de use en grupo.
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
<simpara>
En el mundo de PHP, los espacios de nombres están diseñados para solucionar dos problemas con los
que se encuentran los autores de bibliotecas y de aplicaciones al crear elementos de código reusable,
tales como clases o funciones:
</simpara>
<para>
<orderedlist>
<listitem>
<simpara>
El conflicto de nombres entre el código que se crea y
las clases/funciones/constantes internas de PHP o las clases/funciones/constantes de terceros.
</simpara>
</listitem>
<listitem>
<simpara>
La capacidad de apodar (o abreviar) Nombres_Extra_Largos diseñada para aliviar el primer problema,
mejorando la legibilidad del código fuente.
</simpara>
</listitem>
</orderedlist>
</para>
<simpara>
Los espacios de nombres de PHP proporcionan una manera para agrupar clases, interfaces, funciones
y constantes relacionadas. Un ejemplo de la sintaxis de los espacios de nombres de PHP:
</simpara>
<example>
<title>Ejemplo de sintaxis de espacios de nombres</title>
<programlisting role="php">
<![CDATA[
<?php
namespace mi\nombre; // véase la sección "Definir espacios de nombres"
class MiClase {}
function mifunción() {}
const MICONSTANTE = 1;
$a = new MiClase;
$c = new \mi\nombre\MiClase; // véase la sección "Espacio global"
$a = strlen('hola'); // véase la sección "Utilizar espacios de nombres: una
// alternativa a funciones/constantes globales"
$d = namespace\MICONSTANTE; // véase la sección "El operador namespace y
// la constante __NAMESPACE__"
$d = __NAMESPACE__ . '\MICONSTANTE';
echo constant($d); // véase la sección "Espacios de nombres y características dinámicas del lenguaje"
?>
]]>
</programlisting>
</example>
<note>
<para>
Los nombres de los espacios de nombres <literal>PHP</literal> y <literal>php</literal>, y los nombres compuestos
a partir de estos (como <literal>PHP\Classes</literal>) están reservados para el uso interno del lenguaje
y no deben utilizarse en el código del espacio del usuario.
</para>
</note>
</sect1>
<sect1 xml:id="language.namespaces.definition">
<title>Definir espacios de nombres</title>
<?phpdoc print-version-for="namespaces"?>
<para>
Aunque cualquier código de PHP válido puede estar contenido dentro de un espacio de nombres, solamente se ven
afectados por espacios de nombres los siguientes tipos de código: clases (incluyendo abstractas y traits), interfaces, funciones y constantes.
</para>
<para>
Los espacios de nombres se declaran utilizando la palabra reservada <literal>namespace</literal>.
Un fichero que contenga un espacio de nombres debe declararlo al inicio
del mismo, antes que cualquier otro código, con una excepción: la
palabra reservada <xref linkend="control-structures.declare" />.
<example>
<title>Declarar un único espacio de nombres</title>
<programlisting role="php">
<![CDATA[
<?php
namespace MiProyecto;
const CONECTAR_OK = 1;
class Conexión { /* ... */ }
function conectar() { /* ... */ }
?>
]]>
</programlisting>
</example>
La única construcción de código permitida antes de la declaración de un espacio de nombres es la
sentencia <literal>declare</literal> para declarar la codificación de un fichero fuente. Además,
todo lo que no sea código de PHP no puede preceder a la declaración del espacio de nombres, incluyendo espacios en blanco extra:
<example>
<title>Declarar un único espacio de nombres</title>
<programlisting role="php">
<![CDATA[
<html>
<?php
namespace MiProyecto; // error fatal - el espacio de nombres debe ser la primera sentencia del script
?>
]]>
</programlisting>
</example>
</para>
<para>
También, a diferencia de otras construcciones de PHP, se puede definir el mismo espacio de nombres
en varios ficheros, permitiendo la separación del contenido de un espacio de nombres a través del sistema de ficheros.
</para>
</sect1>
<sect1 xml:id="language.namespaces.nested">
<title>Declarar subespacios de nombres</title>
<?phpdoc print-version-for="namespaces"?>
<para>
Al igual que los directorios y ficheros, los espacios de nombres de PHP también tienen la capacidad
de especificar una jerarquía de nombres de espacios de nombres. Así, un nombre de un espacio de nombres
se puede definir con subniveles:
<example>
<title>Declarar un único espacio de nombres con jerarquía</title>
<programlisting role="php">
<![CDATA[
<?php
namespace MiProyecto\Sub\Nivel;
const CONECTAR_OK = 1;
class Conexión { /* ... */ }
function conectar() { /* ... */ }
?>
]]>
</programlisting>
</example>
El ejemplo de arriba crea la constante <literal>MiProyecto\Sub\Nivel\CONECTAR_OK</literal>,
la clase <literal>MiProyecto\Sub\Nivel\Conexión</literal> y la función
<literal>MiProyecto\Sub\Nivel\conectar</literal>.
</para>
</sect1>
<sect1 xml:id="language.namespaces.definitionmultiple">
<title>Definir varios espacios de nombres en un mismo fichero</title>
<?phpdoc print-version-for="namespaces"?>
<para>
También se pueden declarar varios espacios de nombres en un mismo fichero. Se permiten
dos tipos de sintaxis.
</para>
<para>
<example>
<title>Declarar varios espacios de nombres, sintaxis de combinación simple</title>
<programlisting role="php">
<![CDATA[
<?php
namespace MiProyecto;
const CONECTAR_OK = 1;
class Conexión { /* ... */ }
function conectar() { /* ... */ }
namespace OtroProyecto;
const CONECTAR_OK = 1;
class Conexión { /* ... */ }
function conectar() { /* ... */ }
?>
]]>
</programlisting>
</example>
</para>
<para>
No se recomienda esta sintaxis para combinar espacios de nombres en un único fichero.
En su lugar, se recomienda emplear la sintaxis de llaves alternativa.
</para>
<para>
<example>
<title>Declarar varios espacios de nombres, sintaxis de llaves</title>
<programlisting role="php">
<![CDATA[
<?php
namespace MiProyecto {
const CONECTAR_OK = 1;
class Conexión { /* ... */ }
function conectar() { /* ... */ }
}
namespace OtroProyecto {
const CONECTAR_OK = 1;
class Conexión { /* ... */ }
function conectar() { /* ... */ }
}
?>
]]>
</programlisting>
</example>
</para>
<para>
Se desaconseja completamente, como práctica de código, la combinación de varios espacios de nombres en
un mismo fichero. El caso de uso principal es combinar varios scripts de PHP en el mismo
fichero.
</para>
<para>
Combinar código global que no es de espacio de nombres con código que sí lo es, sólo está
soportado mediante la sintaxis de llaves. El código global debería estar
encerrado en una declaración de espacio de nombres sin nombre de espacio de nombres:
<example>
<title>Declarar múltiples espacios de nombres y código que no es de espacio de nombres</title>
<programlisting role="php">
<![CDATA[
<?php
namespace MiProyecto {
const CONECTAR_OK = 1;
class Conexión { /* ... */ }
function conectar() { /* ... */ }
}
namespace { // código global
session_start();
$a = MiProyecto\conectar();
echo MiProyecto\Conexión::iniciar();
}
?>
]]>
</programlisting>
</example>
</para>
<para>
No puede existir código de PHP fuera de las llaves del espacio de nombres, excepto para
una sentencia de apertura 'declare'.
<example>
<title>Declarar varios espacios de nombres y código que no es de espacio de nombres</title>
<programlisting role="php">
<![CDATA[
<?php
declare(encoding='UTF-8');
namespace MiProyecto {
const CONECTAR_OK = 1;
class Conexión { /* ... */ }
function conectar() { /* ... */ }
}
namespace { // código global
session_start();
$a = MiProyecto\conectar();
echo MiProyecto\Conexión::iniciar();
}
?>
]]>
</programlisting>
</example>
</para>
</sect1>
<sect1 xml:id="language.namespaces.basics">
<title>Uso de los espacios de nombres: lo básico</title>
<?phpdoc print-version-for="namespaces"?>
<para>
Antes de hablar del uso de los espacios de nombres es importante entender cómo sabe
PHP qué elemento del código del espacio de nombres se requiere. Se puede hacer una simple analogía
entre los espacios de nombres de PHP y el sistema de ficheros. Existen tres maneras de acceder a un
fichero en el sistema de ficheros:
<orderedlist>
<listitem>
<simpara>
Nombre de fichero relativo como <literal>foo.txt</literal>. Se resuelve con
<literal>directorio_actual/foo.txt</literal> donde directorio_actual es el
directorio actualmente ocupado. Así, si el directorio actual es
<literal>/home/foo</literal>, el nombre se resuelve con <literal>/home/foo/foo.txt</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Nombre de ruta relativa como <literal>subdirectorio/foo.txt</literal>. Se resuelve
con <literal>directorioactual/subdirectorio/foo.txt</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Nombre de ruta absoluta como <literal>/main/foo.txt</literal>. Se resuelve
con <literal>/main/foo.txt</literal>.
</simpara>
</listitem>
</orderedlist>
Se puede aplicar el mismo principio a los elementos del espacio de nombres de PHP.
Por ejemplo, se puede hacer referencia a un nombre de una clase de tres maneras:
<orderedlist>
<listitem>
<simpara>
Nombre no cualificado, o nombre de clase sin prefijo como
<literal>$a = new foo();</literal> o
<literal>foo::método_estático();</literal>. Si el espacio de nombres actual es
<literal>espacio_de_nombres_actual</literal>, esto se resuelve con
<literal>espacio_de_nombres_actual\foo</literal>. Si
el código es global, es decir, no es de espacio de nombres, esto se resuelve con <literal>foo</literal>.
</simpara>
<simpara>
Una advertencia: los nombres no cualificados para funciones y constantes se
resolverán con funciones y constantes globales si la función o la constante del espacio de nombres
no está definida. Véase <link linkend="language.namespaces.fallback">Utilizar espacios de nombres:
una alternativa a funciones/constantes globales</link> para más detalles.
</simpara>
</listitem>
<listitem>
<simpara>
Nombre cualificado, o un nombre de clase con prefijo como
<literal>$a = new subespacio_de_nombres\foo();</literal> o
<literal>subespacio_de_nombres\foo::método_estático();</literal>. Si el espacio de nombres actual es
<literal>espacio_de_nombres_actual</literal>, esto se resuelve con
<literal>espacio_de_nombres_actual\subespacio_de_nombres\foo</literal>. Si el código es global,
es decir, no es de espacio de nombres, esto se resuelve con <literal>subespacio_de_nombres\foo</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Nombre completamente cualificado, o un nombre con prefijo con el operador de prefijo global como
<literal>$a = new \espacio_de_nombres_actual\foo();</literal> o
<literal>\espacio_de_nombres_actual\foo::método_estático();</literal>. Esto siempre se resuelve
con nombre literal especificado en el código, <literal>espacio_de_nombres_actual\foo</literal>.
</simpara>
</listitem>
</orderedlist>
</para>
<para>
Un ejemplo de los tres tipos de sintaxis en código real:
<informalexample>
<simpara>fichero1.php</simpara>
<programlisting role="php">
<![CDATA[
<?php
namespace Foo\Bar\subespacio_de_nombres;
const FOO = 1;
function foo() {}
class foo
{
static function método_estático() {}
}
?>
]]>
</programlisting>
<simpara>fichero2.php</simpara>
<programlisting role="php">
<![CDATA[
<?php
namespace Foo\Bar;
include 'fichero1.php';
const FOO = 2;
function foo() {}
class foo
{
static function método_estático() {}
}
/* Nombre no cualificado */
foo(); // se resuelve con la función Foo\Bar\foo
foo::método_estático(); // se resuelve con la clase Foo\Bar\foo, método método_estático
echo FOO; // se resuelve con la constante Foo\Bar\FOO
/* Nombre cualificado */
subespacio_de_nombres\foo(); // se resuelve con la función Foo\Bar\subespacio_de_nombres\foo
subespacio_de_nombres\foo::método_estático(); // se resuelve con la clase Foo\Bar\subespacio_de_nombres\foo,
// método método_estático
echo subespacio_de_nombres\FOO; // se resuelve con la constante Foo\Bar\subespacio_de_nombres\FOO
/* Nombre conmpletamente cualificado */
\Foo\Bar\foo(); // se resuelve con la función Foo\Bar\foo
\Foo\Bar\foo::método_estático(); // se resuelve con la clase Foo\Bar\foo, método método_estático
echo \Foo\Bar\FOO; // se resuelve con la constante Foo\Bar\FOO
?>
]]>
</programlisting>
</informalexample>
</para>
<para>
Observe que para acceder a cualquier clase,
función o constante globales, se puede utilizar un nombre completamente cualificado, como
<function>\strlen</function> o <classname>\Exception</classname> o
\<constant>INI_ALL</constant>.
<example>
<title>Acceder a clases, funciones y constantes globales desde un espacio de nombres</title>
<programlisting role="php">
<![CDATA[
<?php
namespace Foo;
function strlen() {}
const INI_ALL = 3;
class Exception {}
$a = \strlen('hola'); // llama a la función global strlen
$b = \INI_ALL; // accede a la constante global INI_ALL
$c = new \Exception('error'); // instancia a la clase global Exception
?>
]]>
</programlisting>
</example>
</para>
</sect1>
<sect1 xml:id="language.namespaces.dynamic">
<title>Espacios de nombres y características dinámicas del lenguaje</title>
<?phpdoc print-version-for="namespaces"?>
<para>
La implementación de PHP de los espacios de nombres está influenciada por su naturaleza dinámica como
lenguaje de programación. Así, para convertir código como el del siguiente ejemplo en código de espacios de nombres:
<example>
<title>Acceder dinámicamente a elementos</title>
<simpara>ejemplo1.php:</simpara>
<programlisting role="php">
<![CDATA[
<?php
class nombre_clase
{
function __construct()
{
echo __METHOD__,"\n";
}
}
function nombre_func()
{
echo __FUNCTION__,"\n";
}
const nombre_const = "global";
$a = 'nombre_clase';
$obj = new $a; // imprime nombre_clase::__construct
$b = 'nombre_func';
$b(); // imprime nombre_func
echo constant('nombre_const'), "\n"; // imprime global
?>
]]>
</programlisting>
</example>
se debe emplear el nombre completamente cualificado (nombre de clase con prefijo de espacio de nombres).
Observe que, debido a que no hay diferencia entre un nombre cualificado y uno completamente cualificado
dentro de un nombre de clase, función, o constante dinámicas, no es necesario
la barra invertida inicial.
<example>
<title>Acceder dinámicamente a elementos de un espacio de nombres</title>
<programlisting role="php">
<![CDATA[
<?php
namespace nombre_espacio_de_nombres;
class nombre_clase
{
function __construct()
{
echo __METHOD__,"\n";
}
}
function nombre_func()
{
echo __FUNCTION__,"\n";
}
const nombre_const = "de espacio de nombres";
/* observe que si se emplean comillas dobles, se debe usar "\\nombre_espacio_de_nombres\\nombre_clase" */
$a = '\nombre_espacio_de_nombres\nombre_clase';
$obj = new $a; // imprime nombre_espacio_de_nombres\nombre_clase::__construct
$a = 'nombre_espacio_de_nombres\nombre_clase';
$obj = new $a; // también imprime nombre_espacio_de_nombres\nombre_clase::__construct
$b = 'nombre_espacio_de_nombres\nombre_func';
$b(); // imprime nombre_espacio_de_nombres\nombre_func
$b = '\nombre_espacio_de_nombres\nombre_func';
$b(); // también imprime nombre_espacio_de_nombres\nombre_func
echo constant('\nombre_espacio_de_nombres\nombre_const'), "\n"; // imprime de espacio de nombres
echo constant('nombre_espacio_de_nombres\nombre_const'), "\n"; // también imprime de espacio de nombres
?>
]]>
</programlisting>
</example>
</para>
<para>
Asegúrese de leer la <link linkend="language.namespaces.faq.quote">nota sobre
escapar nombres de espacios de nombres en cadenas</link>.
</para>
</sect1>
<sect1 xml:id="language.namespaces.nsconstants">
<title>La palabra reservada namespace y la constante __NAMESPACE__</title>
<?phpdoc print-version-for="namespaces"?>
<para>
PHP admite dos formas de acceder de manera abstracta a elementos dentro del espacio de nombres actual:
la constante mágica <constant>__NAMESPACE__</constant>, y la palabra reservada
<literal>namespace</literal>.
</para>
<para>
El valor de <constant>__NAMESPACE__</constant> es una cadena que contiene el nombre del espacio de
nombres actual. En código global, que no es de espacio de nombres, contiene una cadena vacía.
<example>
<title>Ejemplo de __NAMESPACE__, código de espacio de nombres</title>
<programlisting role="php">
<![CDATA[
<?php
namespace MiProyecto;
echo '"', __NAMESPACE__, '"'; // imprime "MiProyecto"
?>
]]>
</programlisting>
</example>
<example>
<title>Ejemplo de __NAMESPACE__, código global</title>
<programlisting role="php">
<![CDATA[
<?php
echo '"', __NAMESPACE__, '"'; // imprime ""
?>
]]>
</programlisting>
</example>
La constante <constant>__NAMESPACE__</constant> es útil para construir nombres
dinámicamente, por ejemplo:
<example>
<title>Empleo de __NAMESPACE__ para la construcción dinámica de nombres</title>
<programlisting role="php">
<![CDATA[
<?php
namespace MiProyecto;
function obtener($nombre_clase)
{
$a = __NAMESPACE__ . '\\' . $nombre_clase;
return new $a;
}
?>
]]>
</programlisting>
</example>
</para>
<para>
La palabra reservada <literal>namespace</literal> se puede utilizar para solicitar explícitamente
un elemento del espacio de nombres o subespacio de nombres actual. Es el equivalente del espacio
de nombres para el operador <literal>self</literal> de las clases.
<example>
<title>El operador namespace, dentro de un espacio de nombres</title>
<programlisting role="php">
<![CDATA[
<?php
namespace MiProyecto;
use blah\blah as mío; // véase "Uso de los espacios de nombres: Apodar/Importar"
blah\mío(); // llama a la función MiProyecto\blah\mío()
namespace\blah\mío(); // llama a la función MiProyecto\blah\mío()
namespace\func(); // llama a la función MiProyecto\func()
namespace\sub\func(); // llama a la función MiProyecto\sub\func()
namespace\nombrec::método(); // llama al método estático "método" de la clase MiProyecto\nombrec
$a = new namespace\sub\nombrec(); // instancia un objeto de la clase MiProyecto\sub\nombrec
$b = namespace\CONSTANTE; // asigna el valor de la constante MiProyecto\CONSTANTE a $b
?>
]]>
</programlisting>
</example>
<example>
<title>El operador namespace, en código global</title>
<programlisting role="php">
<![CDATA[
<?php
namespace\func(); // llama a la función func()
namespace\sub\func(); // llama a la función sub\func()
namespace\nombrec::método(); // llama al método estático "método" de la clase nombrec
$a = new namespace\sub\nombrec(); // instancia un objeto de la clase sub\nombrec
$b = namespace\CONSTANTE; // asigna el valor de la constante CONSTANTE a $b
?>
]]>
</programlisting>
</example>
</para>
</sect1>
<sect1 xml:id="language.namespaces.importing">
<title>Uso de los espacios de nombres: apodar/importar</title>
<?phpdoc print-version-for="namespaces"?>
<para>
La capacidad de referirse a un nombre completamente cualificado externo con un alias, o importar,
es una característca importante de los espacios de nombres. Esto es similar a la capacidad
de los sistemas de ficheros basados en Unix de crear enlaces simbólicos a un fichero o directorio.
</para>
<para>
Todas las versiones de PHP que tienen soporte para espacios de nombres admiten tres tipos de alias
o importación: apodar un nombre de clase, apodar un nombre de interfaz, y
apodar un nombre de espacio de nombres. PHP 5.6+ también permite apodar o importar
nombres de funciones y constantes.
</para>
<para>
En PHP, la acción de apodar se lleva a cabo con el operador <literal>use</literal>.
Aquí hay un ejemplo que muestra los cinco tipos de importación:
<example>
<title>Importar/apodar con el operador use</title>
<programlisting role="php">
<![CDATA[
<?php
namespace foo;
use Mi\Completo\NombreDeClase as Otra;
// esto es lo mismo que utilizar Mi\Completo\NombreEN as NombreEN
use Mi\Completo\NombreEN;
// importar una clase global
use ArrayObject;
// importar una función (PHP 5.6+)
use function Mi\Completo\nombreDeFunción;
// apodar una función (PHP 5.6+)
use function Mi\Completo\nombreDeFunción as func;
// importar una constante (PHP 5.6+)
use const Mi\Completa\CONSTANTE;
$obj = new namespace\Otra; // instancia un objeto de la clase foo\Otra
$obj = new Otra; // instancia un objeto de la clase class Mi\Completo\NombreDeClase
NombreEN\suben\func(); // llama a la función Mi\Completo\NombreEN\subes\func
$a = new ArrayObject(array(1)); // instancia un objeto de la clase ArrayObject
// sin el "use ArrayObject" instanciaríamos un objeto de la clase foo\ArrayObject
func(); // llama a la función Mi\Completo\nombreDeFunción
echo CONSTANT; // imprime el valor de Mi\Completa\CONSTANTE;
?>
]]>
</programlisting>
</example>
Observe que para los nombres de espacios de nombres (nombres de espacios de nombres completamente
cualificados que contienen el separador de espacios de nombres, como <literal>Foo\Bar</literal>, en
oposición a los nombres globales que no lo contienen, como <literal>FooBar</literal>), no es necesaria
y no está recomendada la barra invertida inicial, ya que los nombres importados
deben ser completamente cualificados, por lo que no son procesados en relación al espacio de nombres actual.
</para>
<para>
PHP admite además un atajo para poner varias sentencias use
en la misma línea
<example>
<title>Importar/apodar con el operador use, varias sentencias use combinadas</title>
<programlisting role="php">
<![CDATA[
<?php
use Mi\Completo\NombreDeClase as Otra, Mi\Completo\NombreEN;
$obj = new Otra; // instancia un objeto de la clase Mi\Completo\NombreDeClase
NombreEN\suben\func(); // llama a la función Mi\Completo\NombreEN\suben\func
?>
]]>
</programlisting>
</example>
</para>
<para>
La importación se realiza durante la compilación, por lo que no afecta a los nombres de clases,
funciones o constantes.
<example>
<title>La importación y los nombres dinámicos</title>
<programlisting role="php">
<![CDATA[
<?php
use Mi\Completo\NombreDeClase as Otra, Mi\Completo\NombreEN;
$obj = new Otra; // instancia un objeto de la clase Mi\Completo\NombreDeClase
$a = 'Otra';
$obj = new $a; // instancia un objeto de la clase Otra
?>
]]>
</programlisting>
</example>
</para>
<para>
Además, la importación sólo afecta a los nombres cualificados y no cualificados. Los nombres
completamente cualificados son absolutos, por lo que no se ven afectados por la importación.
<example>
<title>La importación y los nombres completamente cualificados</title>
<programlisting role="php">
<![CDATA[
<?php
use Mi\Completo\NombreDeClase as Otra, Mi\Completo\NombreEN;
$obj = new Otra; // instancia un objeto de la clase Mi\Completo\NombreDeClase
$obj = new \Otra; // instancia un objeto de la clase Otra
$obj = new Otra\cosa; // instancia un objeto de la clase Mi\Completo\NombreDeClase\cosa
$obj = new \Otra\cosa; // instancia un objeto de la clase Otra\cosa
?>
]]>
</programlisting>
</example>
</para>
<sect2 xml:id="language.namespaces.importing.scope">
<title>Reglas de ámbito para la importación</title>
<para>
La palabra reservada <literal>use</literal> debe ser declarada en el
ámbito exterior de un fichero (el ámbito global) o dentro de declaraciones
de espacios de nombres. Esto es así debido a que la importación se realiza durante
la compilación y no durante la ejecución, por lo que no puede ser utilizada en un ámbito de bloque. El siguiente
ejemplo muestra un uso ilegal de la palabra reservada
<literal>use</literal>:
</para>
<para>
<example>
<title>Regla de importación ilegal</title>
<programlisting role="php">
<![CDATA[
<?php
namespace Idiomas;
function aGroenlandés
{
use Idiomas\Danés;
// ...
}
?>
]]>
</programlisting>
</example>
</para>
<note>
<para>
Las reglas de importación tiene una base por fichero, lo que significa que los ficheros incluidos
<emphasis>NO</emphasis> heredarán las reglas de importación del padre.
</para>
</note>
</sect2>
<sect2 xml:id="language.namespaces.importing.group">
<title>Declaraciones de <literal>use</literal> en grupo</title>
<para>
Desde PHP 7.0 en adelante, las clases, funciones y constantes importadas desde
el mismo &namespace; pueden ser agrupadas en una única sentencia
&use.namespace;.
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
// Código anterir a PHP 7
use un\espacioDeNombres\ClaseA;
use un\espacioDeNombres\ClaseB;
use un\espacioDeNombres\ClaseC as C;
use function un\espacioDeNombres\fn_a;
use function un\espacioDeNombres\fn_b;
use function un\espacioDeNombres\fn_c;
use const un\espacioDeNombres\ConstA;
use const un\espacioDeNombres\ConstB;
use const un\espacioDeNombres\ConstC;
// Código de PHP 7+
use un\espacioDeNombres\{ClaseA, ClaseB, ClaseC as C};
use function un\espacioDeNombres\{fn_a, fn_b, fn_c};
use const un\espacioDeNombres\{ConstA, ConstB, ConstC};
]]>
</programlisting>
</informalexample>
</sect2>
</sect1>
<sect1 xml:id="language.namespaces.global">
<title>Espacio global</title>
<?phpdoc print-version-for="namespaces"?>
<para>
Sin ninguna definición de espacios de nombres, todas las definiciones de clases y funciones son
colocadas en el espacio global, como si lo estuvieran antes de que PHP soportara los
espacios de nombres. Prefijar un nombre con <literal>\</literal> especificará que
el nombre es requerido desde el espacio global incluso en el contexto del
espacio de nombres.
<example>
<title>Usar la especificación de espacio global</title>
<programlisting role="php">
<![CDATA[
<?php
namespace A\B\C;
/* Esta función es A\B\C\fopen */
function fopen() {
/* ... */
$f = \fopen(...); // llamar a fopen global
return $f;
}
?>
]]>
</programlisting>
</example>
</para>
</sect1>
<sect1 xml:id="language.namespaces.fallback">
<title>Utilizar espacios de nombres: una alternativa a funciones/constantes globales</title>
<?phpdoc print-version-for="namespaces"?>
<para>
Dentro de un espacio de nombres, cuando PHP se encuentra con nombre no cualificado en un contexto de
nombre de clase, función o constante, lo resuelve con diferentes prioridades. Los nombres de clases
siempre se resuelven con el nombre de espacio de nombres actual. Así, para acceder a clases de
usuario internas o que no son de espacio de nombres, se debe referir a ellas con su nombre completamente cualificado:
<example>
<title>Acceder a clases globales dentro de un espacio de nombres</title>
<programlisting role="php">
<![CDATA[
<?php
namespace A\B\C;
class Exception extends \Exception {}
$a = new Exception('hola'); // $a es un objeto de la clase A\B\C\Exception
$b = new \Exception('hola'); // $b es un objeto de la clase Exception
$c = new ArrayObject; // error fatal, no se encontró la clase A\B\C\ArrayObject
?>
]]>
</programlisting>
</example>
</para>
<para>
Para funciones y constantes, PHP recurrirá a funciones y constantes globales
si no existe una función o constante en el espacio de nombres.
<example>
<title>Recurrir a funciones/constantes globales dentro de un espacio de nombres</title>
<programlisting role="php">
<![CDATA[
<?php
namespace A\B\C;
const E_ERROR = 45;
function strlen($str)
{
return \strlen($str) - 1;
}
echo E_ERROR, "\n"; // imprime "45"
echo INI_ALL, "\n"; // imprime "7" - recurre a INI_ALL global
echo strlen('hola'), "\n"; // imprime "3"
if (is_array('hola')) { // imprime "no es un array"
echo "es una array\n";
} else {
echo "no es un array\n";
}
?>
]]>
</programlisting>
</example>
</para>
</sect1>
<sect1 xml:id="language.namespaces.rules">
<title>Reglas de resolución de nombres</title>
<?phpdoc print-version-for="namespaces"?>
<para>
A continuación se exponen unas definiciones importantes para estas reglas de resolución:
<variablelist>
<title>Definiciones de nombres de espacios de nombres</title>
<varlistentry>
<term>Nombre no cualificado</term>
<listitem>
<para>
Es un identificador sin un separador de espacios de nombres, como <literal>Foo</literal>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Nombre cualificado</term>
<listitem>
<para>
Es un identificador con un separador de espacios de nombres, como <literal>Foo\Bar</literal>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Nombre completamente cualificado</term>
<listitem>
<para>
Es un identificador con un separador de espacios de nombres que comienza con un separador
de espacios de nombres, como <literal>\Foo\Bar</literal>. <literal>namespace\Foo</literal>
también es un nombre completamente cualificado.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
Los nombres se resuelven siguiendo estas reglas de resolución:
<orderedlist>
<listitem>
<simpara>
Las llamadas a clases, funciones o constantes completamente cualificadas se resuelven durante la
compilación. Por ejemplo <literal>new \A\B</literal> se resuelve con la clase <literal>A\B</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Todos los nombres no cualificados y cualificados (no los completamente cualificados) se traducen
durante la compilación según las reglas de
importación actuales. Por ejemplo, si el espacio de nombres <literal>A\B\C</literal> se importa como
<literal>C</literal>, una llamada a
<literal>C\D\e()</literal> se traduce como <literal>A\B\C\D\e()</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Dentro de un espacio de nombres, todos los nombres cualificados no traducidos según la reglas
de importación llevan antepuesto el espacio de nombres actual. Por ejemplo, si una llamada
a <literal>C\D\e()</literal> se lleva a cabo dentro del espacio de nombres <literal>A\B</literal>,
se traduce como <literal>A\B\C\D\e()</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Los nombres de clases no cualificados se traducen durante la compilación según las reglas de
importación actuales (el nombre completo sustituido por el nombre abreviado importado). Por ejemplo,
si el espacio de nombres <literal>A\B\C</literal> se importa como C, <literal>new C()</literal> se
traduce como <literal>new A\B\C()</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Dentro de un espacio de nombres (digamos A\B), las llamadas a funciones no cualificadas se resuelven
durante la ejecución. Así se resuelve una llamada a la función
<literal>foo()</literal>:
</simpara>
<orderedlist>
<listitem>
<simpara>
Se busca una función del espacio de nombres actual:
<literal>A\B\foo()</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Se intenta encontrar y llamar a la función <emphasis>global</emphasis>
<literal>foo()</literal>.
</simpara>
</listitem>
</orderedlist>
</listitem>
<listitem>
<simpara>
Dentro de un espacio de nombres (digamos <literal>A\B</literal>), las llamadas a nombres de clases
no cualificados o cualificados (no los completamente cualificados) se resuelven durante la
ejecución. Así se resuelve una llamada a
<literal>new C()</literal> o a <literal>new D\E()</literal>.
Para <literal> new C()</literal>:
</simpara>
<orderedlist>
<listitem>
<simpara>
Se busca una clase del espacio de nombres actual:
<literal>A\B\C</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Se intenta autocargar <literal>A\B\C</literal>.
</simpara>
</listitem>
</orderedlist>
<simpara>
Para <literal> new D\E()</literal>:
</simpara>
<orderedlist>
<listitem>
<simpara>
Se busca una clase anteponiendo el espacio de nombres actual:
<literal>A\B\D\E</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Se intenta autocargar <literal>A\B\D\E</literal>.
</simpara>
</listitem>
</orderedlist>
<simpara>
Para referirse a cualquier clase global en el espacio de nombres global,
se debe emplear su nombre completamente cualificado <literal>new \C()</literal>.
</simpara>
</listitem>
</orderedlist>
</para>
<example>
<title>Las resoluciones de nombres ilustradas</title>
<programlisting role="php">
<![CDATA[
<?php
namespace A;
use B\D, C\E as F;
// llamadas a funciones
foo(); // primero se intenta llamar a "foo" definida en el espacio de nombres "A"
// después se llama a la función global "foo"
\foo(); // se llama a la función "foo" definidia en el ámbito global
mi\foo(); // se llama a la función "foo" definida en el espacio de nombres "A\mi"
F(); // primero se intenta llamar a "F" definida en el espacio de nombres "A"
// después se llama a la función global "F"
// referecias a clases
new B(); // crea un objeto de la clase "B" definida en el espacio de nombres "A"
// si no se encuentra, se intenta autocargar la clase "A\B"
new D(); // usando las reglas de importación, se crea un objeto de la clase "D" definida en el espacio de nombres "B"
// si no se encuentra, se intenta autocargar la clase "B\D"
new F(); // usando las reglas de importación, se crea un objeto de la clase "E" definida en el espacio de nombres "C"
// si no se encuentra, se intenta autocargar la clase "C\E"
new \B(); // crea un objeto de la clase "B" definida en el ámbito global
// si no se encuentra, se intenta autocargar la clase "B"
new \D(); // crea un objeto de la clase "D" definida en el ámbito global
// si no se encuentra, se intenta autocargar la clase "D"
new \F(); // crea un objeto de la clase "F" definida en el ámbito global
// si no se encuentra, se intenta autocargar la clase "F"
// métodos estáticos y funciones de un espacio de nombres desde otro espacio de nombres
B\foo(); // se llama a la función "foo" desde el espacio de nombres "A\B"
B::foo(); // se llama al método "foo" de la clase "B" definidia en el espacio de nombres "A"
// si no se encuentra la clase "A\B", se intenta autocargar la clase "A\B"
D::foo(); // usando las reglas de importación, se llama al método "foo" de la clase "D" definida en el espacio de nombres "B"
// si no se encuentra la clase "B\D", se intenta autocargar la clase "B\D"
\B\foo(); // se llama a la función "foo" desde el espacio de nombres "B"
\B::foo(); // se llama al método "foo" de la clase "B" desde el ámbito global
// si no es encuentra la clase "B", se intenta autocargar la clase "B"
// métodos estáticos yfunciones de un espacio de nombres del espacio de nombres actual
A\B::foo(); // se llama al método "foo" de la clase "B" desde el espacio de nombres "A\A"
// si no se encuentra la clase "A\A\B", se intenta autocargar la clase "A\A\B"
\A\B::foo(); // se llama al método "foo" de la clase "B" desde el espacio de nombres "A"
// si no se encuentra la clase "A\B", se intenta autocargar la clase "A\B"
?>
]]>
</programlisting>
</example>
</sect1>
<sect1 xml:id="language.namespaces.faq">
<title>P+F: cosas que es necesario saber sobre los espacios de nombres</title>
<?phpdoc print-version-for="namespaces"?>
<para>
Esta sección está dividida en dos subsecciones: preguntas comunes, y algunas especificaciones de
implementación que son útiles para comprender completamente los espacios de nombres.
</para>
<para>
Primero, las preguntas comunes.
<orderedlist>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.shouldicare">Si no utilizo espacios de nombres, ¿debería
preocuparme por algo de esto?</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.globalclass">¿Cómo uso clases internas o
globales en un espacio de nombres?</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.innamespace">¿Cómo uso clases, funciones
o constantes de espacios de nombres en su propio espacio de nombres?</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.full">
¿Cómo se resuelve un nombre como <literal>\mi\nombre</literal> o
<literal>\nombre</literal>?
</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.qualified">¿Cómo se resuelve un nombre como
<literal>mi\nombre</literal>?</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.shortname1">¿Cómo se resuelve un nombre de clase no
cualificado como <literal>nombre</literal>?</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.shortname2">¿Cómo se resuelve un
nombre de función o de constante no cualifcado
como <literal>nombre</literal>?</link>
</simpara>
</listitem>
</orderedlist>
</para>
<para>
Existen unos pocos detalles de las implementaciones de espacios de nombres
que son útiles para enterderlos.
<orderedlist>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.conflict">Importar nombres no entra en conflicto con
las clases definidas en el mismo fichero.</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.nested">Los espacios de nombres anidados no están
permitidos.</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.nofuncconstantuse">Antes de PHP 5.6, ni las funciones ni
las constantes se pueden importar mediante la sentencia
<literal>use</literal>.</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.quote">Los nombres de espacios de nombres dinámicos
(identificadores entre comillas) deberían escaparse con una barra invertida.</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.constants">Las constantes no definidas aludidas
usando cualquier barra invertida terminan en un error fatal</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.builtinconst">No se pueden sobrescribir las
constantes especiales NULL, TRUE, FALSE, ZEND_THREAD_SAFE o ZEND_DEBUG_BUILD</link>
</simpara>
</listitem>
</orderedlist>
</para>
<sect2 xml:id="language.namespaces.faq.shouldicare">
<title>Si no utilizo espacios de nombres, ¿debería preocuparme por algo de esto?</title>
<para>
No. Los espacios de nombres no afectan a ningún código existente de ninguna manera, o a ningún
código todavía por escribir que no contenga espacios de nombres. Se puede
escribir este código si se desea:
</para>
<para>
<example>
<title>Acceder a clases globales fuera de un espacio de nombres</title>
<programlisting role="php">
<![CDATA[
<?php
$a = new \stdClass;
?>
]]>
</programlisting>
</example>
</para>
<para>
Esto es funcionalmente equivalente a:
</para>
<para>
<example>
<title>Acceder a clases globales fuera de un espacio de nombres</title>
<programlisting role="php">
<![CDATA[
<?php
$a = new stdClass;
?>
]]>
</programlisting>
</example>
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.globalclass">
<title>¿Cómo uso clases internas o globales en un espacio de nombres?</title>
<para>
<example>
<title>Acceder a clases internas en espacios de nombres</title>
<programlisting role="php">
<![CDATA[
<?php
namespace foo;
$a = new \stdClass;
function probar(\ArrayObject $ejemploalusiónatipo = null) {}
$a = \DirectoryIterator::CURRENT_AS_FILEINFO;
// extender una clase interna o global
class MiExcepción extends \Exception {}
?>
]]>
</programlisting>
</example>
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.innamespace">
<title>
¿Cómo uso clases, funciones o constantes de espacios de nombres en su propio
espacio de nombres?
</title>
<para>
<example>
<title>Acceder a clases, funciones o constantes internas en un espacio de nombres</title>
<programlisting role="php">
<![CDATA[
<?php
namespace foo;
class MiClase {}
// usar una clase desde el espacio de nombres actual como una declaración de tipo
function probar(MiClase $ejemploalusiónatipo = null) {}
// otra manera de usar una clase desde el espacio de nombres actual una declaración de tipo
function probar(\foo\MiClase $ejemploalusiónatipo = null) {}
// extender una clase desde el espacio de nombres actual
class Extendida extends MiClase {}
// acceder a una función global
$a = \funcglobal();
// acceder a una constante global
$b = \INI_ALL;
?>
]]>
</programlisting>
</example>
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.full">
<title>
¿Cómo se resuelve un nombre como <literal>\mi\nombre</literal> o
<literal>\nombre</literal>?
</title>
<para>
Los nombres que comienzan con una <literal>\</literal> siempre se resuelven a aquello a lo que
se asemejan, así <literal>\mi\nombre</literal> de hecho es <literal>mi\nombre</literal>,
y <literal>\Exception</literal> es <literal>Exception</literal>.
<example>
<title>Nombres completamente cualificados</title>
<programlisting role="php">
<![CDATA[
<?php
namespace foo;
$a = new \mi\nombre(); // instancia a la clase "mi\nombre"
echo \strlen('hola'); // llama a la función "strlen"
$a = \INI_ALL; // $a está establecida al valor de la constante "INI_ALL"
?>
]]>
</programlisting>
</example>
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.qualified">
<title>¿Cómo se resuelve un nombre como <literal>mi\nombre</literal>?</title>
<para>
Los nombres que contienen una barra invertida pero no comienzan con una barra invertida como
<literal>mi\nombre</literal> pueden resolverse de dos formas diferentes.
</para>
<para>
Si hay
una sentencia de importación que apode a otro nombre como <literal>mi</literal>,
el alias de importación se aplica a <literal>mi</literal> en <literal>mi\nombre</literal>.
</para>
<para>
De lo contrario, al nombre del espacio de nombres actual se le antepone <literal>mi\nombre</literal>.
</para>
<para>
<example>
<title>Nombres cualificados</title>
<programlisting role="php">
<![CDATA[
<?php
namespace foo;
use blah\blah as foo;
$a = new mi\nombre(); // instancia a la clase "foo\mi\nombre"
foo\bar::nombre(); // llama a método estático "nombre" de la clase "blah\blah\bar"
mi\bar(); // llama a la función "foo\mi\bar"
$a = mi\BAR; // establece $a al valor de la constante "foo\mi\BAR"
?>
]]>
</programlisting>
</example>
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.shortname1">
<title>¿Cómo se resuelve un nombre de clase no cualificado como <literal>nombre</literal>?</title>
<para>
Los nombres de clases que no contienen una barra invertida como
<literal>nombre</literal> se pueden resolver de dos formas diferentes.
</para>
<para>
Si hay
una sentencia de importación que apode a otro nombre como <literal>nombre</literal>,
se aplica el alias de importación.
</para>
<para>
De lo contrario, al nombre del espacio de nombres actual se le antepone <literal>nombre</literal>.
</para>
<para>
<example>
<title>Nombres de clases no cualificados</title>
<programlisting role="php">
<![CDATA[
<?php
namespace foo;
use blah\blah as foo;
$a = new nombre(); // instancia a la clase "foo\nombre"
foo::nombre(); // llama al método estático "nombre" de la clase "blah\blah"
?>
]]>
</programlisting>
</example>
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.shortname2">
<title>
¿Cómo se resuelve un nombre de función o de constante no cualifcado
como <literal>nombre</literal>?
</title>
<para>
Los nombres de funciones o de constantes que no contienen una barra invertida como
<literal>nombre</literal> se pueden resolver de dos formas diferentes.
</para>
<para>
Primero, al nombre del espacio de nombres actual se le antepone <literal>nombre</literal>.
</para>
<para>
Finalmente, si el <literal>nombre</literal> de la constante o de la función no existe
en el espacio de nombres actual, se emplea un <literal>nombre</literal> de constante o función global,
si es que existe.
</para>
<para>
<example>
<title>Nombres de funciones o constantes no cualificados</title>
<programlisting role="php">
<![CDATA[
<?php
namespace foo;
use blah\blah as foo;
const FOO = 1;
function mi() {}
function foo() {}
function sort(&$a)
{
\sort($a); // invoca a la función global "sort"
$a = array_flip($a);
return $a;
}
mi(); // calls "foo\mi"
$a = strlen('hola'); // llama a la función global "strlen" ya que "foo\strlen" no existe
$array = array(1,3,2);
$b = sort($array); // llama a la función "foo\sort"
$c = foo(); // llama a la función "foo\foo" - la importación no se aplica
$a = FOO; // establece $a al valor de la constante "foo\FOO"; la importación no se aplica
$b = INI_ALL; // establece $b al valor de la constante "INI_ALL"
?>
]]>
</programlisting>
</example>
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.conflict">
<title>Importar nombres no entra en conflicto con las clases definidas en el mismo fichero.</title>
<para>
Están permitidas las siguientes combinaciones de scripts:
<informalexample>
<simpara>fichero1.php</simpara>
<programlisting role="php">
<![CDATA[
<?php
namespace mis\cosas;
class MiClase {}
?>
]]>
</programlisting>
<simpara>otro.php</simpara>
<programlisting role="php">
<![CDATA[
<?php
namespace otro;
class cosa {}
?>
]]>
</programlisting>
<simpara>fichero2.php</simpara>
<programlisting role="php">
<![CDATA[
<?php
namespace mis\cosas;
include 'fichero1.php';
include 'otro.php';
use otro\cosa as MiClase;
$a = new MiClase; // instancia a la clase "cosa" del espacio de nombres otro
?>
]]>
</programlisting>
</informalexample>
</para>
<para>
No existe conflicto entre nombres, aunque la clase <literal>MiClase</literal> exista
dentro del espacio de nombres <literal>mis\cosas</literal>, porque la definición de MiClase está
en otro fichero. Sin embargo, el siguiente ejemplo causa un error fatal por el conflicto entre nombres,
debido a que MiClase está definida en el mismo fichero que el de la sentencia use.
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
namespace mis\cosas;
use otro\cosa as MiClase;
class MiClase {} // error fatal: MiClase entra en conflicto con la sentencia de importación
$a = new MiClase;
?>
]]>
</programlisting>
</informalexample>
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.nested">
<title>Los espacios de nombres anidados no están permitidos.</title>
<para>
PHP no permite los espacios de nombres anidados
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
namespace mis\cosas {
namespace anidado {
class foo {}
}
}
?>
]]>
</programlisting>
</informalexample>
Sin embargo, es fácil simular los espacios de nombres anidados de la siguiente manera:
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
namespace mis\cosas\anidado {
class foo {}
}
?>
]]>
</programlisting>
</informalexample>
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.nofuncconstantuse">
<title>Antes de PHP 5.6, ni las funciones ni las constantes se pueden importar mediante la sentencia
<literal>use</literal>.</title>
<para>
Ants de PHP 5.6, los únicos elementos que se ven afectados por la sentencia <literal>use</literal> son los
espacios de nombres y los nombres de clases. Para abreviar una constante o una función larga,
se ha de importar el espacio de nombres que la contiene:
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
namespace mío;
use nombre\en\ultra\largo;
$a = largo\CONSTANT;
largo\func();
?>
]]>
</programlisting>
</informalexample>
A partir de PHP 5.6, está permitido apodar o imortar nombres de funciones y de constantes.
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.quote">
<title>Los nombres de espacios de nombres dinámicos (identificadores entre comillas) deberían escaparse con una barra invertida.</title>
<para>
Es muy importante darse cuenta de que, debeido a que la barra invertida se usa como carácter de escape
dentro de cadenas, se deberían emplear dos barras inverticas cuando se utilicen dentro de cadenas. De lo contrario,
existe el riesgo de obtener consecuencias inesperadas:
<example>
<title>Peligros de usar nombres de espacios de nombres dentro de una cadena entre comillas dobles</title>
<programlisting role="php">
<![CDATA[
<?php
$a = "peligroso\nombre"; // ¡\n es una nueva línea dentro de las cadenas entre comillas dobles!
$obj = new $a;
$a = 'sin\peligro\alguno'; // aquí sin problemas.
$obj = new $a;
?>
]]>
</programlisting>
</example>
Dentro de una cadena entre comillas dobles, es más seguro usar la secuencia de escape de la barra
invertida, pero aún se recomienda como práctica escapar las barras invertidas en todas las cadenas.
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.constants">
<title>Las constantes no definidas a las que se hace referencia usando una barra invertida terminan con un error fatal</title>
<para>
Cualquier constante no definida que no sea cualificada, como <literal>FOO</literal>,
generará una aviso explicando que PHP asume que <literal>FOO</literal> es el valor
de la constante. Cualquier constante, cualificada o completamente cualificada, que contenga una
barra invertida producirá un error fatal si no se encuentra.
<example>
<title>Constantes no definidas</title>
<programlisting role="php">
<![CDATA[
<?php
namespace bar;
$a = FOO; // produce un aviso - constante no definida "FOO" se asume que es "FOO";
$a = \FOO; // error fatal, constante FOO del espacio de nombres no definida
$a = Bar\FOO; // error fatal, constante bar\Bar\FOO del espacio de nombres no definida
$a = \Bar\FOO; // error fatal, constante Bar\FOO del espacio de nombres no definida
?>
]]>
</programlisting>
</example>
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.builtinconst">
<title>No se pueden sobrescribir las constantes especiales NULL, TRUE, FALSE, ZEND_THREAD_SAFE o ZEND_DEBUG_BUILD</title>
<para>
Cualquier intento de definir una constante de espacio de nombres que sea una constante
especial interna, resultará en un error fatal:
<example>
<title>Constantes no definidas</title>
<programlisting role="php">
<![CDATA[
<?php
namespace bar;
const NULL = 0; // error fatal;
const true = 'estúpido'; // también error fatal;
// etc.
?>
]]>
</programlisting>
</example>
</para>
</sect2>
</sect1>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->