(PHP 5 >= 5.3.0)
Esta FAQ está dividida en dos secciones: preguntas comunes, y algunas especificaciones de implementación que son útiles para comprenderlos completamente.
Primero, las preguntas comunes.
Existen unos pocos detalles de implementación de las implementaciones de espacios de nombres que son útiles para enterderlos.
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:
Ejemplo #1 Acceder a clases globales fuera de un espacio de nombres
<?php
$a = new \stdClass;
?>
Esto es funcionalmente equivalente a:
Ejemplo #2 Acceder a clases globales fuera de un espacio de nombres
<?php
$a = new stdClass;
?>
Ejemplo #3 Acceder a clases internas en espacios de nombres
<?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 {}
?>
Ejemplo #4 Acceder a clases, funciones o constantes internas en un espacio de nombres
<?php
namespace foo;
class MiClase {}
// usar una clase desde el espacio de nombres actual como una alusión a tipo
function probar(MiClase $ejemploalusiónatipo = null) {}
// otra manera de usar una clase desde el espacio de nombres actual una alusión a 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;
?>
Los nombres que comienzan con una \ siempre se resuelven a aquello que parecen, así \mi\nombre de hecho es mi\nombre, y \Exception es Exception.
Ejemplo #5 Nombres Completamente Cualificados
<?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"
?>
Los nombres que contienen una barra invertida pero no comienzan con una barra invertida como mi\nombre pueden resolverse de 2 formas diferentes.
Si hay una sentencia de importación que apode a otro nombre como mi, el alias de importación se aplica a mi en mi\nombre.
De otro modo, al nombre del espacio de nombres actual se le añade al inicio mi\nombre.
Ejemplo #6 Nombres Cualificados
<?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"
?>
Los nombres de clases que no contienen una barra invertida como nombre se pueden resolver de 2 formas diferentes.
Si hay una sentencia de importación que apode a otro nombre como nombre, se aplica el alias de importación.
De otro modo, al nombre del espacio de nombres actual se le añade al inicio nombre.
Ejemplo #7 Nombres de clases no cualificados
<?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"
?>
Los nombres de funciones o de constantes que no contienen una barra invertida como nombre se pueden resolver de 2 formas diferentes.
Primero, al nombre del espacio de nombres actual se le añade al inicio nombre.
Finalmente, si el nombre de la constante o de la función no existe en el espacio de nombres actual, se usa un nombre de constante o función global si es que existe.
Ejemplo #8 Nombres de funciones o constantes no cualificados
<?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
$matriz = array(1,3,2);
$b = sort($matriz); // 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"
?>
Las siguientes combinaciones de scripts está permitidas:
archivo1.php
<?php
namespace mis\cosas;
class MiClase {}
?>
otro.php
<?php
namespace otro;
class cosa {}
?>
archivo2.php
<?php
namespace mis\cosas;
include 'archivo1.php';
include 'otro.php';
use otro\cosa as MiClase;
$a = new MiClase; // instancia a la clase "cosa" desde el espacio de nombres otro
?>
No existe conflicto entre nombres, aunque la clase MiClase exista dentro del espacio de nombres mis\cosas, porque la definición de MiClase está en otro archivo. Sin embargo, el siguiente ejemplo causa un error fatal con conflicto de nombres ya que MiClase está definida en el mismo archivo que el de la sentencia use.
<?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;
?>
PHP no permite los espacios de nombres anidados
<?php
namespace mis\cosas {
namespace anidado {
class foo {}
}
}
?>
<?php
namespace mis\cosas\anidado {
class foo {}
}
?>
Los únicos elementos que son afectados por la sentencia use son los espacios de nombres y los nombres de clases. Para abreviar una constante o función largas, importe el espacio de nombres que la contiene
<?php
namespace mío;
use nombre\en\ultra\largo;
$a = largo\CONSTANT;
largo\func();
?>
Es muy importante darse cuenta de que ya que la barra invertida se usa como carácter de escape dentro de cadenas, se deberían usar dobles cuando se utilizan dentro de cadenas. Si no, existe el riesgo de obtener consecuencias inesperadas:
Ejemplo #9 Peligros de usar nombres de espacios de nombres dentro de una cadena entre comillas dobles
<?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;
?>
Cualquier constante no definida que no es cualificada como FOO producirá una aviso explicando que PHP asume que FOO es el valor de la constante. Cualquier constante, cualificada o completamente cualificada, que contenga una barra invertida producirá un error fatal si no es encontrada.
Ejemplo #10 Constantes no definidas
<?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
?>
Cualquier intento de definir una constante de espacio de nombres que sea especial, constante interna, resultará en un error fatal
Ejemplo #11 Constantes no definidas
<?php
namespace bar;
const NULL = 0; // error fatal;
const true = 'estúpido'; // también error fatal;
// etc.
?>