mirror of
https://github.com/php/doc-es.git
synced 2026-03-23 23:12:09 +01:00
1599 lines
52 KiB
XML
1599 lines
52 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- EN-Revision: 1651836ff309efd14a795eff44ee51455f66c7d3 Maintainer: PhilDaiguille Status: ready -->
|
|
<!-- Reviewed: no -->
|
|
<!-- CREDITS: DAnnebicque -->
|
|
<chapter xml:id="language.namespaces" xmlns="http://docbook.org/ns/docbook"
|
|
version="1.1">
|
|
<title>Los espacios de nombres</title>
|
|
|
|
<sect1 xml:id="language.namespaces.rationale">
|
|
<title>Introducción a los espacios de nombres</title>
|
|
<titleabbrev>Introducción</titleabbrev>
|
|
<?phpdoc print-version-for="namespaces"?>
|
|
<simpara>
|
|
¿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
|
|
<literal>foo.txt</literal> puede existir en ambos directorios
|
|
<literal>/home/greg</literal> y <literal>/home/other</literal>, pero que
|
|
las dos copias de <literal>foo.txt</literal> no pueden coexistir
|
|
en el mismo directorio. Además, para acceder al archivo <literal>foo.txt</literal>
|
|
desde fuera del directorio <literal>/home/greg</literal>, es necesario especificar
|
|
el nombre del directorio utilizando un separador de directorios, como
|
|
<literal>/home/greg/foo.txt</literal>. El mismo principio se aplica a los
|
|
espacios de nombres en el mundo de la programación.
|
|
</simpara>
|
|
|
|
<simpara>
|
|
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:
|
|
</simpara>
|
|
<para>
|
|
<orderedlist>
|
|
<listitem>
|
|
<simpara>
|
|
Colisiones de nombres entre el código que se crea, las clases, funciones
|
|
o constantes internas de PHP, o las de bibliotecas de terceros.
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
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.
|
|
</simpara>
|
|
</listitem>
|
|
</orderedlist>
|
|
</para>
|
|
<simpara>
|
|
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:
|
|
</simpara>
|
|
<example>
|
|
<title>Ejemplo de sintaxis de espacios de nombres</title>
|
|
<titleabbrev>Espacios de nombres</titleabbrev>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace mon\nom; // Ver la sección "Definición de espacios de nombres"
|
|
|
|
class MaClasse {}
|
|
function mafonction() {}
|
|
const MACONSTANTE = 1;
|
|
|
|
$a = new MaClasse;
|
|
$c = new \mon\nom\MaClasse; // Ver la sección "Espacio global"
|
|
|
|
$a = strlen('bonjour'); // Ver "Uso de espacios de nombres: retorno al espacio global
|
|
|
|
$d = namespace\MACONSTANTE; // Ver "El operador namespace y la constante __NAMESPACE__
|
|
|
|
$d = __NAMESPACE__ . '\MACONSTANTE';
|
|
echo constant($d); // Ver "Espacios de nombres y características dinámicas"
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
<note>
|
|
<simpara>
|
|
Los nombres de espacios de nombres no son sensibles a mayúsculas/minúsculas.
|
|
</simpara>
|
|
</note>
|
|
<note>
|
|
<para>
|
|
Los espacios de nombres <literal>PHP</literal>, así como los nombres compuestos
|
|
que comienzan con estos nombres (como <literal>PHP\Classes</literal>)
|
|
están reservados para el uso interno del lenguaje y no deben usarse
|
|
en el código del espacio de usuario.
|
|
</para>
|
|
</note>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="language.namespaces.definition">
|
|
<title>Definición de espacios de nombres</title>
|
|
<?phpdoc print-version-for="namespaces"?>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
Los espacios de nombres se declaran con la palabra clave <literal>namespace</literal>.
|
|
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 <xref linkend="control-structures.declare" />.
|
|
<example>
|
|
<title>Declaración de un espacio de nombres</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace MonProjet;
|
|
|
|
const CONNEXION_OK = 1;
|
|
class Connexion { /* ... */ }
|
|
function connecte() { /* ... */ }
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
<note>
|
|
<simpara>
|
|
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.
|
|
</simpara>
|
|
</note>
|
|
El único elemento autorizado antes de la declaración de espacio de nombres es la instrucción
|
|
<literal>declare</literal>, 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:
|
|
<example>
|
|
<title>Error de declaración de un espacio de nombres</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<html>
|
|
<?php
|
|
namespace MonProjet; // error fatal: el espacio de nombres debe ser el primer elemento del script
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
</sect1>
|
|
<sect1 xml:id="language.namespaces.nested">
|
|
<title>Declaración de un subespacio de nombres</title>
|
|
<titleabbrev>Subespacio de nombres</titleabbrev>
|
|
<?phpdoc print-version-for="namespaces"?>
|
|
<para>
|
|
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:
|
|
<example>
|
|
<title>Declaración de un espacio de nombres con jerarquía</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace MonProjet\Sous\Niveau;
|
|
|
|
const CONNEXION_OK = 1;
|
|
class Connexion { /* ... */ }
|
|
function connecte() { /* ... */ }
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
En el ejemplo anterior, se crean la constante <literal>MonProjet\Sous\Niveau\CONNEXION_OK</literal>,
|
|
la clase <literal>MonProjet\Sous\Niveau\Connexion</literal> y la función
|
|
<literal>MonProjet\Sous\Niveau\connecte</literal>.
|
|
</para>
|
|
</sect1>
|
|
<sect1 xml:id="language.namespaces.definitionmultiple">
|
|
<title>Definición de varios espacios de nombres en el mismo archivo</title>
|
|
<titleabbrev>Definición de varios espacios de nombres en el mismo archivo</titleabbrev>
|
|
<?phpdoc print-version-for="namespaces"?>
|
|
<para>
|
|
También pueden declararse varios espacios de nombres en el mismo archivo.
|
|
Hay dos sintaxis autorizadas.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Declaración de varios espacios de nombres, sintaxis de combinación simple</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace MonProjet;
|
|
|
|
const CONNEXION_OK = 1;
|
|
class Connexion { /* ... */ }
|
|
function connecte() { /* ... */ }
|
|
|
|
namespace AutreProjet;
|
|
|
|
const CONNEXION_OK = 1;
|
|
class Connexion { /* ... */ }
|
|
function connecte() { /* ... */ }
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Esta sintaxis no se recomienda para combinar espacios de nombres
|
|
en un solo archivo. En su lugar, se recomienda utilizar
|
|
la sintaxis de llaves.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Declaración de varios espacios de nombres, sintaxis de llaves</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace MonProjet {
|
|
|
|
const CONNEXION_OK = 1;
|
|
class Connexion { /* ... */ }
|
|
function connecte() { /* ... */ }
|
|
}
|
|
|
|
namespace AutreProjet {
|
|
|
|
const CONNEXION_OK = 1;
|
|
class Connexion { /* ... */ }
|
|
function connecte() { /* ... */ }
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
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>
|
|
<para>
|
|
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:
|
|
<example>
|
|
<title>Declaración de varios espacios de nombres con un espacio sin nombre</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace MonProjet {
|
|
|
|
const CONNEXION_OK = 1;
|
|
class Connexion { /* ... */ }
|
|
function connecte() { /* ... */ }
|
|
}
|
|
|
|
namespace { // código global
|
|
session_start();
|
|
$a = MonProjet\connecte();
|
|
echo MonProjet\Connexion::start();
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
No puede existir ningún código PHP fuera de las llaves del espacio de nombres,
|
|
excepto para abrir una nueva instrucción <literal>declare</literal>.
|
|
<example>
|
|
<title>Declaración de varios espacios de nombres con un espacio sin nombre (2)</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
declare(encoding='UTF-8');
|
|
namespace MonProjet {
|
|
|
|
const CONNEXION_OK = 1;
|
|
class Connexion { /* ... */ }
|
|
function connecte() { /* ... */ }
|
|
}
|
|
|
|
namespace { // código global
|
|
session_start();
|
|
$a = MonProjet\connecte();
|
|
echo MonProjet\Connexion::start();
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
</sect1>
|
|
<sect1 xml:id="language.namespaces.basics">
|
|
<title>Uso de espacios de nombres: introducción</title>
|
|
<titleabbrev>Introducción</titleabbrev>
|
|
<?phpdoc print-version-for="namespaces"?>
|
|
<para>
|
|
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:
|
|
<orderedlist>
|
|
<listitem>
|
|
<simpara>
|
|
Un nombre de archivo relativo, como <literal>foo.txt</literal>. Esto se resuelve
|
|
en <literal>dossiercourant/foo.txt</literal> donde <literal>dossiercourant</literal> es el
|
|
directorio de trabajo. Si el directorio actual es <literal>/home/foo</literal>,
|
|
este nombre se resuelve en <literal>/home/foo/foo.txt</literal>.
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
Una ruta relativa, como <literal>sub-dossier/foo.txt</literal>. Esto se
|
|
resuelve en <literal>dossiercourant/sub-dossier/foo.txt</literal>.
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
Una ruta absoluta, como <literal>/main/foo.txt</literal>. Esto se resuelve
|
|
en <literal>/main/foo.txt</literal>.
|
|
</simpara>
|
|
</listitem>
|
|
</orderedlist>
|
|
El mismo principio puede aplicarse a los espacios de nombres de PHP.
|
|
Por ejemplo, puede hacer referencia a una clase de tres maneras:
|
|
<orderedlist>
|
|
<listitem>
|
|
<simpara>
|
|
Un nombre sin calificador, o una clase sin prefijo, como
|
|
<literal>$a = new foo();</literal> o
|
|
<literal>foo::methodestatique();</literal>. Si el espacio de nombres actual
|
|
es <literal>espacedenomscourant</literal>, esto se resuelve en
|
|
<literal>espacedenomscourant\foo</literal>. Si el espacio de nombres es
|
|
global, es decir, el espacio de nombres sin nombre, esto se convierte en <literal>foo</literal>.
|
|
</simpara>
|
|
<simpara>
|
|
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
|
|
<link linkend="language.namespaces.fallback">Uso de espacios de nombres:
|
|
retorno al espacio de nombres global para funciones y constantes</link> para
|
|
más detalles.
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
Un nombre calificado, o una clase con prefijo como
|
|
<literal>$a = new sousespacedenoms\foo();</literal> o
|
|
<literal>sousespacedenoms\foo::methodestatique();</literal>. Si el espacio de nombres actual
|
|
es <literal>espacedenomscourant</literal>, esto se convierte
|
|
en <literal>espacedenomscourant\sousespacedenoms\foo</literal>. Si
|
|
el código es global, es decir, el espacio de nombres sin nombre,
|
|
esto se convierte en <literal>sousespacedenoms\foo</literal>.
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
Un nombre absoluto, o un nombre con prefijo con un operador global como
|
|
<literal>$a = new \espacedenomscourant\foo();</literal> o
|
|
<literal>\espacedenomscourant\foo::methodestatique();</literal>. Esto siempre
|
|
hace referencia al nombre literal especificado en el código: <literal>espacedenomscourant\foo</literal>.
|
|
</simpara>
|
|
</listitem>
|
|
</orderedlist>
|
|
</para>
|
|
<para>
|
|
Aquí hay un ejemplo de las tres sintaxis, en código real:
|
|
<informalexample>
|
|
<simpara>file1.php</simpara>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace Foo\Bar\sousespacedenoms;
|
|
|
|
const FOO = 1;
|
|
function foo() {}
|
|
class foo
|
|
{
|
|
static function methodestatique() {}
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
<simpara>file2.php</simpara>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace Foo\Bar;
|
|
include 'file1.php';
|
|
|
|
const FOO = 2;
|
|
function foo() {}
|
|
class foo
|
|
{
|
|
static function methodestatique() {}
|
|
}
|
|
|
|
/* nombre no calificado */
|
|
foo(); // Se convierte en Foo\Bar\foo
|
|
foo::methodestatique(); // Se convierte en Foo\Bar\foo, método methodestatique
|
|
echo FOO; // Se convierte en la constante Foo\Bar\FOO
|
|
|
|
/* nombre calificado */
|
|
sousespacedenoms\foo(); // Se convierte en la función Foo\Bar\sousespacedenoms\foo
|
|
sousespacedenoms\foo::methodestatique(); // se convierte en la clase Foo\Bar\sousespacedenoms\foo,
|
|
// método methodestatique
|
|
echo sousespacedenoms\FOO; // Se convierte en la constante Foo\Bar\sousespacedenoms\FOO
|
|
|
|
/* nombre absoluto */
|
|
\Foo\Bar\foo(); // Se convierte en la función Foo\Bar\foo
|
|
\Foo\Bar\foo::methodestatique(); // Se convierte en la clase Foo\Bar\foo, método methodestatique
|
|
echo \Foo\Bar\FOO; // Se convierte en la constante Foo\Bar\FOO
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
Tenga en cuenta que para acceder a cualquier clase, función o constante
|
|
global, puede utilizarse un nombre absoluto, como
|
|
<function>\strlen</function> o <classname>\Exception</classname> o
|
|
\<constant>INI_ALL</constant>.
|
|
<example>
|
|
<title>Acceso 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('hi'); // llama a la función global strlen
|
|
$b = \INI_ALL; // acceso a una constante INI_ALL
|
|
$c = new \Exception('error'); // instancia la clase global Exception
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
</sect1>
|
|
<sect1 xml:id="language.namespaces.dynamic">
|
|
<title>Espacios de nombres y lenguaje dinámico</title>
|
|
<titleabbrev>Espacios de nombres y lenguaje dinámico</titleabbrev>
|
|
<?phpdoc print-version-for="namespaces"?>
|
|
<para>
|
|
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:
|
|
<example>
|
|
<title>Acceso dinámico a elementos</title>
|
|
<simpara>example1.php:</simpara>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
class classname
|
|
{
|
|
function __construct()
|
|
{
|
|
echo __METHOD__,"\n";
|
|
}
|
|
}
|
|
function funcname()
|
|
{
|
|
echo __FUNCTION__,"\n";
|
|
}
|
|
const constname = "global";
|
|
|
|
$a = 'classname';
|
|
$obj = new $a; // muestra classname::__construct
|
|
$b = 'funcname';
|
|
$b(); // muestra funcname
|
|
echo constant('constname'), "\n"; // muestra global
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
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.
|
|
<example>
|
|
<title>Acceso dinámico a espacios de nombres</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace nomdelespacedenoms;
|
|
class classname
|
|
{
|
|
function __construct()
|
|
{
|
|
echo __METHOD__,"\n";
|
|
}
|
|
}
|
|
function funcname()
|
|
{
|
|
echo __FUNCTION__,"\n";
|
|
}
|
|
const constname = "namespaced";
|
|
|
|
/* Tenga en cuenta que si utiliza comillas dobles, "\\nomdelespacedenoms\\classname" debe usarse */
|
|
$a = '\nomdelespacedenoms\classname';
|
|
$obj = new $a; // muestra nomdelespacedenoms\classname::__construct
|
|
$a = 'nomdelespacedenoms\classname';
|
|
$obj = new $a; // también muestra nomdelespacedenoms\classname::__construct
|
|
$b = 'nomdelespacedenoms\funcname';
|
|
$b(); // muestra nomdelespacedenoms\funcname
|
|
$b = '\nomdelespacedenoms\funcname';
|
|
$b(); // también muestra nomdelespacedenoms\funcname
|
|
echo constant('\nomdelespacedenoms\constname'), "\n"; // muestra namespaced
|
|
echo constant('nomdelespacedenoms\constname'), "\n"; // también muestra namespaced
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Se recomienda leer la <link linkend="language.namespaces.faq.quote">nota sobre la protección de espacios de nombres en cadenas</link>.
|
|
</para>
|
|
</sect1>
|
|
<sect1 xml:id="language.namespaces.nsconstants">
|
|
<title>El comando namespace y la constante __NAMESPACE__</title>
|
|
<titleabbrev>Comando namespace y __NAMESPACE__</titleabbrev>
|
|
<?phpdoc print-version-for="namespaces"?>
|
|
<para>
|
|
PHP admite dos medios para acceder de manera abstracta a los elementos
|
|
en el espacio de nombres actual, a saber, la constante mágica
|
|
<constant>__NAMESPACE__</constant> y el comando <literal>namespace</literal>.
|
|
</para>
|
|
<para>
|
|
El valor de <constant>__NAMESPACE__</constant> es una cadena que contiene el nombre
|
|
del espacio de nombres actual. En el espacio global, sin nombre, contiene
|
|
una cadena vacía.
|
|
<example>
|
|
<title>Ejemplo con __NAMESPACE__, en un código con espacio de nombres</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace MonProjet;
|
|
|
|
echo '"', __NAMESPACE__, '"'; // muestra "MonProjet"
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
<example>
|
|
<title>Ejemplo con __NAMESPACE__, en un código con espacio de nombres global</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
echo '"', __NAMESPACE__, '"'; // muestra ""
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
La constante <constant>__NAMESPACE__</constant> es útil para construir
|
|
dinámicamente nombres, como:
|
|
<example>
|
|
<title>Uso de __NAMESPACE__ para una construcción dinámica de nombres</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace MonProjet;
|
|
|
|
function get($classname)
|
|
{
|
|
$a = __NAMESPACE__ . '\\' . $classname;
|
|
return new $a;
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
El comando <literal>namespace</literal> 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
|
|
<literal>self</literal> de las clases.
|
|
<example>
|
|
<title>El operador namespace, en un espacio de nombres</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace MonProjet;
|
|
|
|
use blah\blah as mine; // Ver "Uso de espacios de nombres: alias e importación"
|
|
|
|
blah\mine(); // llama a la función MonProjet\blah\mine()
|
|
namespace\blah\mine(); // llama a la función MonProjet\blah\mine()
|
|
|
|
namespace\func(); // llama a la función MonProjet\func()
|
|
namespace\sub\func(); // llama a la función MonProjet\sub\func()
|
|
namespace\cname::method(); // llama al método estático "method" de la clase MonProjet\cname
|
|
$a = new namespace\sub\cname(); // instancia un objeto de la clase MonProjet\sub\cname
|
|
$b = namespace\CONSTANT; // asigna el valor de la constante MonProjet\CONSTANT a $b
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
<example>
|
|
<title>El operador namespace, en el espacio de nombres 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\cname::method(); // llama al método estático "method" de la clase cname
|
|
$a = new namespace\sub\cname(); // instancia un objeto de la clase sub\cname
|
|
$b = namespace\CONSTANT; // asigna el valor de la constante CONSTANT a $b
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
</sect1>
|
|
<sect1 xml:id="language.namespaces.importing">
|
|
<?phpdoc print-version-for="namespaces"?>
|
|
<title>Uso de espacios de nombres: importación y alias</title>
|
|
<titleabbrev>Importación y alias</titleabbrev>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
PHP puede crear alias(/importar) constantes, funciones, clases, interfaces,
|
|
traits, enumeraciones y espacios de nombres.
|
|
</para>
|
|
<para>
|
|
Un alias se crea con el operador <literal>use</literal>.
|
|
Aquí hay un ejemplo que presenta los cinco tipos de importación:
|
|
<example>
|
|
<title>Importación y alias con el operador use</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace foo;
|
|
use My\Full\Classname as Another;
|
|
|
|
// Esto es lo mismo que use My\Full\NSname as NSname
|
|
use My\Full\NSname;
|
|
|
|
// importación de una clase global
|
|
use ArrayObject;
|
|
|
|
// importación de una función
|
|
use function My\Full\functionName;
|
|
|
|
// alias de una función
|
|
use function My\Full\functionName as func;
|
|
|
|
// importación de una constante
|
|
use const My\Full\CONSTANT;
|
|
|
|
$obj = new namespace\Another; // instancia un objeto de la clase foo\Another
|
|
$obj = new Another; // instancia un objeto de la clase My\Full\Classname
|
|
NSname\subns\func(); // llama a la función My\Full\NSname\subns\func
|
|
$a = new ArrayObject(array(1)); // instancia un objeto de la clase ArrayObject
|
|
// Sin la instrucción "use ArrayObject" habríamos instanciado un objeto de la clase foo\ArrayObject
|
|
func(); // Llama a la función My\Full\functionName
|
|
echo CONSTANT; // muestra el valor de My\Full\CONSTANT
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
Tenga en cuenta que para los nombres con ruta (los nombres absolutos que contienen
|
|
separadores de espacios, como <literal>Foo\Bar</literal>, en comparación con
|
|
los nombres globales, como <literal>FooBar</literal>, 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.
|
|
</para>
|
|
<para>
|
|
Además, PHP admite atajos prácticos, como las instrucciones use múltiples.
|
|
<example>
|
|
<title>Importación y alias múltiples con el operador use</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
use My\Full\Classname as Another, My\Full\NSname;
|
|
|
|
$obj = new Another; // instancia un objeto de la clase My\Full\Classname
|
|
NSname\subns\func(); // llama a la función My\Full\NSname\subns\func
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
La importación se realiza durante la compilación, por lo que no afecta
|
|
a las clases, funciones y constantes dinámicas.
|
|
<example>
|
|
<title>Importación y nombres de espacios dinámicos</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
use My\Full\Classname as Another, My\Full\NSname;
|
|
|
|
$obj = new Another; // instancia un objeto de la clase My\Full\Classname
|
|
$a = 'Another';
|
|
$obj = new $a; // instancia un objeto de la clase Another
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
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.
|
|
<example>
|
|
<title>Importación y nombres de espacios absolutos</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
use My\Full\Classname as Another, My\Full\NSname;
|
|
|
|
$obj = new Another; // instancia un objeto de la clase My\Full\Classname
|
|
$obj = new \Another; // instancia un objeto de la clase Another
|
|
$obj = new Another\untruc; // instancia un objeto de la clase My\Full\Classname\untruc
|
|
$obj = new \Another\untruc; // instancia un objeto de la clase Another\untruc
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<sect2 xml:id="language.namespaces.importing.scope">
|
|
<title>Reglas de contexto para la importación</title>
|
|
<para>
|
|
La palabra clave <literal>use</literal> 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 <literal>use</literal>:
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Reglas de importación incorrectas</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace Languages;
|
|
|
|
function toGreenlandic
|
|
{
|
|
use Languages\Danish;
|
|
// ...
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<note>
|
|
<para>
|
|
Las reglas de importación se basan en archivos, lo que significa que los archivos
|
|
incluidos no heredarán <emphasis>PAS</emphasis> las reglas de importación del archivo padre.
|
|
</para>
|
|
</note>
|
|
</sect2>
|
|
<sect2 xml:id="language.namespaces.importing.group">
|
|
<title>Declaración del grupo <literal>use</literal></title>
|
|
<para>
|
|
Las clases, funciones y constantes importadas desde
|
|
el mismo &namespace; pueden agruparse en una
|
|
sola instrucción &use.namespace;.
|
|
</para>
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
use some\namespace\ClassA;
|
|
use some\namespace\ClassB;
|
|
use some\namespace\ClassC as C;
|
|
|
|
use function some\namespace\fn_a;
|
|
use function some\namespace\fn_b;
|
|
use function some\namespace\fn_c;
|
|
|
|
use const some\namespace\ConstA;
|
|
use const some\namespace\ConstB;
|
|
use const some\namespace\ConstC;
|
|
|
|
// es equivalente a la siguiente declaración de grupo use
|
|
use some\namespace\{ClassA, ClassB, ClassC as C};
|
|
use function some\namespace\{fn_a, fn_b, fn_c};
|
|
use const some\namespace\{ConstA, ConstB, ConstC};
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</sect2>
|
|
|
|
</sect1>
|
|
<sect1 xml:id="language.namespaces.global">
|
|
<title>Espacio de nombres global</title>
|
|
<titleabbrev>Global</titleabbrev>
|
|
<?phpdoc print-version-for="namespaces"?>
|
|
<para>
|
|
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
|
|
<literal>\</literal>, se puede solicitar el uso del espacio de nombres
|
|
global, incluso en un contexto de espacio de nombres específico.
|
|
<example>
|
|
<title>Especificación de espacio de nombres global</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace A\B\C;
|
|
|
|
/* Esta función es A\B\C\fopen */
|
|
function fopen() {
|
|
/* ... */
|
|
$f = \fopen(...); // llamada a fopen global
|
|
return $f;
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
</sect1>
|
|
<sect1 xml:id="language.namespaces.fallback">
|
|
<title>Uso de espacios de nombres: retorno al espacio global para funciones y constantes</title>
|
|
<titleabbrev>Retorno al espacio global</titleabbrev>
|
|
<?phpdoc print-version-for="namespaces"?>
|
|
<para>
|
|
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:
|
|
<example>
|
|
<title>Acceso a clases globales desde un espacio de nombres</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace A\B\C;
|
|
class Exception extends \Exception {}
|
|
|
|
$a = new Exception('hi'); // $a es un objeto de la clase A\B\C\Exception
|
|
$b = new \Exception('hi'); // $b es un objeto de la clase Exception
|
|
|
|
$c = new ArrayObject; // error fatal, clase A\B\C\ArrayObject no encontrada
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Para las funciones y constantes, PHP las buscará en el espacio
|
|
global si no puede encontrarlas en el espacio de nombres actual.
|
|
<example>
|
|
<title>Acceso a funciones y constantes globales en 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"; // muestra "45"
|
|
echo INI_ALL, "\n"; // muestra "7": acceso al espacio de nombres global INI_ALL
|
|
|
|
echo strlen('hi'), "\n"; // muestra "1"
|
|
if (is_array('hi')) { // muestra "no es un array"
|
|
echo "es un 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>
|
|
<titleabbrev>Reglas de resolución de nombres</titleabbrev>
|
|
<?phpdoc print-version-for="namespaces"?>
|
|
<para>
|
|
En el contexto de las reglas de resolución, hay varias definiciones importantes:
|
|
<variablelist>
|
|
<title>Definiciones para espacios de nombres</title>
|
|
<varlistentry>
|
|
<term>nombre no calificado</term>
|
|
<listitem>
|
|
<para>
|
|
Esto es un identificador que no contiene un separador de espacio de nombres.
|
|
Por ejemplo: <literal>Foo</literal>
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>nombre calificado</term>
|
|
<listitem>
|
|
<para>
|
|
Esto es un identificador que contiene un separador de espacio de nombres.
|
|
Por ejemplo: <literal>Foo\Bar</literal>
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Nombre absoluto</term>
|
|
<listitem>
|
|
<para>
|
|
Esto es un identificador que comienza con un separador de espacio de nombres.
|
|
Por ejemplo: <literal>\Foo\Bar</literal>. El espacio de nombres <literal>Foo</literal>
|
|
también es un nombre absoluto.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Nombre Relativo</term>
|
|
<listitem>
|
|
<para>
|
|
Es un identificador que comienza con <literal>namespace</literal>, como
|
|
<literal>namespace\Foo\Bar</literal>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</para>
|
|
<para>
|
|
Los nombres se resuelven siguiendo las siguientes reglas:
|
|
<orderedlist>
|
|
<listitem>
|
|
<simpara>
|
|
Los nombres absolutos siempre se traducen a nombres sin el separador de namespace.
|
|
Por ejemplo, <literal>\A\B</literal> se traduce a <literal>A\B</literal>.
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
Todos los nombres que no son absolutos se traducen con
|
|
<literal>namespace</literal> reemplazado por el namespace actual.
|
|
Si el nombre aparece en el namespace global, el prefijo
|
|
<literal>namespace\</literal> se elimina. Por ejemplo <literal>namespace\A</literal>
|
|
en el namespace <literal>X\Y</literal> se traduce a <literal>X\Y\A</literal>.
|
|
El mismo nombre en el namespace global se traduce a <literal>A</literal>.
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
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 <literal>A\B\C</literal> se importa como <literal>C</literal>, el nombre <literal>C\D\E</literal> se traduce a <literal>A\B\C\D\E</literal>.
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
Para los nombres absolutos, si ninguna regla de importación
|
|
se aplica, el namespace actual se prefiere al nombre.
|
|
Por ejemplo, el nombre <literal>C\D\E</literal> en el namespace <literal>A\B</literal>,
|
|
se traduce a <literal>A\B\C\D\E</literal>.
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
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
|
|
<literal>use A\B\C;</literal> un uso como <literal>new C()</literal> corresponde al nombre
|
|
<literal>A\B\C()</literal>. De manera similar, después de <literal>use function A\B\foo;</literal> un uso
|
|
como <literal>foo()</literal> corresponde al nombre <literal>A\B\foo</literal>.
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
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 <literal>new C()</literal> en el namespace
|
|
<literal>A\B</literal> corresponde al nombre <literal>A\B\C</literal>.
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
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
|
|
<literal>A\B</literal>, aquí es cómo se resuelve una llamada a la función <literal>foo()</literal>:
|
|
</simpara>
|
|
|
|
<orderedlist>
|
|
<listitem>
|
|
<simpara>
|
|
Busca una función en el espacio de nombres actual:
|
|
<literal>A\B\foo()</literal>.
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
Intenta encontrar y llamar a la función <emphasis>global</emphasis>
|
|
<literal>foo()</literal>.
|
|
</simpara>
|
|
</listitem>
|
|
</orderedlist>
|
|
</listitem>
|
|
</orderedlist>
|
|
</para>
|
|
<example>
|
|
<title>Ejemplos de resolución de espacios de nombres</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?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"
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</sect1>
|
|
<sect1 xml:id="language.namespaces.faq">
|
|
<title>Preguntas frecuentes: lo que debe saber sobre espacios de nombres</title>
|
|
<titleabbrev>Preguntas frecuentes</titleabbrev>
|
|
<?phpdoc print-version-for="namespaces"?>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
Primero, las preguntas comunes.
|
|
<orderedlist>
|
|
<listitem>
|
|
<simpara>
|
|
<link linkend="language.namespaces.faq.shouldicare">Si no utilizo espacios
|
|
de nombres, ¿debo preocuparme por ellos?</link>
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
<link linkend="language.namespaces.faq.globalclass">¿Cómo utilizar una clase
|
|
global o interna desde un espacio de nombres?</link>
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
<link linkend="language.namespaces.faq.innamespace">¿Cómo utilizar las clases
|
|
de espacios de nombres, las funciones o las constantes en su propio espacio?</link>
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
<link linkend="language.namespaces.faq.full">
|
|
¿Cómo se resuelve un nombre como <literal>\mon\nom</literal> o
|
|
<literal>\nom</literal>?
|
|
</link>
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
<link linkend="language.namespaces.faq.qualified">¿Cómo se resuelve un nombre
|
|
como <literal>mon\nom</literal>?</link>
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
<link linkend="language.namespaces.faq.shortname1">¿Cómo se resuelve un nombre de clase
|
|
sin calificación, como <literal>nom</literal>?</link>
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
<link linkend="language.namespaces.faq.shortname2">¿Cómo se resuelve una función sin
|
|
calificación o una constante de nombre <literal>nom</literal>?</link>
|
|
</simpara>
|
|
</listitem>
|
|
</orderedlist>
|
|
</para>
|
|
<para>
|
|
Aquí están los puntos particulares de la implementación, que pueden ser
|
|
útiles para la comprensión global.
|
|
<orderedlist>
|
|
<listitem>
|
|
<simpara>
|
|
<link linkend="language.namespaces.faq.conflict">Los nombres importados no deben
|
|
entrar en conflicto con las clases definidas en el mismo archivo</link>
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
<link linkend="language.namespaces.faq.nested">Los espacios de nombres anidados
|
|
están prohibidos</link>
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
<link linkend="language.namespaces.faq.quote">Los nombres de espacios de nombres
|
|
dinámicos deben proteger el backslash</link>
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
<link linkend="language.namespaces.faq.constants">Las constantes no definidas
|
|
referenciadas con un backslash producen un error fatal</link>
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
<link linkend="language.namespaces.faq.builtinconst">Imposible reemplazar
|
|
constantes especiales como &null;, &true; o &false;</link>
|
|
</simpara>
|
|
</listitem>
|
|
</orderedlist>
|
|
</para>
|
|
<sect2 xml:id="language.namespaces.faq.shouldicare">
|
|
<title>Si no utilizo espacios de nombres, ¿debo preocuparme por ellos?</title>
|
|
<para>
|
|
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:
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Acceso a una clase global desde fuera de un espacio de nombres</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$a = new \stdClass;
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Es una funcionalidad 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 utilizar una clase global o interna desde un espacio de nombres?</title>
|
|
<para>
|
|
<example>
|
|
<title>Acceso a clases internas desde un espacio de nombres</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace foo;
|
|
$a = new \stdClass;
|
|
|
|
function test(\ArrayObject $parameter_type_example = null) {}
|
|
|
|
$a = \DirectoryIterator::CURRENT_AS_FILEINFO;
|
|
|
|
// extensión de una clase interna o global
|
|
class MyException extends \Exception {}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
</sect2>
|
|
<sect2 xml:id="language.namespaces.faq.innamespace">
|
|
<title>
|
|
¿Cómo utilizar las clases de espacios de nombres, las funciones o
|
|
las constantes en su propio espacio?
|
|
</title>
|
|
<para>
|
|
<example>
|
|
<title>Acceso a clases, funciones y constantes internas en un espacio de nombres</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace foo;
|
|
|
|
class MaClasse {}
|
|
|
|
// uso de una clase en el espacio de nombres actual, como tipo de parámetro
|
|
function test(MaClasse $parameter_type_example = null) {}
|
|
|
|
// otra manera de usar una clase en el espacio de nombres actual como tipo de parámetro
|
|
function test(\foo\MaClasse $parameter_type_example = null) {}
|
|
|
|
// extensión de una clase en el espacio de nombres actual
|
|
class Extended extends MaClasse {}
|
|
|
|
// acceso a una función global
|
|
$a = \globalfunc();
|
|
|
|
// acceso 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>\mon\nom</literal> o
|
|
<literal>\nom</literal>?
|
|
</title>
|
|
<para>
|
|
Los nombres que comienzan con <literal>\</literal> siempre se resuelven como son,
|
|
por lo que <literal>\mon\nom</literal> es en realidad
|
|
<literal>mon\nom</literal>, y <literal>\Exception</literal> es
|
|
<literal>Exception</literal>.
|
|
<example>
|
|
<title>Nombres de espacios absolutos</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace foo;
|
|
$a = new \mon\nom(); // instancia la clase "mon\nom"
|
|
echo \strlen('hi'); // llama a la función "strlen"
|
|
$a = \INI_ALL; // $a recibe el 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>mon\nom</literal>?</title>
|
|
<para>
|
|
Los nombres que contienen un backslash pero no comienzan con un
|
|
backslash, como <literal>mon\nom</literal> pueden resolverse de dos maneras
|
|
diferentes.
|
|
</para>
|
|
<para>
|
|
Si ha habido una instrucción de importación que hace un alias de
|
|
<literal>mon</literal>, entonces el alias importado se aplica en lugar
|
|
de <literal>mon</literal>, y el espacio de nombres se convierte en <literal>mon\nom</literal>.
|
|
</para>
|
|
<para>
|
|
De lo contrario, el espacio de nombres actual se agrega antes del camino de la clase
|
|
<literal>mon\nom</literal>.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Nombres calificados</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace foo;
|
|
use blah\blah as foo;
|
|
|
|
$a = new mon\nom(); // instancia la clase "foo\mon\nom"
|
|
foo\bar::name(); // llama al método estático "name" en la clase "blah\blah\bar"
|
|
mon\bar(); // llama a la función "foo\mon\bar"
|
|
$a = mon\BAR; // asigna a $a el valor de la constante "foo\mon\BAR"
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
</sect2>
|
|
<sect2 xml:id="language.namespaces.faq.shortname1">
|
|
<title>¿Cómo se resuelve un nombre de clase
|
|
sin calificación, como <literal>nom</literal>?</title>
|
|
<para>
|
|
Los nombres de clases que no contienen backslash como
|
|
<literal>nom</literal> pueden resolverse de dos maneras diferentes.
|
|
</para>
|
|
<para>
|
|
Si hay una instrucción de importación que define un alias para <literal>nom</literal>,
|
|
entonces se aplica el alias.
|
|
</para>
|
|
<para>
|
|
De lo contrario, se utiliza el espacio de nombres actual y se prefiere a
|
|
<literal>nom</literal>.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Clases sin calificación</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace foo;
|
|
use blah\blah as foo;
|
|
|
|
$a = new nom(); // instancia la clase "foo\nom"
|
|
foo::nom(); // llama al método estático "nom" en la clase "blah\blah"
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
</sect2>
|
|
<sect2 xml:id="language.namespaces.faq.shortname2">
|
|
<title>
|
|
¿Cómo se resuelve una función sin calificación o una constante
|
|
de nombre <literal>nom</literal>?
|
|
</title>
|
|
<para>
|
|
Las funciones y constantes que no tienen backslash en su nombre
|
|
como <literal>nom</literal> se resuelven de dos maneras diferentes:
|
|
</para>
|
|
<para>
|
|
Primero, se prefiere el espacio de nombres actual a <literal>nom</literal>.
|
|
</para>
|
|
<para>
|
|
Luego, si la constante o función <literal>nom</literal> no existe
|
|
en el espacio de nombres actual, se utiliza la versión global de la constante o la
|
|
función <literal>nom</literal>.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Funciones y constantes sin espacio de nombres</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace foo;
|
|
use blah\blah as foo;
|
|
|
|
const FOO = 1;
|
|
|
|
function mon() {}
|
|
function foo() {}
|
|
function sort(&$a)
|
|
{
|
|
\sort($a); // Llamada a la función global "sort"
|
|
$a = array_flip($a);
|
|
return $a;
|
|
}
|
|
|
|
mon(); // llama "foo\mon"
|
|
$a = strlen('hi'); // llama a la función global "strlen" ya que "foo\strlen" no existe
|
|
$arr = array(1,3,2);
|
|
$b = sort($arr); // llama a la función "foo\sort"
|
|
$c = foo(); // llama a la función "foo\foo": la importación no se aplica
|
|
|
|
$a = FOO; // asigna a $a el valor de la constante "foo\FOO": la importación no se aplica
|
|
$b = INI_ALL; // asigna a $b el valor de la constante "INI_ALL"
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
</sect2>
|
|
<sect2 xml:id="language.namespaces.faq.conflict">
|
|
<title>Los nombres importados no deben
|
|
entrar en conflicto con las clases definidas en el mismo archivo</title>
|
|
<para>
|
|
La siguiente combinación de scripts es válida:
|
|
<informalexample>
|
|
<simpara>file1.php</simpara>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace mes\trucs;
|
|
class MaClasse {}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
<simpara>another.php</simpara>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace another;
|
|
class untruc {}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
<simpara>file2.php</simpara>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace mes\trucs;
|
|
include 'file1.php';
|
|
include 'another.php';
|
|
|
|
use another\untruc as MaClasse;
|
|
$a = new MaClasse; // instancia la clase "untruc" del espacio de nombres another
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
No hay conflicto de nombres, incluso si la clase <literal>MaClasse</literal> existe
|
|
en el espacio de nombres <literal>mes\trucs</literal>, ya que la definición de
|
|
<literal>MaClasse</literal> está en un archivo separado. Sin embargo, el siguiente
|
|
ejemplo produce un error fatal debido a un conflicto de nombres, ya que
|
|
<literal>MaClasse</literal> se define en el mismo archivo que la instrucción
|
|
<literal>use</literal>.
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace mes\trucs;
|
|
use another\untruc as MaClasse;
|
|
class MaClasse {} // error fatal: MaClasse está en conflicto con la instrucción de importación
|
|
$a = new MaClasse;
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
</sect2>
|
|
<sect2 xml:id="language.namespaces.faq.nested">
|
|
<title>Los espacios de nombres anidados están prohibidos</title>
|
|
<para>
|
|
PHP no permite anidar espacios de nombres.
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace mes\trucs {
|
|
namespace nested {
|
|
class foo {}
|
|
}
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
Sin embargo, es fácil simular espacios de nombres anidados,
|
|
como esto:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace mes\trucs\nested {
|
|
class foo {}
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
</sect2>
|
|
|
|
<sect2 xml:id="language.namespaces.faq.quote">
|
|
<title>Los nombres de espacios de nombres dinámicos deben proteger el backslash</title>
|
|
<para>
|
|
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:
|
|
<example>
|
|
<title>Peligros de usar espacios de nombres en una cadena</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$a = "dangereux\nom"; // \n es una nueva línea en una cadena!
|
|
$obj = new $a;
|
|
|
|
$a = 'pas\vraiment\dangereux'; // ningún problema aquí
|
|
$obj = new $a;
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
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.
|
|
</para>
|
|
</sect2>
|
|
<sect2 xml:id="language.namespaces.faq.constants">
|
|
<title>Constantes no definidas referenciadas con un backslash producen un error fatal</title>
|
|
<para>
|
|
Cualquier constante no definida que no tenga calificador como
|
|
<literal>FOO</literal> producirá una advertencia: PHP asumía que
|
|
<literal>FOO</literal> era el valor de la constante. Cualquier constante,
|
|
calificada parcialmente o totalmente, que contenga un backslash, producirá
|
|
un error fatal si no está definida.
|
|
<example>
|
|
<title>Constantes no definidas</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace bar;
|
|
$a = FOO; // produce una advertencia: constante no definida "FOO", que toma el valor de "FOO";
|
|
$a = \FOO; // error fatal, constante de espacio de nombres no definida FOO
|
|
$a = Bar\FOO; // error fatal, constante de espacio de nombres no definida bar\Bar\FOO
|
|
$a = \Bar\FOO; // error fatal, constante de espacio de nombres no definida Bar\FOO
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
</sect2>
|
|
<sect2 xml:id="language.namespaces.faq.builtinconst">
|
|
<title>Imposible reemplazar constantes especiales como &null;, &true; o &false;</title>
|
|
<para>
|
|
Cualquier intento en un espacio de nombres de reemplazar las constantes
|
|
nativas o especiales, produce un error fatal.
|
|
<example>
|
|
<title>Constantes que no pueden ser redefinidas</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace bar;
|
|
const NULL = 0; // error fatal;
|
|
const true = 'stupid'; // aún otro 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
|
|
-->
|