Стандарт автозагрузки PSR-4
Часть раздела Объектно-ориентированное программирование путешествия по PHP на Coddy — урок 12 из 91.
PSR-4 — это стандарт, который определяет, как PHP-классы должны автоматически загружаться на основе их пространства имен и расположения файлов. Вместо того чтобы вручную подключать каждый файл класса, PSR-4 позволяет PHP находить и загружать классы автоматически при их использовании.
Основное правило простое: пространство имен должно соответствовать структуре каталогов. Если у вас есть класс App\Models\User, файл должен находиться по адресу App/Models/User.php.
<?php
// Файл: src/Models/User.php
namespace App\Models;
class User {
public $name;
public function __construct($name) {
$this->name = $name;
}
}
Вы можете написать простую функцию автозагрузки, которая следует правилам PSR-4:
<?php
// Файл: autoload.php
spl_autoload_register(function ($class) {
$prefix = 'App\\';
$baseDir = __DIR__ . '/src/';
// Проверяем, использует ли класс наш префикс пространства имен
if (strpos($class, $prefix) === 0) {
$relativeClass = substr($class, strlen($prefix));
$file = $baseDir . str_replace('\\', '/', $relativeClass) . '.php';
if (file_exists($file)) {
require $file;
}
}
});
Функция spl_autoload_register сообщает PHP, что нужно вызвать вашу функцию каждый раз, когда он встречает неизвестный класс. Функция преобразует пространство имен в путь к файлу и загружает его.
Ключевой момент: PSR-4 создает предсказуемое сопоставление между пространствами имен и путями к файлам. Когда вы видите App\Models\User, вы сразу понимаете, что файл находится в src/Models/User.php. Это соглашение упрощает навигацию по проектам и их поддержку.
Задание
ЛегкоДавайте создадим простую систему автозагрузки PSR-4, которая автоматически загружает классы на основе их пространства имен и расположения файлов.
Вы создадите проект с тремя файлами, которые демонстрируют, как PSR-4 сопоставляет пространства имен с путями к директориям:
src/Services/Logger.php— Определите классLoggerв пространстве именApp\Services. Он должен иметь публичное свойствоpublic $name, конструктор, который принимает и устанавливает имя, и методlog($message), который возвращает"[name] logged: [message]".src/Services/Mailer.php— Определите классMailerв пространстве именApp\Services. Он должен иметь публичное свойствоpublic $sender, конструктор, который принимает и устанавливает отправителя, и методsend($to), который возвращает"Mail from [sender] to [to]".main.php— Создайте автозагрузчик PSR-4, используяspl_autoload_register, который сопоставляет префикс пространства именApp\с директориейsrc/. Автозагрузчик должен преобразовывать разделители пространства имен в разделители директорий и добавлять.phpдля поиска нужного файла. После регистрации автозагрузчика используйте ключевое словоuseдля импорта обоих классов, затем создайте объектLoggerс именем"FileLogger"и объектMailerс отправителем"admin@site.com". Выведите результат вызоваlog("System started")для логгера иsend("user@example.com")для почтового сервиса (каждый на новой строке).
Ключевая идея заключается в том, что ваша функция автозагрузки получает полное имя класса (например, App\Services\Logger) и должна преобразовать его в путь к файлу (src/Services/Logger.php). Используйте strpos, чтобы проверить, начинается ли класс с вашего префикса пространства имен, substr для получения относительного имени класса и str_replace для замены обратных косых черт на прямые.
Шпаргалка
PSR-4 — это стандарт, который определяет, как классы PHP должны загружаться автоматически на основе их пространства имен и расположения файлов. Пространство имен должно соответствовать структуре каталогов.
Пример структуры класса:
<?php
// File: src/Models/User.php
namespace App\Models;
class User {
public $name;
public function __construct($name) {
$this->name = $name;
}
}
Автозагрузчик PSR-4 с использованием spl_autoload_register:
<?php
spl_autoload_register(function ($class) {
$prefix = 'App\\';
$baseDir = __DIR__ . '/src/';
// Проверка, использует ли класс наш префикс пространства имен
if (strpos($class, $prefix) === 0) {
$relativeClass = substr($class, strlen($prefix));
$file = $baseDir . str_replace('\\', '/', $relativeClass) . '.php';
if (file_exists($file)) {
require $file;
}
}
});
Автозагрузчик преобразует разделители пространства имен (\) в разделители каталогов (/) и добавляет расширение .php для поиска нужного файла. Например, App\Models\User сопоставляется с src/Models/User.php.
Попробуйте сами
<?php
// Реализация автозагрузчика PSR-4
// TODO: Зарегистрируйте автозагрузчик с помощью spl_autoload_register
// Автозагрузчик должен:
// 1. Проверить, начинается ли класс с префикса пространства имен 'App\'
// 2. Удалить префикс 'App\', чтобы получить относительное имя класса
// 3. Преобразовать разделители пространства имен (\) в разделители каталогов (/)
// 4. Добавить 'src/' в начало и '.php' в конец, чтобы построить путь к файлу
// 5. Подключить файл, если он существует
spl_autoload_register(function ($class) {
// TODO: Определите префикс пространства имен и базовый каталог
// TODO: Проверьте, использует ли класс префикс пространства имен (используйте strpos)
// TODO: Получите относительное имя класса (используйте substr)
// TODO: Постройте путь к файлу, заменив \ на / (используйте str_replace)
// TODO: Подключите файл, если он существует
});
// TODO: Используйте ключевое слово 'use' для импорта классов Logger и Mailer
// TODO: Создайте экземпляр Logger с именем "FileLogger"
// TODO: Создайте экземпляр Mailer с отправителем "admin@site.com"
// TODO: Выведите результат log("System started")
// TODO: Выведите результат send("user@example.com")
?>В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыКлючевое слово $thisМетодыСвойстваКонструктор (__construct)Деструктор (__destruct)Итоги — Простой калькулятор4Наследование
Основы наследованияКлючевое слово parent::Переопределение методовКлючевое слово finalАбстрактные классыИтоги — Иерархия сотрудников7Инкапсуляция
Public, Protected, PrivateПодробный разбор модификаторов доступаГеттеры и сеттерыСокрытие данныхConstructor Promotion (8.0)Итоги — Система учета студентов10Продвинутые концепции ООП
Композиция против наследованияВнедрение зависимостейАнонимные классыПеречисления (PHP 8.1)Файберы (PHP 8.1)Глубокое погружение в клонирование объектовГенераторы и итераторы13Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн КомпоновщикПаттерн Репозиторий2Пространства имен и автозагрузка
Введение в пространства именКлючевое слово useСтандарт автозагрузки PSR-4Автозагрузчик ComposerИтоги: структурированный проект5Интерфейсы и контракты
Введение в интерфейсыРеализация интерфейсовРеализация нескольких интерфейсовИнтерфейс против абстрактного классаType Hinting с интерфейсамиИтоги — Калькулятор фигур8Магические методы
Введение в магические методы__toString и __debugInfo__get, __set, __isset, __unset__call и __callStatic__clone и клонирование объектов__serialize и __unserializeИтоги — Кастомная коллекция11Система типов и обработка ошибок
Объявление типовNullable-типыТипы объединения и пересеченияКлассы исключенийИерархия пользовательских исключенийTry, Catch, FinallyИтоги — Валидатор форм14Проект: Управление библиотекой
Обзор проектаКлассы Book и User3Свойства классов
Свойства экземпляра и статические свойстваКонстанты в классахСтатические методы и свойстваПриватные и защищенные свойстваСвойства Readonly (PHP 8.1)Итоги — Менеджер банковского счета6Полиморфизм
Снова о переопределении методовПолиморфизм через интерфейсыType Hinting и Union TypesПозднее статическое связываниеИтоги — Payment Processor9Трейты
Введение в трейтыИспользование нескольких трейтовРазрешение конфликтов трейтовАбстрактные методы в трейтахТрейты и наследование12Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн ObserverПаттерн Strategy