Пространства имен - действительно все что полезный в платформах?

Насколько я могу сказать, единственная причина, у нас есть пространство имен в PHP, состоит в том, чтобы решить проблему классов (+ функции и константы) сталкивающийся с классами других того же имени.

Проблема состоит в том, что большинство платформ устанавливает свою автозагрузку и иерархию файловой системы для отражения названий классов. И никто на самом деле не требует () s или больше включает () s файлы.

Таким образом, как пространство имен помогает этому кто-либо? Любой, из которого класс загружается базирующийся прочь, он - имя:

new Zend_Db_Table_Rowset_Abstract;

или прочь это - пространство имен

new Zend\Db\Table\Rowset\Abstract;

Так или иначе я застреваю только со способностью создать один класс с этим именем.

/var/www/public/Zend/Db/Table/Rowset/Abstract.php

ОБНОВЛЕНИЕ я не уверен, что понимаю через.

Даже если я создал два файла с тем же class Zend\Db\Table\Rowset\Abstract в них я все еще не мог использовать их вместе, так как они оба требуют того же пространства имен. Я должен был бы изменить их имена пространства имен, который является тем, что мы уже делаем!

Это оставляет меня живо, что единственное использование для пространств имен является именами функций. Теперь у нас может наконец быть три функции все названные тем же самым!

Или ожидайте, я забыл, что Вы не можете сделать этого ни один, так как каждый требует префикса пространства имен!

a\myfunction();
b\myfunction();
c\myfunction();

Взятие примера ircmaxell:

$model = new \Application\Model\User;
$controller = new \Application\Controller\User;

Как то, что несколько отличающийся, чем без?

$model = new Application_Model_User;
$controller = new Application_Controller_User;

Это - также аккуратная звучащая функция - но что она действительно делает для нас?

use \Application\Model\User as UserModel;
use \Application\Controller\User as UserController;

$foo = new UserModel;
$bar = new UserController;

Теперь у Вас не может быть класса под названием 'UserModel', так как у Вас есть установка пространства имен для того термина. У Вас также все еще не может быть двух классов, названных под тем же псевдонимом.

Я предполагаю, что хорошая вещь состоит в том, что можно переименовать длинное Zend_Db_Table_Rowset_Abstract

use Zend_Db_Table_Rowset_Abstract as RowAbstract;

продвижение к беспорядку разработчика о том, где несуществующий класс "RowAbstract" определяется и прибывающий из в системе.

12
задан Xeoncross 30 June 2010 в 22:43
поделиться

7 ответов

У меня сложилось впечатление, что пространства имен используются в культовом программировании . Потому что он новый, его привыкают как сумасшедшие. Глубоко вложенные пространства имен, как в Doctrine2, не добавляют дополнительной защиты от конфликтов имен. И совершенно очевидно, что \ nested \ name \ space используются только для достижения сопоставления 1: 1 с именами каталогов / файлов. Явно запах кода.

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

В любом случае, возможность переименовывать классы при импорте пространств имен - это большой плюс. Это полезно, когда действительно приходится смешивать противоречивые определения.И синтаксис пространства имен можно просто добавить, как только возникнет реальный конфликт имен. (Я не вижу необходимости сразу реализовывать пространства имен, когда конфликты имен настолько редки и для большинства проектов проблема является чисто вымышленной.)
Если вы делаете это только при необходимости, неудобный синтаксис пространства имен никогда даже не поднимет свою уродливую голову. Если есть только один уровень пространства имен для импорта, вы можете просто использовать namespace1 \ Class как LocalName и не сворачивать приложение с каким-либо синтаксисом namespace1 \ Class . (Тем не менее, лучше не использовать слишком общие имена классов в пространствах имен.)

13
ответ дан 2 December 2019 в 03:43
поделиться

Фактически, вы можете создать более одного класса с одним и тем же именем

Предположим, у вас есть 2 класса:

\Application\Controller\User

и

\Application\Model\User

Вы не можете импортировать оба в один файл без псевдонима, но вы все равно можете определите и то, и другое одинаково:

$model = new \Application\Model\User;
$controller = new \Application\Controller\User;

Плюс вы можете импортировать и использовать псевдоним:

use \Application\Model\User as UserModel;
use \Application\Controller\User as UserController;

$foo = new UserModel;
$bar = new UserController;

Так что это действительно очень мощный инструмент, поскольку он позволяет вам называть классы, как вы хотите (и ссылаться на них произвольными именами внутри вашего кода). Единственные правила - это зарезервированные ключевые слова ... См.: http://www.php.net/manual/en/language.namespaces.importing.php

13
ответ дан 2 December 2019 в 03:43
поделиться

