Статьи

Как использовать пространства имен PHP, часть 2: импорт, псевдонимы и разрешение имен

PHP namespaces В первой части мы обсудили, почему полезны пространства имен PHP и ключевое слово namespace . В этой статье мы рассмотрим команду use и то, как PHP разрешает имена пространств имен.

Для целей этого примера мы определим два практически идентичных кодовых блока; единственное отличие заключается в их пространстве имен:

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__; } } ?> 

lib2.php:

 <?php // application library 2 namespace App\Lib2; const MYCONST = 'App\Lib2\MYCONST'; function MyFunction() { return __FUNCTION__; } class MyClass { static function WhoAmI() { return __METHOD__; } } ?> 

Прежде чем мы начнем, нужно немного разобраться в терминологии PHP.

Полностью квалифицированное имя
Любой код PHP может ссылаться на полностью определенное имя — идентификатор, начинающийся с разделителя обратной косой черты пространства имен, например, AppLib1MYCONST, AppLib2MyFunction () и т. Д.

Полностью квалифицированные имена не имеют двусмысленности. Начальная обратная косая черта работает аналогично пути к файлу; это означает «корневое» глобальное пространство. Если бы мы реализовали другую MyFunction () в нашем глобальном пространстве, ее можно было бы вызвать из lib1.php или lib2.php с помощью MyFunction() .

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

Квалифицированное имя
Идентификатор по крайней мере с одним разделителем пространства имен, например, Lib1MyFunction ().

Неквалифицированное имя
Идентификатор без разделителя пространства имен, например, MyFunction ().

Работа в одном и том же пространстве имен

Рассмотрим следующий код:

myapp1.php:

 <?php namespace App\Lib1; require_once('lib1.php'); require_once('lib2.php'); header('Content-type: text/plain'); echo MYCONST . "\n"; echo MyFunction() . "\n"; echo MyClass::WhoAmI() . "\n"; ?> 

Хотя мы включаем и lib1.php, и lib2.php , идентификаторы MYCONST, MyFunction и MyClass будут ссылаться только на код в lib1.php . Это происходит потому, что код myapp1.php находится в том же пространстве имен AppLib1:

результат:

 App\Lib1\MYCONST App\Lib1\MyFunction App\Lib1\MyClass::WhoAmI 

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

Пространства имен могут быть импортированы с use оператора use , например

myapp2.php:

 <?php use App\Lib2; require_once('lib1.php'); require_once('lib2.php'); header('Content-type: text/plain'); echo Lib2\MYCONST . "\n"; echo Lib2\MyFunction() . "\n"; echo Lib2\MyClass::WhoAmI() . "\n"; ?> 

Можно определить любое количество операторов использования или отдельные пространства имен можно разделить запятой. В этом примере мы импортировали пространство имен AppLib2. Мы по-прежнему не можем напрямую ссылаться на MYCONST, MyFunction или MyClass, потому что наш код находится в глобальном пространстве, и PHP будет искать их там. Однако, если мы добавим префикс ‘Lib2’, они станут полными именами; PHP будет искать в импортированных пространствах имен, пока не найдет совпадение.

результат:

 App\Lib1\MYCONST App\Lib2\MyFunction App\Lib2\MyClass::WhoAmI 

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

Псевдонимы пространства имен, пожалуй, самая полезная конструкция. Псевдонимы позволяют нам ссылаться на длинные пространства имен, используя более короткое имя.

myapp3.php:

 <?php use App\Lib1 as L; use App\Lib2\MyClass as Obj; header('Content-type: text/plain'); require_once('lib1.php'); require_once('lib2.php'); echo L\MYCONST . "\n"; echo L\MyFunction() . "\n"; echo L\MyClass::WhoAmI() . "\n"; echo Obj::WhoAmI() . "\n"; ?> 

Первый оператор use определяет AppLib1 как «L». Любые квалифицированные имена, использующие ‘L’, будут переведены в ‘AppLib1’ во время компиляции. Поэтому мы можем ссылаться на LMYCONST и LMyFunction, а не на полное имя.

Второе утверждение более интересно. Он определяет ‘Obj’ как псевдоним для класса ‘MyClass’ в пространстве имен AppLib2. Это возможно только для классов, но не для констант или функций. Теперь мы можем использовать new Obj() или запускать статические методы, как показано выше.

результат:

 App\Lib1\MYCONST App\Lib1\MyFunction App\Lib1\MyClass::WhoAmI App\Lib2\MyClass::WhoAmI 

Правила разрешения имен в PHP

Имена идентификаторов PHP разрешаются с использованием следующих правил пространства имен. Обратитесь к руководству по PHP для получения дополнительной информации.

1. Вызовы полностью определенных функций, классов или констант разрешаются во время компиляции.

2. Неквалифицированные и квалифицированные имена переводятся в соответствии с правилами импорта, например, если пространство имен ABC импортируется как C, вызов CDe() переводится в ABCDe() .

3. Внутри пространства имен всем квалифицированным именам, еще не переведенным в соответствии с правилами импорта, предшествует текущее пространство имен, например, если в пространстве имен AB выполняется вызов CDe() , оно транслируется в ABCDe() .

4. Неквалифицированные имена классов переводятся в соответствии с текущими правилами импорта, а полное имя заменяется коротким импортированным именем, например, если класс C в пространстве имен AB импортируется как X, new X() переводится в new ABC() .

5. Неполные вызовы функций в пространстве имен разрешаются во время выполнения. Например, если MyFunction () вызывается в пространстве имен AB, PHP сначала ищет функцию ABMyFunction (). Если это не найдено, он ищет MyFunction () в глобальном пространстве.

6. Призывы к неквалифицированным или квалифицированным именам классов разрешаются во время выполнения. Например, если мы вызовем new C() в пространстве имен AB, PHP будет искать класс ABC. Если это не найдено, он попытается автоматически загрузить ABC.

Смотрите также:

В заключительной статье завтра мы рассмотрим автозагрузку и другие дополнительные параметры.