Menu
Coddy logo textTech

Стандарт автозагрузки 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. Это соглашение упрощает навигацию по проектам и их поддержку.

challenge icon

Задание

Легко

Давайте создадим простую систему автозагрузки 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")
?>
quiz iconПроверьте себя

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

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