
Предисловие: На Хабре уже публиковались несколько статей, посвященных пространству имен в PHP (все ссылки на них я привожу в приложении). Однако, этот интересный и полезный вопрос был раскрыт не полностью. Поэтому я привожу перевод первой из трех статей по данной теме (остальные переведу в ближайшее время). P.S. Статья для начинающих
Пространства имен (namespaces) — это одно из самых значительных изменений в PHP 5.3. Они будут хорошо знакомы С# и Java разработчикам, и, вероятно, они изменят к лучшему структуру PHP-приложений.
Почему мы нуждаемся в пространстве имен?
Поскольку размер библиотеки Вашего PHP кода растет, возрастает и риск случайного переопределения функции или имени класса, которые были объявлены ранее. Проблема усугубляется, когда Вы пытаетесь добавлять сторонние компоненты или плагины; что будет, если два или более наборов кода будут выполнять классы «Database» или «User»?
Ранее, единственным решением были длинные имена классов/функций. Например, WordPress добавлял к каждому имени префикс «WP_». Zend Framework обычно дает детально описывающие названия, что приводит к длиннющим именам классов, таким как Zend_Search_Lucene_Analysis_Analyzer_Common_Text_CaseInsensitive.
Проблемы совпадения имен снимаются введением пространств имен. PHP константы, классы и функции могут быть сгруппированы в библиотеки пространств имен (namespaced libraries).
Как определяются пространства имен?
По умолчанию, все имена констант, классов и функций размещены в глобальном пространстве — как это и было до того, как PHP стал поддерживать пространства имен.
В коде, пространства имен определяются с помощью единственного слова namespace в самом начале Вашего PHP файла. Это слово должно быть самой первой командой (за исключением declare) и ни не-PHP код, ни HTML, ни даже пробел не должен предшествовать этой команде, например:
- <?php
- // define this code in the 'MyProject' namespace
- namespace MyProject;
-
- // ... code ...
* This source code was highlighted with Source Code Highlighter.Весь код, следующий за этими строками, будет относиться к пространству имен «MyProject». Невозможно вкладывать в него другие пространства имен, или определять более чем одно пространство имен для одной и той же части кода (поскольку распознано будет лишь последнее объявление пространства имен, предшествующие же — игнорируются). Тем не менее, Вы можете определить различные пространства имен в одном и том же файле, например:
- <?php
- namespace MyProject1;
- // PHP code for the MyProject1 namespace
-
- namespace MyProject2;
- // PHP code for the MyProject2 namespace
-
- // Alternative syntax
- namespace MyProject3 {
- // PHP code for the MyProject3 namespace
- }
- ?>
* This source code was highlighted with Source Code Highlighter.Но, хотя это и возможно, я бы не советовал делать так: будьте благоразумны, определяя только одно пространство имен для каждого файла.
Подпространства имен (Sub-namespaces)
PHP дает Вам возможность определять иерархию пространств имен таким образом, чтобы библиотеки могли быть соподчинены друг другу. Получившиеся подпространства имен разделяются с помощью обратных слэшей \, например:
- MyProject\SubName
- MyProject\Database\MySQL
- CompanyName\MyProject\Library\Common\Widget1
Вызов кода, относящегося к пространству имен
В файле с именем lib1.php мы определим константу, функцию и класс в пределах пространства имен App\Lib1:
lib1.php
- <?php
- // application library 1
- namespace App\Lib1;
-
- const MYCONST = 'App\Lib1\MYCONST';
-
- function MyFunction() {
- return __FUNCTION__;
- }
-
- class MyClass {
- static function WhoAmI() {
- return __METHOD__;
- }
- }
- ?>
* This source code was highlighted with Source Code Highlighter.Теперь мы можем включить этот код в другой PHP файл, например:
myapp.php
- <?php
- header('Content-type: text/plain');
- require_once('lib1.php');
-
- echo \App\Lib1\MYCONST . "\n";
- echo \App\Lib1\MyFunction() . "\n";
- echo \App\Lib1\MyClass::WhoAmI() . "\n";
- ?>
* This source code was highlighted with Source Code Highlighter.Никаких пространств имен не определено в файле myapp.php, поэтому код существует в глобальном пространстве. Любая прямая ссылка на MYCONST, MyFunction или MyClass вызовет сбой, поскольку они существуют только в пространстве имен App\Lib1. Чтобы вызвать код из lib1.php, мы можем добавить префикс \App\Lib1, чтобы определить полное квалифицированное имя. На выходе, когда загрузим myapp.php, мы получим следующий результат:
- App\Lib1\MYCONST
- App\Lib1\MyFunction
- App\Lib1\MyClass::WhoAmI
* This source code was highlighted with Source Code Highlighter.Полные квалифицированные имена могут становиться достаточно длинными; вместе с тем, существует несколько очевидных преимуществ в определении длинных имен классов, наподобие App-Lib1-MyClass. Поэтому, в следующей статье, мы обсудим использование псевдонимов (aliasing) и разберемся как PHP разрешает имена пространств имен.
Читайте также:
Как использовать пространства имён в PHP, Часть 2: Импортирование, псевдонимы и правила разбора имён
Как использовать пространства имён в PHP, Часть 3: Ключевые слова и автозагрузка
Примечания:
A/ Единственная подробная статья по теме на Хабре:
Также имеются упоминания в статьях:
- Пространства имён уже в PHP 5.3?!
- PHP 5.3: обзор
- Стили кодирования и рекомендации по написанию чистого кода
B/ Замечания, поправки, указания на неточности и проч. — приветствуются!



комментарии (83)