Menu
Coddy logo textTech

Стандарт автозагрузки PSR-4

Часть раздела Объектно-ориентированное программирование путешествия по PHP на Coddy. Урок 12 из 91.

PSR-4 — это стандарт, который определяет, как классы PHP должны автоматически загружаться на основе их пространства имён и расположения файла. Вместо того чтобы вручную подключать файл каждого класса, PSR-4 позволяет PHP автоматически находить и загружать классы при их использовании.

Основное правило простое: namespace должен соответствовать структуре directory. Если у вас есть class App\Models\User, file должен находиться по адресу App/Models/User.php.

<?php
// Файл: src/Models/User.php
namespace App\Models;

class User {
    public $name;
    
    public function __construct($name) {
        $this->name = $name;
    }
}

Вы можете написать простую функцию autoloader, которая соответствует правилам 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, что нужно вызывать вашу функцию всякий раз, когда встречается неизвестный class. Функция преобразует namespace в path к файлу и загружает его.

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

challenge icon

Задание

Легко

Давайте создадим простую систему автозагрузки PSR-4, которая автоматически загружает классы на основе их пространства имён и расположения file.

Вы создадите проект с тремя file, демонстрирующими, как PSR-4 сопоставляет пространства имён с путями directory:

  • src/Services/Logger.php: Define класс Logger в пространстве имён App\Services. У него должно быть свойство public $name, constructor, который принимает и устанавливает имя, и method log($message), возвращающий "[name] logged: [message]".
  • src/Services/Mailer.php: Define класс Mailer в пространстве имён App\Services. У него должно быть свойство public $sender, constructor, который принимает и устанавливает отправителя, и method send($to), возвращающий "Mail from [sender] to [to]".
  • main.php: Create автозагрузчик PSR-4 с использованием spl_autoload_register, который сопоставляет prefix пространства имён App\ с directory src/. Автозагрузчик должен преобразовать разделители пространства имён в разделители directory и append .php, чтобы найти нужный file. После регистрации автозагрузчика используйте keyword use, чтобы import оба класса, затем создайте Logger с именем "FileLogger" и Mailer с отправителем "admin@site.com". Print результат вызова log("System started") для logger и send("user@example.com") для mailer, каждый результат — в отдельной строке.

Основная идея заключается в том, что ваша функция autoloader получает полное имя класса (например, App\Services\Logger) и должна преобразовать его в путь к file (src/Services/Logger.php). Используйте strpos, чтобы проверить, начинается ли класс с вашего prefix пространства имён, substr, чтобы получить относительное имя класса, и str_replace, чтобы преобразовать обратные косые черты в прямые косые черты.

Попробуйте сами

<?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")
?>
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор PHP