Как работает автозагрузка PHP
Автозагрузчик PHP автоматически подключает файл класса при первом обращении к нему. Без автозагрузчика нужно было бы вручную писать require для каждого файла. Composer генерирует автозагрузчик на основе правил из composer.json.
Типы автозагрузки в Composer
| Тип | Описание | Производительность |
|---|---|---|
PSR-4 | Пространства имён → директории | Хорошая |
PSR-0 | Устаревший стандарт | Хуже PSR-4 |
classmap | Заранее составленная карта классов | Лучшая (production) |
files | Всегда подключаемые файлы | — |
Оптимизация автозагрузчика для production
# Базовая оптимизация — генерирует classmap для всех PSR-4 классов
composer dump-autoload --optimize
# С отключением dev-зависимостей
composer dump-autoload --optimize --no-dev
# APCu кэш (самый быстрый)
composer dump-autoload --apcu --optimize --no-devAPCu autoloader (максимальная скорость)
APCu кэширует результаты поиска классов в памяти. Требует расширение php-apcu:
sudo apt install php8.2-apcu
# В composer.json:
{
"config": {
"apcu-autoloader": true
}
}Конфигурация autoload в composer.json
{
"autoload": {
"psr-4": {
"App\\": "src/",
"Tests\\": "tests/"
},
"classmap": [
"database/seeds",
"database/factories"
],
"files": [
"src/helpers.php"
]
}
}Laravel: полная оптимизация для production
# Оптимизировать все кэши
php artisan optimize
# Что делает optimize:
# php artisan config:cache
# php artisan route:cache
# php artisan view:cache
# composer dump-autoload --optimizeПроверка автозагрузки
# Посмотреть сгенерированный classmap
cat vendor/composer/autoload_classmap.php | head -20
# Размер autoloader файлов
du -sh vendor/composer/Типичные ошибки автозагрузки
Class not found после деплоя
PHP Fatal error: Uncaught Error: Class "App\\Services\\PaymentService" not found in /var/www/html/public/index.php:12Файл vendor/composer/autoload_classmap.php — статичный снимок, составленный на момент запуска dump-autoload. Если после этого добавили новый класс, а автозагрузчик не перегенерировали, PHP просто не знает о нём. То же случается, если в CI собрали classmap на одной ветке, а задеплоили другую.
Failed opening required vendor/autoload.php
PHP Fatal error: Uncaught Error: Failed opening required 'vendor/autoload.php' (include_path='.:/usr/share/php') in /var/www/html/public/index.php:3Папка vendor/ обычно не попадает в git — если на сервере после деплоя не выполнили composer install, автозагрузчика физически нет.
Когда classmap-оптимизация не подходит
- Активная разработка с частым добавлением классов: после каждого нового класса нужно перегенерировать карту — забыли, получите «Class not found» ровно как в примере выше.
- APCu-кэш живёт в памяти конкретного воркера: после деплоя новой версии кода его нужно сбрасывать отдельно, иначе воркер продолжит искать старые пути к файлам.
- Библиотеки, создающие классы динамически во время выполнения (
eval, рантайм-class_alias), не всегда попадают в classmap корректно — для них остаётся обычный PSR-4 поиск.
Проверка результата
# Подробный вывод покажет число классов в карте
composer dump-autoload --optimize -v
# Generated optimized autoload files containing 4821 classes
# Убедиться, что конкретный класс виден автозагрузчику
php -r "var_dump(class_exists('App\\Services\\PaymentService'));"Если после установки Composer и оптимизации класс всё ещё не находится — проверьте, что namespace в коде совпадает с ключом psr-4 в composer.json побуквенно, включая регистр: на Linux файловая система чувствительна к регистру, в отличие от Windows, где ошибка может не проявиться у разработчика, но вылезет на проде.
| Режим генерации | Нужна перегенерация после нового класса | Где уместен |
|---|---|---|
| Без флагов | Нет, ищет по правилам PSR-4 на лету | Локальная разработка |
--optimize | Да, classmap статичен | Стейджинг, CI |
--optimize --apcu | Да, плюс сброс APCu на деплое | Продакшн с постоянными воркерами |
Ключевая мысль этой таблицы: чем агрессивнее оптимизация автозагрузчика, тем строже требование не забывать перегенерировать его после каждого изменения состава классов — это плата за скорость.
На практике команду для деплоя стоит зафиксировать в скрипте сборки раз и навсегда, а не набирать вручную каждый раз — человеческий фактор здесь надёжно устраняется автоматизацией, а не памятью разработчика.
Проверяйте также опцию optimize-autoloader прямо в секции config файла composer.json — тогда флаг --optimize применяется автоматически при любом запуске composer install, и его не нужно помнить отдельно для каждого окружения.