Пространство имён в php 5.3 и php 6

    Пространство имён (namespace/package) знакомо java и c# программистам, теперь доступно и в php. Нужно оно для того, что-бы не писать длинные перефиксы к названиям классов, как сейчас делается в Zend, PEAR и других библиотеках и платформах для совместимости.
    Вместо этого классы, функции, интерфейсы (абстрактные классы) и константы могут быть объединены в одно пространство имён. Глобальные переменные в это пространство не входят.

    Простой пример


    Определяется пространство ключевым словом namespace
    //определяем класс в пространстве
    namespace MyCMS::Core;
    class System{}

    Использование этого класса в третьих библиотеках осуществляется ключевым словом use
    require_once('mycms/core.php');
    use MyCMS::Core::System; //импортируем только заданный класс
    $objSystem=new System;


    Как вы уже догадались, разделитель :: работает так же как и вызов статических методов, разделяя уровень пространства имён и конкретный класс. Уровень вложённости пространств можно использовать наряду с модульностью библиотеки, например реализовать пространства Database::MySQL::Adapter и Database::Oracle::Adapter.

    Новые возможности и новые проблемы


    Если в пространстве имён имя класса перезаписывает ранее объявленный глобальный класс или функцию, то к нему по прежнему можно обратится через ::SomeClassName, однако не зная к какой именно реализации программист обращается может вызвать проблемы. Например можно переобъявить стандартные php функции, поменять sin() и cos() местами, что-бы кому-то жизнь мёдом не казалась.
    Для отладки существует рабочая константа __NAMESPACE__.
    С двоеточием возникает и проблема неоднозначности:
    A::B() // вызов функции B из namespace A
    A::B() // вызов статичного метода B у класса A

    Читайте по теме:


    Оригинал
    Поделиться публикацией
    Похожие публикации
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 78
    • +2
      Не боян-ли?

      По-моему лучше в оригинале прочитать - например тут - http://ilia.ws/files/phpquebec_php53.pdf
      • 0
        Спасибо, приятная статья. Многим полезно будет новое узнать.
        Один только вопрос - почему на в блоге PHP? Перенесли бы.
      • 0
        И вопрос в догонку - может автор знает какие-то ньюансы работы с неймспейсами в 5.3 и 6 версии, все-таки лично мне хочется больше уже ньансов, а не простого переписывания того, что написано в принципе везде про появление неймспейсов в новых версиях..

        Согласен, вопрос актуальный, но нужно как-то больше конкретики.
        • 0
          увы, рабочий хостинг всё ещё на 5.2.5 стоит
          • 0
            Очень жаль :(
            • 0
              Установите 5.3 в качестве cgi... И будет счастье ;-)
          • 0
            Мда, чет они перемудрили с двумя двоеточиями. Неужели сложно было придумать новое обозначение? типо >> или три двоеточия)
            • 0
              А разве >> не бинарный сдвиг?
              • 0
                точняк, вылетело из головы) тогда :>:
              • 0
                точку надо!! как в нормальных ЯВУ.
                • 0
                  зачем? двоеточие на эту роль хорошо подходит, в то же время, неймспейсы - имхо недостаточный повод чтобы вносить в язык новый синтаксический элемент.

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

                  и два: в чем концептуальная разница между статическим методом и функцией в неймспейсе, а? (-:

                  А, ну и ещё: в питоне, например, для обращения к методам объектов и к объектам из ругого пространства имён тоже используется одинаковый синтаксис (точка) и ничего, никто пока не умер (-:
                  • 0
                    Метод связан с классом или объектом, тогда как функция от объекта не зависит
                    http://en.wikipedia.org/wiki/Method_(computer_science)
                    http://en.wikipedia.org/wiki/Function_(computer_science)
                    • 0
                      не-не. я спрашивал конкретно про статические методы.

                      с точки зрения вызывающего в чем разница?

                      насколько важно мне знать чем концептуально отличаются класс C и неймспейс N в этих примерах:

                      C::get_instance();
                      N::get_instance();
                      • 0
                        self
                        как я понимаю, в неймспейсах он не доступен
                        • 0
                          снаружи когда я вызываю это, зачем мне знать как оно внутри работает?
                        • 0
                          1. В статичных методах при наследовании насколько я помню можно обращаться к родительским методам через parent::метод
                          2. Обращение к статичным параметрам класса (правда с наследием там вроде баги были)
                          Как я понимаю c namespace такого не проделаешь, хотя выглядит оно одинаково и вероятно реализуется тоже.
                          • 0
                            1. снаружи когда я это вызываю, зачем мне знать как оно работает внутри?
                            2. см. п. 1

                            Естественно, если я хочу наследоваться, то разница есть и я вынужден буду узнать как оно устроено, однако вопрос стоял не так.
                    • 0
                      Это преемственность С++
                    • 0
                      в C++ такая же неоднозначность существует. И ничего, живут.
                      • +1
                        Проблема надуманна, это факт. Просто такое положение дел не привычно в PHP, так, как неймспейсов до этого вообще не было, поэтому многих смущает то, как это выглядит и выдумывают проблему на пустом месте.
                      • НЛО прилетело и опубликовало эту надпись здесь
                        • 0
                          интересно, когда версии с поддержкой неймспейсов станут распространены на различных хостингах, имена классов в Zend Framework остануться такими же, или все переведут на неймспейсы...
                          • 0
                            а о совместимости ты подумал?
                            • 0
                              ZF активно развивается, нельзя тащить с собой кучу старого кода только для совместимости, а то как у microsoft получится. конечно, в случае таких тяжелых нововведений нужно дать достаточно времени разработчикам на переход
                              • 0
                                вот именно, что достаточно, а это растянется очень надолго..
                                • 0
                                  префиксы в именах старых классов ради обратной совместимости - не такое уж большое зло, как мне кажется.
                            • +1
                              require_once — моветон в php 5+, есть SPL. А так ниче нового не сказали, анонс namespace был давно.
                              • 0
                                Вы имеете ввиду autoload? Помоему он тоже require_once использует.
                                • +1
                                  Он использует то, что напишет программист. __autoload() - это просто функция, а не магия какая-то :)

                                  function __autoload($className) {
                                  $fileName = $className.'.class.php';
                                  require PATH_ROOT."classes/".$fileName;
                                  }

                                  Простейший пример.
                                  • 0
                                    Я такую конструкцию и использую, вот и интересуюсь - можно ли и как попроще (и куда уж проще)?
                                    • 0
                                      Тогда я не совсем понял, что значит "Вы имеете ввиду autoload? Помоему он тоже require_once использует. ".

                                      Ответ на Ваш вопрос - "а куда еще проще?".
                                      • 0
                                        Я не складирую все файлы в одну папку если вы подразумеваете autoload по умолчанию
                                        • 0
                                          Ну на самом деле я не подразумевал, у меня как раз в разных папках.

                                          Я делаю это приблизительно так:

                                          function __autoload($className) {
                                          $locations = array('forum', 'fun', 'gallery', 'leecher', 'soap', 'common');

                                          $fileName = $className.'.class.php';
                                          foreach ($locations as $path) {
                                          if (file_exists(PORTAL_PATH_ROOT."classes/".$path."/".$fileName)) {
                                          require PATH_ROOT."classes/".$path."/".$fileName;
                                          break;
                                          }
                                          }
                                          }

                                          Вы же можете массив сделать в конфиге или из базы выбирать, в зависимости от того, как храните информацию о модулях.
                                          • 0
                                            PORTAL_PATH_ROOT = PATH_ROOT - плохо отредактировал.
                                            • 0
                                              Видите - всё правильно, вы тоже require используете, а что Xobb имел ввиду я не понимаю..
                                              • 0
                                                Я имею ввиду SPL-register. Оно позволяет написать правило загрузки классов. Наглядный пример здесь. Да, в принципе используется require, но только один раз и больше его в коде использовать не надо. Своим комментарием я имел ввиду, что если мы уж настолько продвинуты чтобы использовать namespace то было б хорошо научится и делать autoload.
                                                • 0
                                                  Спасибо за информацию! Давно пишу на php, а про эту фичу не знал. Буду разбираться, надоело писать в стиле php4
                                                  • 0
                                                    По поводу spl_autoload_register, я его использовал одно время, но потом отказался в пользу статичного(единственного) автолоада с проверками дирректорий и наличия файлов, поскольку динамическая регистрация уж очень много ресурсов жрет.
                                                    • 0
                                                      Не понимаю, чем require плох. Да, автолоад, несомненно, рулит, но, имхо, это какая-то глупая религия - сокращать количество require до 1 в проекте... Конечно, 500 require это тоже перебор, но autoload так или иначе выполняет столько же require(достаточно глянуть по профайлеру), хоть они и сосредоточены в одном методе.
                                                      • 0
                                                        Все просто - уменьшение сложности. Тебе не надо задумыватся о том как подключать, где и по какому принципу классы, ты решаешь это все зарание и больше не задумываешься.
                                                        • 0
                                                          Хм, тут такие хитрые коды пишут, лишь бы не писать лишние require... Может я читаю как-то не так, но мне кажется, что слишком категорично высказано, что на весь проект должен быть 1 require и тот в автолоаде... Я и сам активно юзаю autoload, но не вижу смысла сокращать количество require до 1-2, имхо, разумный предел - 5-10, хотя всё зависит от архитектуры проекта.
                                                      • 0
                                                        А разве исполнение php-файлов ограничивается только подключением классов?
                                                        • 0
                                                          Простите меня пожалуйста, вы сноб и приебываетесь.
                                                          require_once('mycms/core.php');
                                                          use MyCMS::Core::System; //импортируем только заданный класс
                                                          $objSystem=new System;

                                                          Мое мнение относится только к коду выше. И никуда больше. Да, я сам использую require, когда мне надо подключить левый код к своему проекту, который не следует API фреймворка, на котором я работаю.
                                                          • 0
                                                            Несомненно можно было бы разобрать ваш код и, возможно, даже признать свою неправоту. Но, к сожалению, вынужден завершить наш диалог пожеланием вам отправится к определенной матери. спасибо.
                                        • 0
                                          Да ну..для классов уже давно используется __autoload, а если пишут на функциях все, то кто уж им виноват..
                                          • 0
                                            Хм, почему моветон?
                                        • НЛО прилетело и опубликовало эту надпись здесь
                                          • 0
                                            Вас так пугают двоеточия?
                                            • НЛО прилетело и опубликовало эту надпись здесь
                                            • 0
                                              Да, хорошо, что не стали изобретать велосипед. PHPшникам легче будет понимать код на Perl.
                                              • 0
                                                Как правило для хороших PHPшников нет проблемы понимать Perl, посколько до PHP они писали на Perl :)
                                            • 0
                                              require_once('mycms/core.php');
                                              use MyCMS::Core::System; //импортируем только заданный класс

                                              А разве require_once не "импортировало" уже все то, что было в mycms/core.php?
                                              • 0
                                                use автоподстановку делает.
                                                Как я понимаю, new Class() будет на самом деле делать new MyCMS::Core::System::Class()...
                                                Имхо, бесполезная штука — нагляднее использовать полное название неймспейса или хотя бы алиас...
                                                • 0
                                                  во всех языках сделали такую бесполезную штуку. вот глупцы.
                                                  • 0
                                                    Вы о чём? Это чтобы конфликтов имён классов в разных неймспейсах небыло. Ну и чтобы, используя много классов из неймспейса, не писать много раз подряд всю вереницу вложености NS.
                                                    • 0
                                                      я о сарказме на тему того, на что отвечал
                                                      • 0
                                                        Пардон, не сразу уследил...
                                                    • 0
                                                      я только про use ;) и я ступил, признаю, сам ведь буду использовать...
                                                • 0
                                                  Хотелось бы, например, знать
                                                  • как можно в автолоаде узнать запрашиваемый неймспейс или как можно (и можно ли) делать локальные (в рамках одного неймспейса) автолоады
                                                  • можно ли перемещаться по иерархии неймспейсов? потому как если нет, то лучше было бы сделать вложенные классы для static обращений
                                                  • как понять фразу мануала «К примеру, если пространство имён A::B::C импортировано, new C() будет транслировано как new A::B::C().», если new A::B::C() обращается к неймспейсу A::B
                                                  • 0
                                                    По поводу первого: в автолоад имя класса приходит полностью My::Namespace::For:MyClass.
                                                    • 0
                                                      я подозревал, спасибо )
                                                  • 0
                                                    Хороший язык - php, сейчас правда перешел с него на Java и уже плотно занимаюсь только ею, но такое чувство что концептуально (т.е. за исключением некоторых моментов синтаксиса и конечно же рантайма) между ними скоро не будет различий ;)
                                                    • 0
                                                      боюсь, что основное концептуальное различие - строгая типизация, навряд ли будет добавлено в PHP
                                                      • 0
                                                        А вот это бооольшой вопрос )) На крайняк будет 2 явы - со строгой типизацией и без строгой типизации )))
                                                        • 0
                                                          вообще-то уже есть, в виде Groovy )
                                                          • 0
                                                            Не, ну груви это все же не php ))
                                                            • 0
                                                              это сильно круче :) так сказать, ява мутирует в питона и руби
                                                        • 0
                                                          Нашли чего бояться :)
                                                      • –1
                                                        пространства имен штука очень полезная. Но, как это обычно бывает у разработчиков PHP, хотели как лучше - получилось как всегда: какой то корявый синтаксис System::Core. А ведь можно было сделать очень просто и красиво:


                                                        namespase System.Core
                                                        {
                                                            class MyClass()
                                                            {}
                                                        }
                                                        • 0
                                                          к сожалению, точка уже давно забита под конкатенацию строк :(
                                                          • 0
                                                            уверяю, нет никакой технической проблемы, что точка конкатенирует строки. На месте имени нэймспэйса же не expression.

                                                            А в принципе точка как конкатенация строки — бред полный, плюс куда лучше был бы.
                                                            • 0
                                                              Хватит говорить со мной как с разработчиком пхп!
                                                            • 0
                                                              ну в общем, дело не в точке, а в единообразности - содержимое класса находится между фигурными скобками{}, так почему же сам класс не поместить в пространство имен между {}.
                                                          • 0
                                                            Постепенно php превращается в perl. Это не может не радовать. Так глядишь и оператор =~ появится вместно ужасных preg_*
                                                            • 0
                                                              Хм, Namespace'ы двигают PHP в сторону Perl? Сомневаюсь, думаю, NS это серьёзная необходимость - во многих продвинутых языках(с точки зрения реализации возможностей ООП) Namespace'ы уже давно реализованы, так что PHP, пусть и слегка запоздало, просто подтягивается до неписаных стандартов. имхо.
                                                              • 0
                                                                Сам писал только на 4 пхп, поэтому не видел раньше в пхп оператора use =)

                                                            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.