2011-12-22 12 views
10

? He estudiado el uso de espacios de nombres en PHP hace un tiempo pero recientemente mirando un proyecto que usó la palabra clave use y luego accedí al objeto namespaced como si fueran normales sin espacio de nombres.¿Es esta una buena manera de utilizar Namespaces en PHP

Mi pregunta es, es el siguiente código correcto, hs un archivo index.php y utiliza el espacio de nombres MyLibrary\Base después utiliza use para traer \MyLibrary\Registry\MyLibrary\User y \MyLibrary\Request

A continuación, puede acceder a cualquiera de estos objetos sin poner allí espacio de nombres delante de ellos, por lo que el código real debajo de la sección use se parece a un archivo php de nombres previos normal.

Pregunto si así es como usa espacios de nombres? ¿O me estoy perdiendo algo?

del archivo: index.php

<?php 
namespace MyLibrary\Base; 

use \MyLibrary\Registry; 
use \MyLibrary\User; 
use \MyLibrary\Request; 


class Base 
{ 
    public $registry; 

    function __construct($registry) 
    { 
     $this->registry = $registry; 
     $this->user = New User; 
     $this->request = new Request; 
     # code... 
    } 
} 
?> 

del archivo: registry.class.php

<?php 
namespace MyLibrary\Registry; 

class Registry 
{ 
    public $user; 

    function __construct($user) 
    { 
     $this->user = $user; 
     # code... 
    } 
} 
?> 

Respuesta

5

Sí. La declaración use importa el nombre de clase o nombre de espacio en el ámbito actual. Para escribir todo lo que se corta es la razón, ¿por qué los PHP-desarrolladores implementaron espacios de nombres;)

namespace MyFirstNamespace { 
    class Foo {} 
} 
namespace MySecondNamespace { 
    use \MyFirstNamespace\Foo as Bar; 
    $foo = new Bar; 
} 

a) que hacen que todo sea más fácil de leer, porque es mucho más corto, que Vendor_Package_Foo_Bar_XyzClass yb) se pueden intercambiar las clases de usar muy rapido.

# use \MyFirstNamespace\Foo as Bar; // I don't like Foo anymore 
use \MyFirstNamespace\SimilarToFoo as Bar; 
+1

Esto es increíble y me dan ganas de usar espacios de nombres ahora, antes de que realmente no quisiera porque pensé que tendría que tratar con el mal aspecto del separador '\\' en todo mi código. Esto me recuerda a Python, la forma en que tiene que importar bibliotecas – JasonDavis

+0

En realidad, debería decir que es como C# donde usan ... 'using System;' 'using System.Collections.Generic;' etc ... no se dio cuenta de que estaban importando espacios de nombres. También puedo ver cuánto mejor se vería con un punto/período como el separador NS. – JasonDavis

+0

Una pregunta rápida, como la que publicó 'use \ MyFirstNamespace \ Foo as Bar;' Sé que puede cambiar el nombre de esa manera, pero en el código que vi lo hicieron como mi ejemplo ... 'use \ MyFirstNamespace \ Foo ; 'y luego acceder simplemente usando' Foo' ¿es esto posible? Tenga en cuenta que no configuré es como cualquier otra cosa o ¿TIENE que establecerlo así 'use \ MyFirstNamespace \ Foo como Foo;'? – JasonDavis

3

El espacio de nombres tiene muchas ventajas.

El primero es reutilizar nombres de métodos e incluso nombres de clases si tiene sentido siempre que existan dentro de un espacio de nombres diferente. Ejemplo:

namespace \myNamespace\data\postgres; 

class DataBase extends \PDO 
{ 
} 

namespace \myNamespace\data\mysql; 

class DataBase extends \PDO 
{ 
} 

Incluso se puede volver a utilizar los nombres que normalmente están reservadas para funciones de PHP

namespace \myNamespace\dir; 

function makedir() 
{ 
    if (// some condition is true) 
    { 
     \makedir(); 
    } 
} 

Todo ello con el fin de hacer más fácil el uso de código de fuentes diferentes entre sí sin tener que preocuparse por nombrar conflictos. Si los programadores son lo suficientemente cortés como para observar algunas reglas simples, entonces las posibilidades de conflictos de nombres se reducen enormemente. En realidad, prácticamente la única regla con la que debe preocuparse para evitar nombrar conflictos es hacer suyo el primer nivel de su espacio de nombres. Por ejemplo, use el nombre de su compañía, o alguna otra forma de identificarlo como un proveedor único como el primer nivel de su espacio de nombres y todo debería ser bueno.

Por ejemplo, utilizo \ gordian como el espacio de nombres raíz en todo el código que escribo, ya que puedo llamar a mis clases en ese espacio de nombre cualquier cosa que me guste sin preocuparme por colisionar con alguien que eligió un espacio de nombres raíz diferente.

Entonces, ¿qué hay de malo con las convenciones de PEAR, usted puede ser que pregunte? Muchos proyectos los siguen, incluido el popular marco Zend.

La respuesta es que los nombres se vuelven muy difíciles de manejar muy rápidamente. Por ejemplo, Zend, como sigue la convención PEAR, usa una especie de pseudo-namespacing. Todas las clases de la colección comienzan con Zend_ y con cada nivel de jerarquía de clase agregan una parte adicional al nombre.
Ze Como resultado, terminas con nombres de clase como Zend_Db_Adaptor_Abstract y Zend_Dojo_Form_Decorator_TabContainer.

Debería Zend actualizar su marco de trabajo para usar espacios de nombres (que me dicen que está sucediendo con Zend Framework 2.0) luego serían reemplazados por \ Zend \ Db \ Adapter \ Abstract y \ Zend \ Dojo \ Form \ Decorator \ TabContainer en su lugar. Entonces, ¿qué? ¿Podrías preguntar? La respuesta es que puedes asignarles nombres mucho más cortos con la palabra clave Usar, como ya has visto. Esto significa que no tiene que seguir escribiendo el nombre completo de la clase, sino solo en lo que se refiere a su alias.

use \Zend\Dojo\Forn\Decorator as Dec; 

$a = new Dec\TabContainer; // Not easy to do without namespaces! 

Más aún, si ya está en un espacio de nombres dado, entonces no siquiera tiene que utilizar la palabra clave use para acceder a otros elementos dentro del mismo espacio de nombres de un nombre corto, como sucede automáticamente tú en ese caso. Para los escritores de framework esto es un gran ahorro de tiempo.

Por ejemplo, es posible que vea algo como el siguiente en Zend Framework 2 (ya que no estoy trabajando en ello de ninguna manera, esto es solo un ejemplo y no de la fuente real de ZF2).

namespace \Zend\Db\Adaptor; 

class Postgres extends Abstract // We don't need to use \Zend\Db\Adaptor\Abstract here because it's in the same namespace already anyway 
{ 
} 

Hay también otras ventajas, tales como cargadores automáticos hace ridículamente fácil de hacer (siempre que su estructura de espacio de nombres asigna exactamente en la estructura de directorios del sistema de archivos).

Los espacios de nombre pueden parecer como una de esas características que no son realmente muy importantes, o que ni siquiera parecen tener sentido, pero después de usarlas por un tiempo su utilidad se volverá obvia de repente.

Cuestiones relacionadas