Uso de espacios de nombres: introducción
(PHP 5 >= 5.3.0, PHP 7, PHP 8)
Antes de discutir el uso de espacios de nombres, es importante comprender
cómo PHP deduce qué espacio de nombres está utilizando su código. Puede hacerse
una analogía simple entre los espacios de nombres de PHP y un sistema de archivos.
Hay tres formas de acceder a un archivo en un sistema de archivos:
-
Un nombre de archivo relativo, como
foo.txt. Esto se resuelve
en dossiercourant/foo.txt donde dossiercourant es el
directorio de trabajo. Si el directorio actual es /home/foo,
este nombre se resuelve en /home/foo/foo.txt.
-
Una ruta relativa, como
sub-dossier/foo.txt. Esto se
resuelve en dossiercourant/sub-dossier/foo.txt.
-
Una ruta absoluta, como
/main/foo.txt. Esto se resuelve
en /main/foo.txt.
El mismo principio puede aplicarse a los espacios de nombres de PHP.
Por ejemplo, puede hacer referencia a una clase de tres maneras:
-
Un nombre sin calificador, o una clase sin prefijo, como
$a = new foo(); o
foo::methodestatique();. Si el espacio de nombres actual
es espacedenomscourant, esto se resuelve en
espacedenomscourant\foo. Si el espacio de nombres es
global, es decir, el espacio de nombres sin nombre, esto se convierte en foo.
Una advertencia: los nombres sin calificador para funciones y constantes
se tomarán del espacio de nombres global, si la función
no está definida en el espacio de nombres actual. Ver
Uso de espacios de nombres:
retorno al espacio de nombres global para funciones y constantes para
más detalles.
-
Un nombre calificado, o una clase con prefijo como
$a = new sousespacedenoms\foo(); o
sousespacedenoms\foo::methodestatique();. Si el espacio de nombres actual
es espacedenomscourant, esto se convierte
en espacedenomscourant\sousespacedenoms\foo. Si
el código es global, es decir, el espacio de nombres sin nombre,
esto se convierte en sousespacedenoms\foo.
-
Un nombre absoluto, o un nombre con prefijo con un operador global como
$a = new \espacedenomscourant\foo(); o
\espacedenomscourant\foo::methodestatique();. Esto siempre
hace referencia al nombre literal especificado en el código: espacedenomscourant\foo.
Aquí hay un ejemplo de las tres sintaxis, en código real:
Tenga en cuenta que para acceder a cualquier clase, función o constante
global, puede utilizarse un nombre absoluto, como
\strlen() o \Exception o
\INI_ALL.
Ejemplo #1 Acceso a clases, funciones y constantes globales desde un espacio de nombres
<?php
namespace Foo;
function strlen() {}
const INI_ALL = 3;
class Exception {}
print \strlen('hi') . "\n"; // llama a la función global strlen
print \INI_ALL . "\n"; // acceso a una constante INI_ALL
$c = new \Exception('error'); // instancia la clase global Exception
print $c::class . "\n";
richard at richard-sumilang dot com ¶18 years ago
Syntax for extending classes in namespaces is still the same.
Lets call this Object.php:
<?php
namespace com\rsumilang\common;
class Object{
}
?>
And now lets create a class called String that extends object in String.php:
<?php
class String extends com\rsumilang\common\Object{
}
?>
Now if you class String was defined in the same namespace as Object then you don't have to specify a full namespace path:
<?php
namespace com\rsumilang\common;
class String extends Object
{
}
?>
Lastly, you can also alias a namespace name to use a shorter name for the class you are extending incase your class is in seperate namespace:
<?php
namespace com\rsumilang\util;
use com\rsumlang\common as Common;
class String extends Common\Object
{
}
?>
- Richard Sumilang
Anonymous ¶11 years ago
<?php
namespace Foo;
try {
}
catch (Exception as $ex) {
}
?>
Instead use fully qualified name for the exception to catch it
<?php
namespace Foo;
try {
}
catch (\Exception as $ex) {
}
?>
Lukas Z ¶14 years ago
Well variables inside namespaces do not override others since variables are never affected by namespace but always global:
"Although any valid PHP code can be contained within a namespace, only four types of code are affected by namespaces: classes, interfaces, functions and constants. "
Source: "Defining Namespaces"
http://www.php.net/manual/en/language.namespaces.definition.php
tom at tomwardrop dot com ¶14 years ago
It seems the file system analogy only goes so far. One thing that's missing that would be very useful is relative navigation up the namespace chain, e.g.
<?php
namespace MyProject {
class Person {}
}
namespace MyProject\People {
class Adult extends ..\Person {}
}
?>
That would be really nice, especially if you had really deep namespaces. It would save you having to type out the full namespace just to reference a resource one level up.
philip dot preisser at arcor dot de ¶15 years ago
Working with variables can overwrite equal variables in other namespaces
<?php namespace
main
{}
namespace
main\sub1
{
$data = 1;
}
namespace
main\sub2
{
echo $data;$data = 2;
}
namespace
main\sub1
{
echo $data;$data = 1;
}
namespace
{
echo $data;}
?>