Пространства имен
Любой современный PHP-код вызывается с указанием пространства имен. Не важно, о каком коде идет речь — это может быть вызов кода из файла в соседней директории или из установленной зависимости. Это касается любой библиотеки, включая те, которые пишем мы сами. По этой причине нужно как-то выбрать имя пространства имен.
Имя пакета отображается в имени пространства имен таким образом — Dependency\Injection
, где дефис заменяется на обратный слеш \
, а каждое слово начинается с заглавной буквы.
К сожалению, пространства имен в языке появились не сразу, поэтому PHP позволяет создавать файловую структуру и структуру пространств имен независимо. Кроме того, в разных пакетах есть разные способы именования файлов, формирования самих имен пакетов, организации файлов внутри пакета. По этой причине мы старались использовать в php-package самые распространенные практики, которые максимально похожи на то, как все организовано в других языках:
- Пакет именуется в стиле kebab-case
- Каждый пакет может выставлять наружу только одно пространство имен, что снижает риск пересечения с другими пакетами и позволяет легко определить принадлежность пространства имен к пакету. В терминах стандарта PSR-4 такое пространство имен называется vendor namespace
- Пространства имен именуются в стиле StudlyCaps и напрямую отображаются на файловую систему. Единственное исключение — это корневое пространство имен, которое получается путем трансформации имени пакета
- Исходный код проекта находится в папке src, а тесты — в директории tests
Что касается именования файлов: что бы ни хранилось внутри, придерживайтесь именования в стиле StudlyCaps. На практике такие названия выглядят так: MySuperFile.php
.
Автозагрузка
В предыдущем уроке мы создали файл src/Runner.php. Мы попытались запустить функции, которые он содержит — например, подключить соответствующий неймспейс в файл index.php. В итоге все завершилось с ошибкой.
Дело в том, что попытка использовать любой сторонний код или другие файлы, принадлежащие текущему пакету, требует загрузки этих файлов. Указание пространства имен никак не влияет на их загрузку.
По умолчанию считается, что если вы пытаетесь использовать какой-то код, то он уже загружен, используя require
или require_once
. Чисто технически, можно так и делать. Каждый раз, когда нам нужно использовать сторонний код, мы можем сначала делать его подгрузку через require
. К счастью, этого делать не нужно. Более того, линтер ругается на попытку использовать require
самостоятельно.
Дело в том, что Composer умеет автоматически загружать все необходимые файлы. Эта функциональность частично опирается на возможности автозагрузки самого PHP. Мы еще не проходили классы, но стандарт PSR-4 описывает автозагрузку именно классов. Грубо говоря, если правильно сконфигурировать автозагрузчик, то мы можем просто добавить новый файл с классом, и он загрузится автоматически. В случае с файлами, в которых есть только пространство имен и функции, все чуть сложнее. Каждый новый файл должен быть прописан внутри composer.json
, только тогда он будет загружен. Вот как это выглядит:
{
"name": "hexlet/pairs",
"autoload": {
"files": [
"src/Pairs.php",
"src/Lists.php"
]
}
}
В файл composer.json
добавляется секция autoload
. Внутрь этой секции добавляется еще одна секция files
. Она в свою очередь содержит список файлов, которые надо загрузить. После обновления секции autoload
нужно обязательно запускать команду composer dump-autoload
. Она генерирует необходимый код в директории vendor
, реализующий указанную загрузку. Затем остается только один шаг. Чтобы ваш код начал использовать все, что сделал Composer, необходимо в начале вашего кода прописать следующую строку:
<?php
require_once __DIR__ . '/../vendor/autoload.php';
Конкретный путь зависит от того, где находится директория vendor
. При работе с локальным проектом Composer по умолчанию создаст директорию vendor
в его корне. Но в случае глобальной установки пакета путь к директории vendor
будет другим. Его можно узнать, выполнив команду в терминале:
composer global config vendor-dir
# Changed current directory to /home/user/.config/composer
# vendor
После установки сам пакет, его зависимости и файл autoload.php
будут созданы именно в этой директории. Путь, который мы указали выше, уже не сработает, потому что при глобальной установке путь к директории vendor
отличается. Чтобы файл autoload.php
был найден в любом случае, используют следующую запись:
<?php
// Путь, который будет использован при глобальной установке пакета
$autoloadPath1 = __DIR__ . '/../../../autoload.php';
// Путь для локальной работы с проектом
$autoloadPath2 = __DIR__ . '/../vendor/autoload.php';
if (file_exists($autoloadPath1)) {
require_once $autoloadPath1;
} else {
require_once $autoloadPath2;
}
Самостоятельная работа
- Добавьте файл Runner.php в автозагрузку в секцию files
Измените ранее созданный файл index.php в корне проекта вне директории src. Он должен выглядеть так:
<?php require_once __DIR__ . '/vendor/autoload.php'; // Файл не включается напрямую // Он загрузится автоматически благодаря автозагрузке use Hexlet\Php\Runner; print_r(Runner\run());
Запустите файл index.php на выполнение из корня проекта:
php index.php # ['TAYLOR', 'ABIGAIL', '']
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.