Pull to refresh

Comments 83

Хорошее нововведение, но ведь оно не решает проблемы затирания старых библиотек. Используя пространство имен мы практически гарантируем, что наш код не будет затерт, но совершенно не гарантируем, что наш код не затрет чужой код, не использующий пространство имен. Или я что-то не так понял?
!!! Прошу прощения, ответил ниже…
Если я правильно понял Вас, то могу выразится иначе — используя пространство имен, мы гарантируем существование наших библиотек (моего кода и стороннего) в абсолютно разных пространствах, что означает — вообще никто никого затирать не будет.
аааа… значит в Вашем примере function MyFunction() можно вызвать только как \App\Lib1\MyFunction() а просто MyFunction() — ничего не даст?
Именно!
Любая прямая ссылка на MYCONST, MyFunction или MyClass вызовет сбой, поскольку они существуют только в пространстве имен App\Lib1

То есть:
echo \App\Lib1\MyFunction()

И не иначе :-)
но никто не запрещает обращаться к MyFunction() в lib1.php просто через имя. Т.е. внутри пространства имён всё работает. А снаружи — снаружи обычно довольно редко вызываются объекты (функции, переменные, константы и т.д.) из пространства имён, так как новвоведение специально для библиотек
Можно импортировать пространство имен через use, и после этого вызывать как MyFunction.
UFO landed and left these words here
Не жаль… :-) Вы не обратили внимания, что это не одна статья, там три части. Во второй, которую я опубликую завтра утром, как раз идет речь и о use и о MyFunction.
Мм, первая статья об операторе namespace, вторая о use. Также можно написать целый цикл статей про функции работы с БД, там ведь непочатый край, первая статья про mysql_connect, вторая про mysql_select_db, третья про mysql_query… уж без обид :)
А что, идея однако! ;-) Надо бы автору написать, еще напишет!
UFO landed and left these words here
Практическую разницу между «WP_Function()» и «\WP\Function()» углядеть непросто.

Кое-кому, я уверен, покажется, что её почти и вовсе нéту…
Очень верно заметили. Ничего, на ошибках учатся, хотя я даже думал подчеркнуть этот «лишний» слэш :-)))
Не знаю.
например: «Пространство имён определяется блоком инструкций.… Внутри этого блока идентификаторы могут вызываться именно так, как они были объявлены.» — это довольно хорошо. Правда этого в статье не написано
На днях опубликую еще два перевода статей этого же автора — 2-ую и 3-ю часть.
Это стандартное поведение PHP кода если namespace не используется. В чем же достоинство namespace если он даже умеет работать так, как если бы его не было.
UFO landed and left these words here
Не стоит прогибаться под изменчивый Хабр. (почти ©)
UFO landed and left these words here
Пациент выздоравливает, уже начал цитировать расового еврейского Макаревича:)
Ну тут смысл несколько в другом если сделать ґ
use WP
То писать надо будет только Function()

Главное теперь, чтобы имена пространств имён ещё не совпадали
Верно! Вот во избежание этого автор и взывает:
будьте благоразумны, определяя только одно пространство имен для каждого файла...
UFO landed and left these words here
можно как в яве делать, используя в имени неймспейса написанные наоборот домены — \ru\site\Controllers например :)
Становиться удобно применять простарнства имён в больших проектах, в скромных это начинает приобретать склонность к преувеличению…
ага, скромнее надо быть =)
но обычно маленькие проекты иногда со временем перетекают в крупные
Мне честно говоря не очень нравится синтаксис этих неймспейсов. В некотором роде префикс был даже лучше, потому как WP_Function() — тут всего один символ разделения, а \WP\Function() — тут два. Кончено, это не сильный показатель, но лучше меньше да лучше. Более того тут прямые ассоциации с файловой системой, что опять же не будет украшать код. Сделали бы они точку типа WP.Function() тогда еще ничего (да я знаю, что точку нельзя использовать).
все-таки это уродство, использовать обратный слеш для разделения пространства имен.
вытащили бы палец из жопы и сделали бы по-человечески ::
:: занято
. занято
-> занято
| занято

какие еще предложения?

# — кстати, всё равно хотят отменять как комментарий :)