В вашем примере фреймворка Zend вы можете добавить пространство имен Zend; в начало каждого файла класса, удалить Zend_ из всех ваших классов и функций, и вам (в основном) больше не нужно беспокоиться о конфликтах имен. Ваш класс Zend_Date можно переименовать просто как Date , не мешая встроенным классам дат. Между тем, пользователи вашего фреймворка могут написать Zend \ Date вместо Zend_Date , который больше не вводится, но теперь у них есть несколько других вариантов для более легкого доступа к классу.

3
ответ дан 2 December 2019 в 03:43
поделиться

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

Например, в Java (поскольку пока мало кто использует пространства имен в PHP, мне не удалось найти подобных примеров). Вот варианты, которые появляются для List в моей IDE (Eclipse):

java.util.List
com.ibm.toad.utils.Strings.List
com.ibm.ws.objectManager.List
com.ibm.ws.webcontainer.util.List
java.awt.List

В этом случае я действительно не понимаю, почему они не могли просто сохранить java.util.List в качестве только List и, например, переименованный java.awt.List в ScrollingList , который на самом деле описывает, что это такое, делает более очевидным, что это элемент графического интерфейса , и избегает столкновения.Я бы предпочел набрать более длинное и информативное имя класса, чем иметь дело с этим.

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

2
ответ дан 2 December 2019 в 03:43
поделиться

Вы действительно пытаетесь создать новый класс с именем Zend_Db_Table_Rowset_Abstract ?

Более вероятный сценарий состоит в том, что у вас есть локальный класс, называемый чем-то общим, например Date, Project, User, или что-то подобное, или у вас есть фреймворк, в котором уже есть эти классы. Имея пространства имен, не должно быть никаких коллизий.

В web2project мы только что добавили поддержку пространства имен в v2.0 (но нам не нужен PHP 5.3), потому что наши классы, такие как Date, DBQuery, Mail и некоторые другие, довольно легко сталкивались с разными вещами. Хотя у нас нет намерения добавлять в систему внешний фреймворк, кто-то другой мог бы довольно легко, если бы захотел.

Есть ли менее подробные способы решения проблемы? Потенциально ... но это сработало в мире Java с их кучей библиотек, так что это не совсем новое пространство.

1
ответ дан 2 December 2019 в 03:43
поделиться

Возможно, если вы немного расширите свои взгляды :)

"Насколько я могу судить, единственная причина, по которой в PHP существует пространство имен, это решение проблемы столкновения классов (+ функций и констант) с другими одноименными классами." - Да, это огромная проблема, которая создавала проблемы в течение многих лет в каждом языке, где нет пространств имен - все создают классы Database, Date, URL и т.д., и это решает ее :)

"Проблема в том, что большинство фреймворков настраивают свою автозагрузку и иерархию файловой системы так, чтобы отразить имена классов. И никто больше не требует() или включает() файлы." - Ну, на самом деле, часто требуют, просто потому что некоторые распространенные фреймворки были вынуждены придумать практику, чтобы обойти отсутствие пространств имен, не означает, что эти обходные пути или хаки должны аннулировать "реальное" решение проблемы для всех :)

follow?

1
ответ дан 2 December 2019 в 03:43
поделиться

Похоже, вы не поняли, что имена пространств имен являются составными. Т.е. вы можете сделать:

use Zend\Db\Table as Table;
$a = new Table\Rowset();
$b = new Table\Fields();

и т.д. Т.е. это позволяет вам определить ваш контекст (или набор контекстов) и затем ссылаться на него. Конечно, вы можете сократить его до одного имени, но это не обязательно. Это btw также помогает с общими именами классов - Fields может быть слишком общим, но Table\Fields меньше.

Другое дело, если вам надоели таблицы Zend и вы хотите написать свои собственные классы таблиц Db, вы меняете вышеуказанное на:

use My\Own\Table as Table;

и весь код теперь использует ваш набор классов. Кроме того, вы не определяете класс по длинному имени. Вот что вы делаете:

namespace Zend\Db\Table;
class Rowset exteds AbstractRowset {
    function doStuff() {
       $this->fields = new Fields();
       if($this->fields->areBroken()) {
          throw Exception("Alas, fields are broken!");
       }
    }
 }

Обратите внимание, что здесь мы использовали 4 класса из пространства Zend\Db\Table, но ни разу не ссылались на них по длинному имени. Конечно, в реальной жизни это будет не так просто :), но идея в том, что код - особенно библиотечный - имеет тенденцию быть локализованным - т.е. если вы находитесь в Db части библиотеки, есть шанс, что вы используете классы, связанные с DB гораздо чаще, чем классы LDAP или PDF. Расстановка имен позволяет вам использовать эту локальность, используя более короткие имена.

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

7
ответ дан 2 December 2019 в 03:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: