Namespaces en PHP

  • Por
  • PHP
Guía para el trabajo con espacios de nombres en PHP. Utilidades y manera de trabajar con ellos: declararlos y usarlos.

Los espacios de nombres son una de las utilidades que han aparecido en PHP 5, en la versión PHP 5.3. Ya tienen un tiempo de vida relativamente grande y deberían estar disponibles en tu servidor de PHP. Gracias a las facilidades que nos ofrecen deberías comenzar a usarlos, así que te proponemos seguir esta guía para conocer su funcionamiento.

Básicamente sirven de contenedores para el código de PHP, de modo que cuando creemos elementos del lenguaje como constantes, funciones o clases, se queden en un ámbito más restringido, evitando colisiones o conflictos de nombres con otros elementos que puedas crear tú más adelante, otras personas de tu equipo o incluso otros desarrolladores.

Lo primero sería aclarar que en la página de PHP tienen una estupenda guía para comenzar con los namespaces. Además está traducida al español, por lo que te recomendamos tenerla a mano: Namespaces en la documentación oficial.

En este artículo pretendemos aclarar algunas cosas básicas y otras adicionales, a la vez que te ayudamos con nuevos ejemplos y explicaciones que puedan complementar la documentación oficial.

Para qué sirven los espacios de nombres

Como hemos dicho, sirven para organizar el código, de manera que los nombres que nosotros reservemos a la hora de crear clases o funciones no entren en conflicto con los que hayan podido, o puedan en el futuro, crear otras personas.

Por ejemplo, imagina que tienes una clase que se llama "Seguridad" que se encarga de validar usuarios en tu aplicación para saber si están correctamente autenticados en el sistema. Es posible que otras personas, ya sea en tu mismo proyecto, o en otras librerías que puedas llegar a utilizar, hayan imaginado ese mismo nombre para otra clase, por ejemplo una clase que se encarga de impedir que se acceda a los recursos situados dentro de una carpeta sin los permisos necesarios.

Como no puede haber en el sistema dos clases con el mismo nombre, si necesitases trabajar con ambas clases dentro de un proyecto, encontrarías que PHP te da un mensaje de error. Pero bueno, esto nos puede ocurrir con otros elementos más sencillos, como funciones. Imagina que tienes una función validar_entero() y más adelante otra persona se le ocurre el mismo nombre para una función en otra parte del código, ambas funciones entrarían en conflicto, pues deberían tener nombres distintos.

Hasta la creación de los namespaces, para evitar colisiones de nombres, los desarrolladores estaban obligados a ser un poco imaginativos con los nombres que ponían a sus piezas de software, creando nombres extra largos para sus clases, evitando así que otras personas en el futuro pudieran usar esos mismos nombres.

Obviamente, esa solución no era la mejor, así que PHP incorporó los espacios de nombres, que nos permiten reservar nombres para las funciones, clases, interfaces, traits, constantes, etc, que solo tienen validez en cierto namespace. Al crear una librería, colocarías tus funciones dentro de un espacio de nombres, de manera que otros desarrolladores puedan usar los mismos nombres de piezas de software sin que colisionen, por estar en distintos espacios de nombres.

Símil de los namespaces y el sistema de ficheros de tu ordenador

Creo que este símil hace muy fácil entender qué son los namespaces y cómo funcionan, pues nos apoyamos en algo que todo el mundo usamos, que es el sistema de carpetas y archivos de tu disco duro.

En tu ordenador los archivos están dentro de carpetas y dentro de éstas hay a su vez otras carpetas que tienen otros archivos. Una carpeta de tu ordenador se comporta como si fuera un espacio de nombres o namespace de PHP.

Por ejemplo, no puede haber dos archivos con el mismo nombre en la misma carpeta o directorio. Pero sí puede haber dos archivos con el mismo nombre que están en distintos directorios.

Es tan sencillo como eso, los espacios de nombres son como carpetas de tu disco duro, que en lugar de contener archivos contienen funciones, clases, etc. Esas clases pueden tener cualquier nombre sin colisionar con otros códigos que estén en un espacio de nombres distinto.

Cómo declarar un espacio de nombres en PHP

El concepto, como has podido ver, es muy sencillo de entender. Ahora solo falta ver la sintaxis con la que PHP define los espacios de nombres.

Cuando estás creando un archivo que tiene una serie de código que quieres situar en un espacio de nombres, tienes que indicarlo al principio del código del fichero.

Indicas el namespace de esta manera:

<?php
namespace Deswebcom;

A partir de esa línea puedes escribir cualquier tipo de código, donde cada uno de los elementos declarados se quedarán en el espacio de nombres definido.

Tienes que asegurarte que:

1) La declaración del espacio de nombres sea la primera línea de tu código fuente. Y como código fuente entendemos tanto código PHP como código HTML.

Por ejemplo, esto no funcionaría:

<?php
echo "probando";
namespace Deswebcom;

Recibirás un error fatal como este: Fatal error: Namespace declaration statement has to be the very first statement in the script.

Del mismo modo, tampoco podrás hacer algo como esto:

<html>
    <head>
<?php
namespace Deswebcom;

2) En un espacio de nombres se pueden engloban:

  • Constantes
  • Funciones
  • Clases y otros elementos de programación orientada a objetos, como interfaces, traits o clases abstractas.

