Пространства имён
Любой код на 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', '']

Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
- Статья «Как учиться и справляться с негативными мыслями»
- Статья «Ловушки обучения»
- Статья «Сложные простые задачи по программированию»
- Урок «Как эффективно учиться на Хекслете»
- Вебинар «Как самостоятельно учиться»
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.