Понятно, что это изначальная ошибка при проектировании языка, но рушить всё уже поздно, обратная совместимость в любом случае при такой популярности языка нужна.
\ тоже занят — это типа спецсимвол экранирования
\n, \t всякие
Ну это только внутри строковых констант, да, приходится имя класса, если уж понадобилось, писать как «SomeSpace\\SomeSubSpace\\SomeClass», только когда это нужно? Только в случае если нужно составить имя класса динамически, причем вместе с пространством имен, не такой уж это частый случай, у меня в личных наработках на php 5.3 такой встречается единожды, для подключения контроллеров модулей, итого 2 лишних слеша на всю систему.
конечно, если у тебя нет — то ни у кого уж точно не будет…
это внутри "" и '' просто
MyNameSpace:::MyClass::staticMethod();
MyNameSpace:::MYCONST;
MyNameSpace:::myFunc();
MyNameSpace:::SubName:::blabla
Да ладно, хорошо бэкслэш, а не бэкспейс :)
Можно было бы хотя бы прямой слеш. Обратный как-то уж совсем…
Реализовать перегрузку :: так чтобы работало и для неймспейсов тоже не представляется таким уж сложным.
"/" — деление :)
"::" занято, и неоднозначности точно бы появились.
Ну так чем черт не шутит — подчеркивание не занято. Тогда бы всем стал очевиден смысл и удобство (если есть) затеи :)
подчёркивание можно использовать в теле идентификатора, так что тоже занято
Использовать хотя бы не обратный слеш, а прямой, т.к. обратный явно ассоциируется с экранированием символов.
UFO landed and left these words here
Я бы использовал тильду — WP~Function(); или «волнистую стрелку»: WP~>Function();
Идея «волнистой стрелки» не плохая, что-то новенькое, правда имхо не подходит именно для пространства имен.
Вот-вот, слава уродского языка останется за ПХП навсегда.
UFO landed and left these words here
он не уродский, а живой :)
Ну два разделителя тут не случайно, это особенность реализации пространств имен в PHP, попробую привести пример:
namespace SomeSpace;
WP\Function();

Вызовет SomeSpace\WP\Function, так как учитывается объявленное в файле пространство имен, чтобы вызвать функцию из другого пространства имен и нужен первый слеш, иже
namespace SomeSpace;
\WP\Function();

вызовет уже функцию WP\Function относительно корневого пространства имен. Или-же (я считаю это более правильным) — сделать так:
namespace SomeSpace;
use WP;
WP\Function();

Use импортирует заданное пространство имен в текущее, и соот-но члены этого пространства можно использовать без слеша.
Ну и вы забываете главное, представим себе более серьезную вложенность, в случае действительно большого проекта — вон из того-же Zend'а, например Zend_Navigation_Page_Mvc, без пространств имен так и придется его выписывать заново каждый раз, с пространствами:
use Zend\Navigation\Page\Mvc;
$a = new Mvc($options);

Собственно ради этого пространства имен и существуют :) так что экономия одного символа — имхо не аргумент :)
Ваш коммент привлекает желающих выразить свою антипатию к \(слэшу) как мух — г***о. Это обсуждалось тысячи раз на иностранных форумах, и на том-же хабре в каждом топике про пхп 5.3, зачем ещё раз поднимать снова набрасывать на вентилятор?
Значит, видимо, проблема людей волнует. Я на иностранных форумах не был, и неймспейсами как-то не интересовался (да и сейчас то не очень, нигде на наших серверах нету 5.3). ПОэтому увиденный backslash как разделитель действительно вызывает легкое подташнивание.
Ничего, привыкните, либо просто не будете использовать. Разработчики не собираются ничего менять.
Ну можно выпустить свой PHP с блекджеком и все такое :)
Ага. И компилить PHP из своих исходников на каждом серваке, на котором будет работать ваша система. Правда сервак должен быть выделенным, так как ничего другого кроме ваших систем на этом серваке работать не будет.
Я соглашусь с каментом выше — я так же не читаю иностранные форумы. Я лишь сравнил сушествующие префиксы с неймспейсами и сделал вывод о лучшем (имхо) по красоте и читаемости кода использованию последних. Почему у вас мой камент вызвал ассоциации с вентилятором я не знаю. Ну это не имеет значения — так как вы совершенно правы — никто ничего менять не будет. так что придется использовать в том варианте, который есть. Или не использовать.
Сколько раз тема поднималась, всё никак не привыкну к "\" разделителю. Не нравится, почему-то :(
Но нововведение полезное. Осталось дождаться теперь поддержки множественного наследования и ООП в php куда удобнее станет :)
Мне в голову не приходит где бы вы его применили это множественное наследование в веб-приложении на php, можно примерно описать?
Например, изобретал я свой мини-фреймворк велосипед, была система кэширования своя. Потом понадобилось использовать другую систему кэша с другим интерфейсом. Я сделаю адаптер. Вариант с множественным наследованием удобнее, чем вариант с методом-ссылкой, т.к. не нужно инстанцировать лишние объекты.
не будет множественного наследования, скорее всего будут traits.
Любопытная система. Местами напоминает import'ы из питона.
А примеси, по вашему, это что? Это когда модули включают в классы. Вы Рубин давно используете? :-)
А мне больше Grafts понравились, на мой взгляд они как-то более логичны.
Тем не менее, Вы можете определить различные пространства имен в одном и том же файле, например:
Так всё-таки namespace должен быть самой первой командой в файле или можно их указывать в произвольном месте?
Вы не зря обратили внимание, но и я не ошибся в переводе. Тут есть такая заковырка. Полагаю, высшей инстанцией в данном вопросе можно считать официальный PHP Manual. К нашей проблеме имеют отношение две страницы: Defining namespaces и Defining multiple namespaces in the same file.

