Class not found в Yii2: где искать проблему с автозагрузкой

Ошибка Class not found в Yii2 обычно выглядит простой: приложение не нашло класс. Но причина не всегда в том, что файла нет. На практике часто мешает неправильный namespace, регистр букв в имени файла, не обновлённый Composer autoload, неполный деплой или различие между Windows и Linux.

Разбирать такую ошибку лучше от конкретного класса. В сообщении обычно указано полное имя, которое пытался загрузить PHP. Это и есть точка старта.

Проверить namespace и путь к файлу

Если класс называется app\services\OrderService, файл обычно должен лежать примерно так:

services/OrderService.php

Внутри файла namespace должен совпадать с расположением:

<?php

namespace app\services;

class OrderService
{
}

Частая ошибка — файл лежит в services, а namespace указан app\helpers. На локальном проекте это иногда долго не замечают, если класс раньше подключался другим способом или лежал в кэше IDE.

Регистр букв важен

На Windows и некоторых локальных окружениях файловая система не чувствительна к регистру. На Linux сервере чувствительна. Поэтому файл orderservice.php может работать локально и падать на production, где код ожидает OrderService.php.

ls -la services
grep -R "class OrderService" -n .

Для Yii2 и Composer лучше держать одинаковый регистр в имени класса, имени файла и use-импорте.

use app\services\OrderService;

Composer autoload

Если класс находится в namespace, который грузится через Composer, после добавления файлов иногда нужно пересобрать autoload.

composer dump-autoload

На production обычно используют оптимизированную автозагрузку:

composer dump-autoload -o

Если после деплоя vendor не обновлялся, а composer.lock изменился, нужно выполнить install:

composer install --no-dev --prefer-dist --optimize-autoloader

Проверить composer.json

Для нестандартных директорий нужно проверить секцию autoload. Например, старый код может подключаться через classmap.

{
    "autoload": {
        "psr-4": {
            "app\\": ""
        },
        "classmap": [
            "legacy/classes"
        ]
    }
}

Если директорию с legacy-классами перенесли, а composer.json не обновили, автозагрузка перестанет находить эти классы.

use, alias и полное имя класса

Иногда класс существует, но в коде указан неправильный use. Особенно это заметно, если в проекте есть классы с одинаковыми короткими именами.

use app\models\User;
use common\models\User;

В спорном месте можно временно указать полное имя класса, чтобы исключить ошибку alias:

$service = new \app\services\OrderService();

Модули Yii2

Если класс находится внутри модуля, namespace должен соответствовать модулю. Например:

namespace app\modules\admin\controllers;

class BlogController extends Controller
{
}

При переносе контроллера из обычной папки в модуль часто забывают обновить namespace и use. Ошибка может проявляться как Class not found или как 404, если Yii2 не может создать контроллер.

Кэш и opcache

После деплоя сервер может продолжать выполнять старую версию файлов из opcache. Это особенно неприятно, когда файл уже есть, а ошибка говорит, что класса нет.

php -i | grep opcache.validate_timestamps
sudo systemctl restart php8.2-fpm

Перезапуск PHP-FPM нужен не всегда, но если opcache настроен агрессивно, это нормальная часть деплоя.

Неполный деплой

Иногда причина совсем простая: файл не попал на сервер. Например, он не был добавлен в git или был исключён правилом deploy-скрипта.

git status
git ls-files | grep OrderService.php
git pull origin main

Если используется ручная загрузка по FTP, риск неполного деплоя выше. В таких проектах Class not found встречается особенно часто.

Чек-лист диагностики

  1. Скопировать полное имя класса из ошибки.
  2. Проверить файл и namespace.
  3. Проверить регистр букв в имени файла.
  4. Проверить use в месте вызова.
  5. Выполнить composer dump-autoload.
  6. Проверить composer.json, psr-4 и classmap.
  7. Проверить, что файл попал на сервер.
  8. Сбросить opcache или перезапустить PHP-FPM при необходимости.

Class not found редко требует сложного исправления. Обычно проблема в одном несоответствии между именем класса, файлом, namespace и автозагрузкой. Главное — не исправлять наугад, а проверить всю цепочку.

Комментарии (0)

Пока нет комментариев. Будьте первым!