Hablemos de Namespace, lo básico

By | 22 Noviembre, 2016

Definición

Carpetas organizadasEmpecemos por el principio, ¿qué son los namespace? La manera más sencilla de entender ese concepto es haciendo una metáfora. Imaginemos que nuestro código está impreso en cientos de hojas, estas las agrupamos por áreas: bases de datos, manipulación de texto, scraping, clases, etc. Los grupos de páginas los guardamos en carpetas identificadas. Así pues, hemos organizado nuestra información y podremos conseguirla fácilmente. Pues bien, las carpetas, serían nuestros namespace (en su forma más básica). Si pensamos un poco, nos damos cuenta de que un namespace no es otra cosa que una manera de clasificar o diferenciar información, podríamos decir que son una manera práctica y sencilla de encapsular nuestro código.

Contexto

The Powerd CordRegresemos al código de alguna de nuestras aplicaciones y veamos la siguiente situación. A medida que el código de nuestro proyecto crece podríamos encontrarnos conque empezamos a repetir los nombres de nuestras funciones, de las clases y/o de las constantes que definimos, esto podría ponerse peor si al proyecto le agregamos código pertenecientes a librerías y/o frameworks de terceros. Tenemos entonces un problema serio, funciones, definiciones de clases y constantes con nombres duplicados. Veamos un ejemplo que, seguramente, muchos hemos vivido:

Al intentar ejecutar ejemplo_01.php en nuestro navegador, tendremos un error fatal como éste:
Fatal error: Cannot redeclare Suma() (previously declared in /hostlocal/namespace/funciones1.php:2) in /hostlocal/namespace/funciones2.php on line 2

Antes de que existieran los namespace, eso lo solucionábamos de una manera sencilla. Podíamos usar un prefijo en los nombres de nuestras funciones: prefijoMiFuncion() o podíamos usar nombres largos y descriptivos: NombreDeFuncionLargoYDescriptivo() o mejor aún, podíamos usar ambas cosas: prefijoNombreDeFuncionLargoYDescriptivo() y así nos quitábamos esos dolores de cabeza… ¡Ya va, ya va, ya va, yaaaa vaaaaa! ¿En serio solucionábamos el problema?

No le demos más vueltas a esto, los namespace llegaron en su momento para quitarnos estos y otros dolores de cabeza. Nos permiten evitar el uso de prefijos o identificadores larguísimos en nuestro código. Además, nos dejan organizar nuestro código de una manera lógica e, inclusive, nos facilitan la implementación de autoloaders, aunque esa es harina de otro costal.

Nuestro primer namespace

Siguiendo el ejemplo anterior, empecemos a usar los namespace y solucionemos ese problema. ¿De qué manera, bueno, veamos el siguiente código:

¡Todo funciona! ¿cierto? En nuestro navegador podemos ahora ver algo como esto:
Suma en funciones1ns.php: 30
Suma en funciones2ns.php: 60

Como podemos ver, ya no tenemos el error de colisión de nombres y nuestro código se ejecutó sin mayores inconvenientes. Revisemos ahora el código y veamos que ocurre, detallemos entonces:

  1. namespace <NombreDelNamespace>, es lo primero que escribimos al inicio de nuestro script. Esto es así, porque namespace debe ser siempre la primera instrucción cuando los estamos implementando. Pueden ver que luego de nombrado el namespace, colocamos una llave. Esto es opcional, pueden usarlos sin la llave y todo funcionará sin mayores problemas.
  2. Siguiendo la instrucción namespace, escribimos todo el código que queramos, funciones, clases, procedimientos, etc.
  3. Para usar la función de ejemplo Suma() en nuestro código, referenciamos el namespace correspondiente seguido de un back slash (\) y el nombre de la función y sus parámetros.

¡Ya hemos usado namespace ! Como pueden ver, no es algo difícil. Ahora bien, sería ideal si ahondamos un poco más en esta práctica funcionalidad de nuestro amado PHP y vemos usos más avanzados y buenas prácticas de su implementación en nuestro código.

