Primeros Pasos con Namespaces en PHP

php-namespaces

Voy a traducir al español este artículo de Craig Buckler que me parecio una buena introducción a los namespaces de php.

Porqué debo usar Namespaces?

El tamaño de las librerias de PHP crece dia a dia, y tambíen incrementa el riesgo accidental de definir una clase o una función que hubiese sido declarado antes. El problema  se complica cuando tu intentas agregar componentes de terceros o plugins y en cualquiera de los dos tengan una clase “Base de Datos” o una clase “Usuario”.

Hasta ahora la única solución habia sido tener nombres clase/función. Es decir, WordPress utiliza prefijos para cada nombre “WP_”. Zend Framework usa nombres descriptivos que resultan largos nombres para clases como por ejemplo Zend_Search_Lucene_Analysis_Analyzer_Common_Text_CaseInsensitive.

El problema de colisión de nombres es resuelto con los Namespaces. Las constantes de PHP, clases y funciones pueden ser agrupadas como librerias namespaces.

Cómo se definen los Namespaces?

Por defecto, todas las constantes, clases y funciones son ubicadas en un espacio global,  asi se hacia antes del soporte para namespaces.

El código namespaces es definido usando la palabra clave namespaces en el inicio del archivo PHP. Debe ser el primer comando (con la excepción de declare) y un código que no sea PHP, HTML o espacios en blanco pueden preceder el comando.

<?php
// define this code in the 'MyProject' namespace
namespace MyProject;
 
// ... code ...

El código que sigue asigna como namespaces “MyProject”. No es posible  definir mas namespaces en el mismo bloque de código ( solo el último se reconocerá). Como sea, tu puedes definir diferentes namespaces en el mismo archivo.

<?php
namespace MyProject1;
// PHP code for the MyProject1 namespace
 
namespace MyProject2;
// PHP code for the MyProject2 namespace
 
// Alternative syntax
namespace MyProject3 {
	// PHP code for the MyProject3 namespace
}
?>

Aunque esto es posible, se aconseja no hacerlo, para mantener el orden en la definición de un único namespaces por cada archivo.

Sub-namespaces

PHP permite definitir jerarquicamente  namespaces que pueden ser subdivididas. Los Sub-namespaces pueden ser separados con la barra () por ejemplo.

  • MiProyectoSubNombre
  • MiProyectoBaseDatosMySQL
  • NombreCompañiaMiProyectoLibreriaCommonWidget1

Llamados a código Namespaces

En este archivo llamada lib1.php,  vamos a definir, una constante, una función  y una clase como AppLib1 namespace:

lib1.php

<?php
// application library 1
namespace AppLib1;
 
const MYCONST = 'AppLib1MYCONST';
 
function MyFunction() {
	return __FUNCTION__;
}
 
class MyClass {
	static function WhoAmI() {
		return __METHOD__;
	}
}
?>

Nosotros podemos ahora uncluir el código en otro archivo PHP, como sigue.

myapp.php

<?php
header('Content-type: text/plain');
require_once('lib1.php');
 
echo AppLib1MYCONST . "n";
echo AppLib1MyFunction() . "n";
echo AppLib1MyClass::WhoAmI() . "n";
?>

No se han definido namespaces en myapp.php, entonces el código existe en el espacio global. Cualquier referencia directa a MY CONST, MyFunction o MyClass fallarán porque existen en el namespaces AppLib1. Para llamar el código lib1.php, puede agregar el prefijo AppLib1 para definir nombres debidamente cualificados. El siguiente resultado es la salida que cargamos en myapp.php.

AppLib1MYCONST
AppLib1MyFunction
AppLib1MyClass::WhoAmI

Nombres debidamente cualificados pueden ser algo largos, pero son obvio los beneficios en contra de definir nombres largos para clases App-Lib1-MyClass.

Artículo en Inglés