Class not found - причины по убыванию частоты
Страница падает с фатальной ошибкой вида «Class Bitrix\Sale\Order not found» или с именем собственного класса проекта. Разбираем причины по убыванию частоты, начиная с подключения того модуля, которому принадлежит класс.
С чего начать
Смотрим, доступен ли класс автозагрузке:
var_dump(class_exists('\Bitrix\Sale\Order')); // без подключения модуля будет falsevar_dump(\Bitrix\Main\Loader::includeModule('sale')); // подключение возвращает признак успехаvar_dump(class_exists('\Bitrix\Sale\Order')); // после подключения класс обязан находиться// имя класса пишут полностью, вместе с пространством имён и ведущим слэшемРазница между двумя проверками отвечает на главный вопрос сразу. Класс, который появился после подключения модуля, означает забытый вызов подключения, а не поломку автозагрузки.
Проверяем, установлен ли модуль вообще:
$name = 'sale';printf("установлен: %s, подключается: %s\n", \Bitrix\Main\ModuleManager::isModuleInstalled($name) ? 'да' : 'нет', \Bitrix\Main\Loader::includeModule($name) ? 'да' : 'нет');// у стороннего решения имя модуля пишут с точкой: vendor.solutionСмотрим регистрацию своих классов:
// include.php своего модуля\Bitrix\Main\Loader::registerNamespace('Vendor\Module', __DIR__ . '/lib');// PSR-4: имя файла повторяет имя класса в нижнем регистре\Bitrix\Main\Loader::registerAutoLoadClasses('vendor.module', ['Vendor\Module\Helper' => 'lib/helper.php']);// вторая форма - явная карта классов, она нужна для нестандартных путейСверяем регистр имени файла:
ls -la /home/bitrix/www/local/modules/vendor.module/lib/grep -rn 'namespace\|^class' /home/bitrix/www/local/modules/vendor.module/lib/helper.php# на боевом сервере регистр важен, а на локальной машине разработчика обычно нетПричины
-
Модуль не подключён перед обращением к классу примерно 35% случаев
ПризнакВ имени класса видно пространство имён платформы: продажи, каталог, инфоблоки.
ПроверкаПроверяем наличие класса до и после подключения модуля прямо в упавшем файле проекта.
Что делатьПодключаем модуль вызовом загрузчика и обязательно проверяем признак успеха, который он вернул.
-
Свой класс не зарегистрирован в автозагрузке примерно 25% случаев
ПризнакОшибка приходит на классе проекта, а файл с этим классом лежит на месте.
ПроверкаСмотрим регистрацию пространства имён или карты классов в файле подключения своего модуля.
Что делатьРегистрируем пространство имён по стандарту либо добавляем класс в явную карту автозагрузки.
-
Разошёлся регистр имени файла или пространства имён примерно 20% случаев
ПризнакНа машине разработчика код работает, а на боевом сервере падает с той же строкой.
ПроверкаСверяем имя файла, имя класса и объявленное в нём пространство имён строго посимвольно.
Что делатьПриводим имя файла к нижнему регистру, а пространство имён - к пути каталогов.
-
Не выложена или не подключена папка библиотек примерно 12% случаев
ПризнакПадает класс сторонней библиотеки, установленной в проект пакетным менеджером.
ПроверкаПроверяем наличие папки библиотек на боевом сервере и подключение её загрузчика в проекте.
Что делатьВыкладываем папку библиотек вместе с кодом либо ставим зависимости на самом сервере.
-
Класс исчез после обновления решения примерно 8% случаев
ПризнакОшибка появилась сразу после обновления модуля Маркетплейса или ядра платформы.
ПроверкаИщем имя класса по коду решения и смотрим историю обновлений этого модуля.
Что делатьПравим вызов под новое имя класса либо откатываем обновление до разбора с автором.
Частые вопросы
Чем эта ошибка отличается от «Call to undefined function»?
Здесь не найден класс, там - функция, и причины разные. Классы приходят из автозагрузки модулей, функции - из подключённых файлов и расширений языка.
Нужно ли подключать модуль в каждом файле?
Да, в каждой точке входа, где используются его классы. Подключение дешёвое и повторный вызов ничего не ломает: загрузчик помнит уже подключённые модули.
Почему на стенде работает, а на сервере нет?
Файловая система стенда обычно нечувствительна к регистру, а на сервере регистр важен. Имя файла класса приводят к нижнему регистру и сверяют с пространством имён.
Где регистрировать свои классы?
В файле подключения своего модуля: пространство имён по стандарту либо явная карта классов. Регистрация обязана выполняться до первого обращения к классу.
Что делать с классами сторонней библиотеки?
Убедиться, что папка библиотек выложена на сервер и её загрузчик подключён в проекте. Папку либо кладут в репозиторий, либо ставят зависимости на сервере при выкладке.
Смежное
- Ошибки сервера и базы - оглавление подтемы
- Call to undefined function: причины по убыванию частоты - соседний разбор про функции
- Свой модуль: структура, установка, автозагрузка классов - как устроена регистрация классов модуля
- Свой модуль не устанавливается: разбор причин - когда модуля нет в списке установленных
- Сторонняя библиотека в проекте: composer, автозагрузка, выкладка - папка библиотек и её выкладка
- После выкладки сайт сломался: разбор причин - когда ошибка появилась после релиза
- Отладка на боевом сайте: журналы, режим ошибок, поиск виновника - где искать полный текст ошибки
- Инфраструктура и эксплуатация - устройство серверной части целиком