Если, позволите, обойдемся без цитат — объясню своими словами.

1. Мы имеем четкое правило, что если мы вообще используем, хотя бы раз, в документе namespace, то мы обязаны поместить его в самое начало кода, даже перед комментариями и пробелом. Единственным позволенным исключением, является только declare.
  1. <?php
  2. namespace MyProject;
  3.  
  4. const CONNECT_OK = 1;
  5. class Connection { /* ... */ }
  6. function connect() { /* ... */ }
  7.  
  8. ?>
* This source code was highlighted with Source Code Highlighter.

!!! Даже это уже является ошибкой —
  1. <html>
  2. <?php
  3. namespace MyProject; // fatal error - namespace must be the first statement in the script
  4. ?>
* This source code was highlighted with Source Code Highlighter.

2. Если мы хотим применить к одной части нашего кода namespace, а другую оставить не помеченной, мы обязаны разместить помеченную часть в начале нашего кода (таки руководствуясь вышеизложенным пунктом 1.), а вторую специально отметить, пример:
  1. <?php
  2. namespace MyProject {
  3.  
  4. const CONNECT_OK = 1;
  5. class Connection { /* ... */ }
  6. function connect() { /* ... */ }
  7. }
  8.  
  9. namespace { // global code
  10. session_start();
  11. $a = MyProject\connect();
  12. echo MyProject\Connection::start();
  13. }
  14. ?>
* This source code was highlighted with Source Code Highlighter.

3. Ну и если мы, хоть это и не рекомендуется, желаем пометить две части нашего кода (или более) разными namespaces, это можно сделать двумя вариантами. Нежелательным и боле-менее приемлимым.

а) нежелательно, но валидно:
  1. <?php
  2. namespace MyProject;
  3.  
  4. const CONNECT_OK = 1;
  5. class Connection { /* ... */ }
  6. function connect() { /* ... */ }
  7.  
  8. namespace AnotherProject;
  9.  
  10. const CONNECT_OK = 1;
  11. class Connection { /* ... */ }
  12. function connect() { /* ... */ }
  13. ?>
* This source code was highlighted with Source Code Highlighter.

а) желательно и валидно:
  1. <?php
  2. namespace MyProject {
  3.  
  4. const CONNECT_OK = 1;
  5. class Connection { /* ... */ }
  6. function connect() { /* ... */ }
  7. }
  8.  
  9. namespace AnotherProject {
  10.  
  11. const CONNECT_OK = 1;
  12. class Connection { /* ... */ }
  13. function connect() { /* ... */ }
  14. }
  15. ?>
* This source code was highlighted with Source Code Highlighter.

Итак, namespace обязан быть самой первой командой в файле, но после него можно остальные указывать и в произвольных местах.
Спасибо за разжёвывание :) Фигурные скобки хорошие.
Но тогда в ваших примерах стоит убрать комментарии перед объявлениями пространств =)
Поверьте, в Ваших знаниях не сомневался. Решил детально расписать, поскольку уверен, что статью будут читать в том числе и начинающие, и именно разжевывание может им пригодиться.

Комментарии не обрабатываются компилятором и никак не влияют на программу, а только служат подсказкой и памяткой… Они имеют другой «вес», чем даже тот же пробел. Это даже не исключение.
Да нет, правда спасибо! Всё до пространств руки не доходили.

Насчёт комментария сказал из-за этого:
… то мы обязаны поместить его в самое начало кода, даже перед комментариями и пробелом.
Здорово! Это я ошибся… Ты прав!
Может, не стоит переводить «full qualified name»? Или хотя бы не превращать его в «полностью квалифицированное имя»? ;)
Вполне понятный термин. Как вам «полное имя» в качестве аналога?
Согласен с Вами, уже изменил. Да пребудет с Вами положительная Карма!
Оказывается, правильно будет:

Fully-qualified name — полное квалифицированное имя

Qualified name — квалифицированное имя

Unqualified name — неквалифицированное имя
Насколько следует из документации, ключевое слово const работает только внутри классов.

ЗЫ: Я прям уже вижу толпу кодеров, которые вместо singleton'ов, к примеру, везде понаставят пространств имен и глобальных переменных…
Спасибо за статью, но для себя я пока не вижу применения пространства имен.
Значит, если займетесь серверным программированием, у Вас еще все впереди :-)
вот если бы ещё стандартные функции языка по пространствам разложили.
>Примечение: разработчики отказались от поддрежки этой возможности.
блин не дочитал
Не хочу обижать разработчиков на Php, но namespaces в чистом виде — не вполне удачное решение из мира C++. Да, гибко; да, позволяет решить проблему; но утяжеляет и без того несимпатичный синтаксис.

приемлемо работает Ява с ее пакетами

Хорошо решен вопрос в Питоне, Руби, Хаскеле и других — модулями, по которым распихана стандартная библиотека и вообще весь код.
Only those users with full accounts are able to leave comments. Log in, please.