Пространства имен в PHP

Пространства имен в PHP

От автора: Разрабатывая сложное веб-приложение, может возникнуть ситуация, когда при объявлении функции или переменной произойдет дублирование имен, что незамедлительно приведет к ошибке. Поэтому в данном уроке мы с Вами рассмотрим очень полезное нововведение в PHP 5.3 – пространства имен, используя которое, можно позабыть о ошибках, связанных с дублированием имен элементов Вашего скрипта.

скачать исходникискачать урок

Понятие пространства имен

Для начала рассмотрим следующие два файла. Файл file1.php

Файл file2.php

При этом обратите внимание, что в каждом из них объявлена функция foo(). Сразу хотел бы отметить, что сейчас мы еще не говорим о пространствах имен и ни коем образом их не объявляем. А значит, по умолчанию используется глобальное пространство имен. Теперь обратите внимание, на еще один файл в котором мы подключим два предыдущих файла и вызовем на исполнение функцию foo(). Файл index.php

Запустив данный файл в браузере, мы, конечно же, увидим ошибку, так как в данный момент у нас объявляется две функции, с одинаковыми именами:

Так же хотел бы отметить, что обращаясь к функции foo(), в данном случае мы используем неквалификационное имя – то есть это только идентификатор конкретной функции (имя функции, без учета пространства имен). Что бы предотвратить появление ошибки – используем пространства имен. Для этого в каждом из подключаемых файлов укажем собственное пространство имен, используя ключевое слово namespace. Файл file1.php

Файл file2.php

Обратите внимание, что объявляя пространство имен, обязательно необходимо прописывать ключевое слово namespace перед любым кодом PHP или отображением данных на экран, в противном случае будет ошибка. Теперь, если мы обновим данные в браузере – мы получим ошибку вида:

Скорее всего Вы догадались, ошибка означает, что не найдена функция foo(). Данная функция определена, но в других пространствах имен. Файл index.php использует глобальное пространство имен, поэтому обращаясь к функции foo(), используя неквалификационное имя, мы ни как не можем получить доступ к функциям foo(), объявленным в других пространствах имен. Для того, что бы получить доступ к функции foo(), файла file1.php, мы должны в начале имени функции указать пространство имен:

При этом в браузере мы увидим отработку вызываемой функции:

Таким образом, мы указали интерпретатору языка PHP, где искать интересующую нас функцию (в каком пространстве имен, осуществлять поиск). И в нашем случае отработала функция foo() из файла file1.php. Но, каждый раз при вызове функций, или переменных, обращаться к пространствам имен не совсем удобно, поэтому в файле index.php, мы можем объявить пространство имен, которое нас интересует и соответственно вызвать функцию foo(), используя неквалификационное имя:

При этом, если мы перейдем браузер, то увидим, что функция нормально отрабатывает. Теперь давайте посмотрим, что будет, если я в текущем пространстве имен, обращусь к функции foo(), следующим образом:

В этом случае мы увидим ошибку следующего вида:

Ошибка возникает, потому как мы с Вами обращаемся к функции, используя имя и пространство имен — File1\foo(), таким образом, мы используем квалификационное имя. Квалификационное имя элемента содержит пространство имен, а также идентификатор элемента (его имя). В этом случае, да и в случае с неквалификационными именами, интерпретатор PHP всегда будет добавлять объявленное пространство имен к имени вызываемого элемента. Таким образом, если мы в начале файла объявили пространство имен File1, и вызываем на исполнение функцию File1\foo() – интерпретироваться данная строка будет как File1\File1\foo(). А теперь давайте посмотрим, что будет, если я обращусь к функции foo(), следующим образом:

В этом случае мы увидим, что функция отлично отрабатывает.

Здесь, хотел бы отметить, что \File1\foo() – это полное квалификационное имя функции foo(). Полное квалификационное имя всегда начинается с обратного слеша и содержит полное пространство имен и идентификатор интересующего элемента (имя функции, переменой и т.д). Если мы обращаемся к полному квалификационному имени, то интерпретатор не будет учитывать объявленное ранее пространство имен при интерпретации.

Объявляя пространства имен, мы можем создавать некие иерархии пространств имен, к примеру. Файл file1.php

Файл file2.php

При этом в файле index.php, мы можем вызвать функцию foo(), следующим образом:

Импортирование пространств имен и псевдонимы

Если в нашем проекте предусмотрена иерархия пространств имен, мы можем импортировать интересующее нас пространство имен в тот или иной файл, к примеру, в файле index.php импортируем пространство имен, используя ключевое слово use:

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

Импортируя пространство имен, можно указать псевдоним, используя который можно ссылаться на пространство имен, к примеру:

В этом случае мы можем обращаться к интересующим нас элементам, используя псевдоним. При интепретации данный псевдоним будет заменен на импортируемое пространство имен, то есть, вызывая name\foo(), мы вызываем MyProject\File1\foo(). Очень удобно использовать импортирование пространств имен в связке с псевдонимами, работая с классами, к примеру, есть файл следующего содержания:

Данный файл принадлежит к пространству имен MyProject\File3 и соответственно расположен по адресу MyProject\File3\My2.php, то есть иерархия пространств имен, точно соответствует структуре папок, в которых содержится данный файл. В файле index.php, мы подключим данный файл и импортируем его пространство имен, используя при этом псевдоним:

Обратите внимание я импортирую пространство имен и псевдоним назначаю непосредственно для класса, описанного в указанном пространстве имен, таким образом при создании объекта данного класса, я могу использовать псевдоним: new myclass(). Что собственно мы и видим при обновлении страницы браузера:

Еще хотел бы обратить Ваше внимание, на следующий пример, файл index.php:

В данном примере, мы с Вами рассмотрим создание механизма автоматической загрузки классов, используя пространства имен. Обратите внимание, вначале импортируем пространство имен и назначаем псевдоним для имени класса. Далее описываем функцию __autoload($class), функцию автоматической загрузки классов, которая выполнится при создании ранее неопределенного объекта класса. Данная функция принимает параметром переменную $class, в которую попадет имя класса, объект которого мы пытаемся создать. В нашем случае, используется псевдоним myclass, который при интерпретации будет заменен на MyProject\File3\My2, а это полностью соответствует файловой структуре примера, остается только заменить обратные слеши на прямые и добавить расширение для файла.

При обновлении браузера, на экране мы увидим следующее:

Как Вы видите все успешно отрабатывает.

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

На этом данный урок завершен. Всего Вам доброго и удачного кодирования!!!

Метки: ,

Похожие статьи:

Комментарии Вконтакте:

Комментарии (1)