Uso de los espacios de nombres: introducción

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

Antes de discutir el uso de los espacios de nombres, es importante comprender cómo PHP deduce qué espacio de nombres utiliza su código. Se puede hacer una analogía simple entre los espacios de nombres de PHP y un sistema de ficheros. Hay tres maneras de acceder a un fichero en un sistema de ficheros:

  1. Un nombre de fichero relativo, como foo.txt. Esto se resuelve en directoriocorriente/foo.txt donde directoriocorriente es el directorio de trabajo. Si el directorio actual es /home/foo, este nombre se resuelve en /home/foo/foo.txt.
  2. Una ruta relativa, como subdirectorio/foo.txt. Esto se resuelve en directoriocorriente/subdirectorio/foo.txt.
  3. Una ruta absoluta, como /main/foo.txt. Esto se resuelve en /main/foo.txt.
El mismo principio puede ser aplicado a los espacios de nombres de PHP. Por ejemplo, se puede hacer referencia a una clase de tres maneras:
  1. Un nombre sin calificativo, 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 calificativo para las funciones y las constantes se tomarán del espacio de nombres global, si la función no está definida en el espacio de nombres actual. Véase Uso de los espacios de nombres: retorno al espacio de nombres global para las funciones y las constantes para más detalles.
  2. Un nombre calificado, o una clase prefijada como $a = new subespacedenoms\foo(); o subespacedenoms\foo::methodestatique();. Si el espacio de nombres actual es espacedenomscourant, esto se convierte en espacedenomscourant\subespacedenoms\foo. Si el código es global, es decir, el espacio de nombres sin nombre, esto se convierte en subespacedenoms\foo.
  3. Un nombre absoluto, o un nombre prefijado 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.

A continuación se muestra un ejemplo de las tres sintaxis, en código real:

file1.php

<?php
namespace Foo\Bar\subespacio_de_nombres;

const
FOO = 1;
function
foo() {}
class
foo
{
static function
método_estático() {}
}
?>

file2.php

<?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
?>

Tenga en cuenta que para acceder a cualquier clase, función o constante global, se puede utilizar un nombre absoluto, como \strlen() o \Exception o \INI_ALL.

Ejemplo #1 Acceso a las clases, funciones y constantes globales desde un espacio de nombres

<?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
?>

add a note

User Contributed Notes 5 notes

up
211
richard at richard-sumilang dot com
17 years ago
Syntax for extending classes in namespaces is still the same.

Lets call this Object.php:

<?php

namespace com\rsumilang\common;

class
Object{
// ... code ...
}

?>

And now lets create a class called String that extends object in String.php:

<?php

class String extends com\rsumilang\common\Object{
// ... code ...
}

?>

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
{
// ... code ...
}

?>

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
{
// ... code ...
}

?>

- Richard Sumilang
up
113
Anonymous
10 years ago
<?php

namespace Foo;

try {
// Something awful here
// That will throw a new exception from SPL
}
catch (
Exception as $ex) {
// We will never get here
// This is because we are catchin Foo\Exception
}
?>

Instead use fully qualified name for the exception to catch it

<?php

namespace Foo;

try {
// something awful here
// That will throw a new exception from SPL
}
catch (
\Exception as $ex) {
// Now we can get here at last
}
?>
up
49
Lukas Z
13 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
up
40
tom at tomwardrop dot com
13 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.
up
18
philip dot preisser at arcor dot de
13 years ago
Working with variables can overwrite equal variables in other namespaces

<?php // php5 - package-version : 5.3.5-1ubuntu7.2

namespace
main
{}

namespace
main\sub1
{
$data = 1;
}

namespace
main\sub2
{
echo
$data;// 1
$data = 2;
}

namespace
main\sub1
{
echo
$data;// 2
$data = 1;
}

namespace
{
echo
$data;// 1
}

?>
To Top