2011-12-22 6 views
10

Я изучал использование пространств имен в PHP некоторое время назад, но недавно посмотрел на проект, который использовал ключевое слово use, а затем обратился к объекту с расширением имен, как если бы они были нормальными без пространства имен.Является ли это хорошим способом использования пространств имен в PHP

Мой вопрос, является ниже код правильно, это hŠ файл index.php и использует пространство имен MyLibrary\Base тогда использует use принести в \MyLibrary\Registry\MyLibrary\User и \MyLibrary\Request

Затем он может получить доступ к любому из этих объектов, не подвергая там пространство имен перед ними, поэтому фактический код ниже раздела use выглядит как обычный файл php-файла с предварительным пространством имен.

Я спрашиваю, если вы используете пространства имен? Или я чего-то не хватает?

файла: 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... 
    } 
} 
?> 

Файл: registry.class.php

<?php 
namespace MyLibrary\Registry; 

class Registry 
{ 
    public $user; 

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

ответ

5

Да. Объект use импортирует имя класса или пространства имен в текущую область. Для того, чтобы написать все, что короткие является причиной, почему PHP-разработчики реализованы пространств имен;)

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

а) сделать все более удобным для чтения, потому что его гораздо короче, чем Vendor_Package_Foo_Bar_XyzClass и б) вы можете обменять классы для использования очень быстро.

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

Это потрясающе и заставляет меня хотеть использовать пространства имен сейчас, прежде чем я действительно не захотел, потому что я думал, что мне придется иметь дело с злым, выглядящим '\\' разделителем на всем протяжении моего кода. Это напоминает мне Python, как вам нужно импортировать библиотеки – JasonDavis

+0

На самом деле, я бы сказал, это похоже на C#, где они используют ... 'using System;' 'using System.Collections.Generic;' и т.д ... Я просто не понимали, что они импортируют пространства имен. Я также могу видеть, насколько лучше он будет выглядеть с точкой/периодом в качестве разделителя NS. – JasonDavis

+0

Быстрый вопрос, как вы опубликовали 'use \ MyFirstNamespace \ Foo как Bar;' Я знаю, что вы можете изменить имя, подобное этому, но в коде, который я видел, они сделали это как мой пример ... 'use \ MyFirstNamespace \ Foo ; 'и тогда доступ только с помощью' Foo' - это возможно? Заметьте, что я не установил, так же, как и все остальное, или вы должны были бы установить его так: 'use \ MyFirstNamespace \ Foo as Foo;'? – JasonDavis

3

Namespacing имеет много преимуществ.

Первое, что вы можете повторно использовать имена методов и даже имена классов, если это имеет смысл, если они существуют в другом пространстве имен. Пример:

namespace \myNamespace\data\postgres; 

class DataBase extends \PDO 
{ 
} 

namespace \myNamespace\data\mysql; 

class DataBase extends \PDO 
{ 
} 

Можно даже использовать повторно имена, которые, как правило, зарезервированы для PHP функций

namespace \myNamespace\dir; 

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

Все это предназначено, чтобы сделать его проще использовать код из разных источников вместе, не заботясь об именовании конфликты. При условии, что программисты достаточно учтивы, чтобы соблюдать несколько простых правил, тогда шансы на конфликты имен значительно сокращаются. Фактически, в значительной степени единственное правило, в котором вам нужно заботиться, чтобы избежать конфликтов имен, - это сделать первый уровень вашего пространства имен своим. Например, используйте название вашей компании или какой-либо другой способ идентифицировать вас как уникального поставщика в качестве первого уровня вашего пространства имен, и все должно быть хорошо.

Например, я использую \ gordian как корневое пространство имен во всем коде, который я пишу, поскольку тогда я могу называть мои классы под этим пространством имен чем угодно, не беспокоясь о том, что они сталкиваются с кем-то, кто выбрал другое корневое пространство имен.

Итак, что случилось с соглашениями PEAR, вы можете спросить? За ними следуют многие проекты, в том числе популярная структура Zend.

Ответ - это имена, которые очень быстро становятся очень громоздкими. Например, Zend, как следует из соглашения PEAR, использует своего рода псевдо-именное пространство. Все классы в коллекции начинаются с Zend_ и с каждым уровнем иерархии класса добавляют дополнительную часть имени.
Ze В результате вы получаете имена классов, такие как Zend_Db_Adaptor_Abstract и Zend_Dojo_Form_Decorator_TabContainer.

Если Zend обновит свою инфраструктуру для использования пространств имен (что, как мне сказали, происходит с Zend Framework 2.0), то они будут заменены на \ Zend \ Db \ Adapter \ Abstract и \ Zend \ Dojo \ Form \ Decorator \ TabContainer. Так что, спросите вы? Ответ заключается в том, что вы можете использовать их для более коротких имен с ключевым словом Use, как вы уже видели. Это означает, что вам не нужно писать полное имя класса, но только в отношении того, что вы наложили.

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

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

Более того, если вы уже в заданном пространстве имен, то вам даже не придется использовать использовать ключевое слово, чтобы получить доступ к другим пунктов в пределах одного пространства имен с коротким именем, как это происходит автоматически вы в этом случае. Для разработчиков фреймворков это огромный развал.

Например, вы можете увидеть что-то вроде подзаголовка в Zend Framework 2 (поскольку я никоим образом не работаю над этим, это просто пример, а не настоящий источник 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 
{ 
} 

Есть и другие преимущества, такие, как это делает автопогрузчики до смешного просто сделать (при условии, структура пространства имен отображает именно на вашу структуру каталогов файловой системы).

Пространства имен могут показаться одной из тех функций, которые на самом деле не очень важны или, по-видимому, даже не имеют смысла, но после их использования на некоторое время их полезность вдруг станет очень очевидной.

Смежные вопросы