Por tanto las variables globales que creas en un namespace se van al ámbito global. Es decir, si dentro de un archivo donde has declarado estar en un espacio de nombres usas variables sueltas (sin ser locales a funciones o métodos, osea, variables globales de toda la vida), esas variables se quedan en el ámbito global.

Siguiendo con la declaración de nuestro primer namespace, podemos ver el código completo de un archivo con su espacio de nombres.

<?php
namespace Deswebcom;

const PI = 3.14;
function avisa(){
    echo "Te estoy avisando";
}
class MiClase{
    public function probando(){
	echo "Esto es una prueba";
    }
}

Ese código lo meterás en un archivo de tu proyecto, por ejemplo "primer-namespace.php".

Nota: La localización donde lo pongas ese archivo, o su nombre en si, es indiferente. Es decir, por el hecho de haber definido un namespace no estás obligado a colocar el código fuente en una ruta determinada. Aunque como veremos más adelante, muchos programadores con base en las buenas prácticas colocan los archivos del espacio de nombres en carpetas que tienen los mismos nombres que el namespace declarado.

Cómo usar un espacio de nombres

Ahora que ya tenemos nuestro primer namespace vamos a usarlo en otro archivo aparte.

Primero tendrás que incluir el archivo (aquel donde tienes el código de tu namespace), para poder usarlo.

include "primer-namespace.php";

Ahora PHP conoce ese código, está en un namespace y su uso será distinto que si hubieses colocado todos esos miembros en el ámbito global, pero al menos ya puedes usarlo. Ahora bien, la manera de usar aquellos elementos del namespace puede tener diversas alternativas que veremos a continuación:

a) Colocar la ruta completa del namespace cuando nos referimos a sus elementos:
Para hacer uso de los miembros de ese espacio de nombres usaremos la ruta completa dentro del namespace declarado.

Por ejemplo, en el namespace se declaró la constante PI, a la que podemos acceder de esta manera:

echo Deswebcom\PI;

Como puedes comprobar, comenzamos haciendo referencia al namespace, por su nombre, seguido de una contrabarra y el miembro al que quieres acceder, en este caso la constante PI.

De manera similar podríamos acceder a las funciones o las clases, a través de la mención del espacio de nombres donde están englobadas:

Deswebcom\avisa();

b) Declarar el uso de un miembro del namespace:
Otra alternativa útil es definir que vas a usar un miembro de un namespace, esto es, una constante, función, clase o similares para, a partir de ese momento, poder usarla como si fuera un miembro declarado de manera global.

use const Deswebcom\PI;
echo PI;

use function Deswebcom\avisa;
avisa();

use Deswebcom\MiClase;
$prueba = new MiClase();
$prueba->probando();

En este código primero se declara que se va a usar una constante del espacio de nombres.
Luego se declara que se va a usar una función y por último se declara que se va a usar una clase. A partir de ahí podemos hacer referencia a esos miembros sin referirnos a la ruta del namespace donde han sido creados, como si esa constante, función o clase que se hubiera declarado de manera global.

Fíjate que al usar una constante tenemos que informar "use const" y si es una función "use function", mientras que si es una clase usamos "use" a secas.

Nota: La posibilidad de declarar el uso de una función o constante de un namespace está disponible solo a partir de PHP 5.6.

Conclusión

Con esto ya conoces las bases sobre los espacios de nombres en PHP. Como introducción creo que está bastante bien y que ya tienes información suficiente para usarlos sin problemas. No obstante, el lenguaje PHP nos permite diversas otras alternativas de uso que estudiaremos en futuros artículos.

Autor

Miguel Angel Alvarez

Miguel es fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Comenzó en el mundo del desarrollo web en el año 1997, transformando su hobby en su trabajo.

Compartir

Comentarios

Michi

28/6/2015
Comenzando a entender namespaces
Hola, me ayudo mucho este post.

Podrias ayudarme a entender la forma de utilizar un metodo dentro de una clase que pertenece a un namespace utilizando "Clase::metodo()"?

Gracias de antemano!

ernestosoto

14/7/2015
Gran post! realmente interesante el uso de los namespaces
Como herramienta de organización de código hay que quitarse el sombrero y felicitar a los de PHP, no solo por las capacidades, sino también por la sencillez de los namespaces.

León

17/7/2015
Operador ::
Realmente es el operador :: para acceso a miembros estáticos, el uso sería el mismo q ya conoces.

NameSpaceClase::metodo()

sergio alberto

03/10/2015
gracias me sirvió para cakephp
Me salia error de Fatal error: Namespace declaration statement has to be the very first en cake php ya que deje un salto de linea de linea al principio del php. gracias a esto su solucionar mi error.

Victor

27/1/2016
Muy buen artículo
Ayuda a entender mejor después de leer la documentación oficial.

Gracias

Augusto

04/2/2016
Buenisimo!
Excelente post, me has sacado de un pocoton de dudas que tenía de los namespace que me daban tan duro.

Saludos !

Afah

07/5/2016
:)
Buen post , gracias

Camilo Calderón

11/4/2017
Pregunta con Include, require
Muchas gracias por el Post, tengo una pregunta ¿es necesario usar include o require para que funcione?