Menu

Пространства имён PHP: namespace, use и псевдонимы

Пространство имён PHP группирует классы, функции и константы под общим префиксом: namespace App\Models; в начале файла, а в другом месте use App\Models\User;, чтобы обращаться к классу по короткому имени. Полные имена, псевдонимы use ... as, use function, обратный слеш для глобальных классов и автозагрузка PSR-4.

На этой странице есть исполняемые редакторы: меняйте, запускайте и сразу видите результат.

Пространство имён PHP помещает классы, функции и константы под префикс, чтобы их имена не сталкивались с чужими. Его объявляют через namespace App\Models; первой инструкцией файла, а другие файлы обращаются к классу как \App\Models\User или импортируют его через use App\Models\User; и пишут просто User.

Внутри пространства имён User означает App\Models\User. User::class даёт полное имя строкой, ничего не создавая, что удобно для логирования и для автозагрузчиков.

Два пространства имён в одном файле

В реальном проекте в каждом файле одно пространство имён. Для самостоятельной демонстрации в одном файле может быть несколько пространств имён, если каждое обёрнуто в фигурные скобки. Код, который не относится ни к одному пространству имён, помещается в namespace { }:

Два класса с именем Order живут рядом, потому что их полные имена различаются. Именно эту проблему решают пространства имён, когда вы устанавливаете библиотеки: ваш Order, Order платёжной библиотеки и Order библиотеки для PDF больше не конфликтуют.

Импорт через use и псевдоним через as

Писать везде \Shop\Order громоздко. use в начале файла (или блока пространства имён) импортирует имя, чтобы можно было использовать короткую форму. Когда два импорта заканчиваются на одно и то же короткое имя, as даёт одному из них другое имя:

use лишь создаёт короткое имя до конца файла. Он не загружает файл и не выполняет код и работает одинаково, существует класс или ещё нет. Допускаются и групповые импорты: use Shop\{Order, Invoice};.

use function и use const

Функции и константы из пространства имён импортируются через use function и use const:

Глобальным классам нужен обратный слеш

Внутри пространства имён неквалифицированное имя класса разрешается относительно этого пространства, поэтому new DateTime() внутри namespace App; ищет App\DateTime. С функциями и константами иначе: если App\strlen не существует, PHP откатывается к глобальной strlen. Классы никогда не откатываются.

В catch (\Error $e) обратный слеш понадобился по той же причине: без него PHP искал бы App\Error, никогда не совпал бы с настоящей ошибкой, и скрипт остановился бы с неперехваченным Error. Исправьте это начальным обратным слешем, как выше, или через use DateTime; в начале файла. То же касается \Exception, \Throwable и любого другого встроенного класса; как их перехватывать, смотрите в try catch.

Автозагрузка и PSR-4

В проекте каждый класс лежит в своём файле, а путь к файлу следует пространству имён. PSR-4 это соглашение: префикс пространства имён сопоставляется базовой папке, а остаток имени становится путём. Автозагрузчик, зарегистрированный через spl_autoload_register(), загружает файл класса при первом использовании класса. Этот блок записывает на диск два файла классов и загружает их автоматически:

Каждый файл класса загружается один раз, в тот момент, когда класс впервые нужен. В реальных проектах эту функцию сами не пишут: её генерирует Composer по нескольким строкам в composer.json:

{
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    }
}

После composer dump-autoload одна строка require __DIR__ . '/vendor/autoload.php'; в начале входного скрипта загружает любой класс App\... по требованию.

Правила пространств имён, которые приводят к ошибкам

  • namespace должен быть первой инструкцией в файле. Перед ним могут стоять только declare(strict_types=1); и комментарии.
  • Импорты use действуют в пределах файла. Импорт класса в index.php не делает короткое имя рабочим внутри подключённого файла; каждому файлу нужны свои строки use.
  • use ставится на верхнем уровне файла или блока пространства имён. Внутри тела класса use означает другое: он подключает трейт.
  • Строки никогда не разрешаются: $class = 'User'; new $class(); ищет глобальный User. Храните полное имя, лучше всего через User::class.

Последнее правило стоит быстро проверить:

Часто задаваемые вопросы

Что такое пространство имён в PHP?

Префикс, который группирует связанные классы, интерфейсы, функции и константы, как папка для имён. namespace App\Models; в начале файла делает его класс User классом App\Models\User, поэтому он не может столкнуться с User из другой библиотеки.

Что делает use в PHP?

use App\Models\User; в начале файла позволяет писать в этом файле User вместо полного имени \App\Models\User. Он ничего не загружает и не подключает; загрузка файла класса это работа автозагрузчика. use ... as Alias; выбирает другое короткое имя.

Почему внутри пространства имён возникает Class not found?

Внутри namespace App; голое имя класса разрешается относительно пространства имён, поэтому new DateTime() ищет App\DateTime. Пишите new \DateTime() или добавьте use DateTime; в начало файла. Функции и константы автоматически откатываются к глобальному пространству имён, классы нет.

Что означает обратный слеш перед именем класса в PHP?

Начальный обратный слеш делает имя полностью квалифицированным, начиная от глобального пространства имён: \Exception это всегда встроенный Exception PHP, в каком бы пространстве имён ни был код. Без него имя разрешается относительно текущего пространства имён и импортов use.

Как пространства имён связаны с папками и PSR-4?

Сам PHP не привязывает пространства имён к папкам. Это делает соглашение PSR-4: префикс вроде App\ сопоставляется каталогу вроде src/, поэтому App\Models\User лежит в src/Models/User.php. Автозагрузчик Composer следует этому соглашению, поэтому обычно одно совпадает с другим.

Иллюстрация языков программирования Coddy

Учитесь программировать с Coddy

НАЧАТЬ