Usando Alias

Siguiendo con nuestro ejemplo, resulta que debemos usar una vez la función Suma() definida en nuestro script funciones1ns.php y un montón de veces la función Suma() definida en nuestro script funciones2ns.php. Al ocurrir esto, podríamos encontrarnos con algo así (y que a nadie se le ocurra pensar en ciclos, ese no es el problema):

Si ejecutan el ejemplo, verán que todo sigue funcionando a la perfección, el problema es que nuestro código se ha convertido en un montón de horribles referencias al namespace Funciones2 y la verdad no es un código elegante. Para evitar tales cosas existen los alias. ¿Cómo es eso, cómo lo usamos? En el siguiente ejemplo, se muestra claramente la manera:

Observen que ahora hacemos uso de la instrucción use <namespace> as <alias>. En base a nuestro código de ejemplo, le decimos a PHP que haga uso del namespace Funciones2 y le asigne el alias fn2: use Funciones2 as fn2. De esa manera, PHP reconocerá fn2\ como una llamada al namespace Funciones2 y ejecutará el código correspondiente. Eso no sólo simplifica nuestro código, sino que lo hace más elegante, minimalista. ¡Vamos, que escribir código es un arte tanto como una ciencia! 😉

NOTA: Podemos crear más de un namespace dentro del mismo script. Sin embargo, NO es una buena práctica, procura evitarlo.

Subnamespaces

Hagamos una pequeña pausa y vayamos al principio, allá donde estaban nuestras carpetas con nuestro código, ¿lo recuerdas? Bueno, imagina ahora que en la carpeta de clases estamos escribiendo no una ni dos, sino tres clases para diferentes componentes de una aplicación. Podríamos meter cada clase en una carpeta, por ejemplo. O podríamos usar divisores a efectos de que cada una de nuestras clases se mantenga en la misma carpeta pero sin mezclarse. Como dice el viejo refrán: Juntos pero no revueltos.

Bien, usando namespace podemos hacer eso mismo y la manera es muy sencilla. Sigamos con nuestras tres clases y veamos como podemos hacerlo con el código de ejemplo:

Si observas un poco, podrás darte cuenta que hemos declarado 3 clases: Atreides, Harkonnen y Corrino. Cada una de estas clases puede distinguirse y separarse de sus «hermanas» gracias a que sus namespace  son distintos y, además, hemos agregado un subnamespace a cada una. Nuestros «separadores» nos permiten entonces dejar todas nuestras clases en la misma carpeta «Clases». De hecho, sería ideal que cada archivo de clase estuviera en su propia carpeta de esta manera, si usamos autoloaders, el trabajo sería mucho más sencillo de realizar. Llamar a estas clases, sería un trabajo que podría resultar divertido. Usemos para nuestro ejemplo a las clases Atreides y Harkonnen y veamos todo lo que hasta ahora hemos visto.

Como verás, en ese último ejemplo, usamos los archivos de clases que se encontraban en las carpetas «atreides» y «harkonnen» de nuestro proyecto. Por supuesto las rutas son ficticias y sólo fueron agregadas para que te hagas una idea de una estructura de directorios y de la manera en que esta puede ser útil para la organización del código de nuestra aplicación. Al mismo tiempo, usamos los alias de los namespace  a efectos de que el código sea más limpio y por último, usamos los subnamespaces para «diferenciar» el origen de una y otra clase.

Conclusión

Para finalizar, sólo me resta agradecer que hayas llegado a éste punto, espero que este pequeño y sucinto tutorial te haya resultado útil y que puedas así iniciarte (si ya no lo has hecho) en el uso y aprovechamiento de esta práctica característica de PHP.

No dejes de preguntar y comentar. ¡Ah!, si quieres saber más de nosotros y participar en las conversas y discusiones sobre PHP que siempre tenemos, puedes unirte a nuestro canal en Telegram, desde tu teléfono móvil o tu PC: PHP.ve

  • Súper sencillo de digerir. Muy buen post.

  • Jonathan Duran

    Excelente