PHP Fatal error: Declaration of Bitrix\Main\Diag\Logger::log($level, Stringable|string $message, array $context = []): void must be compatible with Psr\Log\LoggerInterface::log($level, $message, array $context = []) in ..../bitrix/modules/main/lib/diag/logger.php
Столкнулись с ошибкой, которую не удается зафиксировать в exception_handling 1С-Битрикс. Происходит фатальное исключение при попытке записать исключение в лог.
Обратитесь в «Техдиректор» за помощью, если сталкиваетесь с проблемой на вашем проекте.
Причина: 1. В главном модуле обновился пакет psr/log - для аргументов функции добавлено указание типов. 2. Класс для логирования exception_handling (Bitrix\Main\Diag\Logger) теперь так же реализует интерфейс с типами аргументов. 3. В проекте может быть загружена старая версия psr/log (без указания типов). Например, в php_interface или стороннем модуле.
Как происходит: 1. Класс Psr\Log\LoggerInterface загружается из старой версии psr/log (пункт №3) 2. Exception_handling 1С-Битрикс загружает Bitrix\Main\Diag\Logger (пункт №2). 3. PHP выбрасывает исключение, т.к. Bitrix\Main\Diag\Logger сужает набор типов аргумента относительно интерфейса. В PHP при наследовании можно только расширять набор типов аргументов функции или сужать тип возвращаемого значения ^1.
Как найти ошибку, если ничего не выводится и exception_handling не работает: 1. Проверьте error_log веб-сервера или файл, указанный в php.ini для error_log. 2. В начале скрипта вставьте register_shutdown_function с выводом последней зарегистрированной ошибки. Если в браузере не получается вывести ошибку, заполните $_SERVER['DOCUMENT_ROOT'] и запустите скрипт через ssh.
//$_SERVER['DOCUMENT_ROOT'] = ....; use for cli
register_shutdown_function(function() {
print_r(error_get_last());
});
Как найти старую версию psr/log, если столкнулись с таким текстом ошибки: 1. Перед строкой с проблемой можно вставить (например, в init.php). Обратите внимание, может давать разный результат в зависимости от порядка автозагрузки классов
$reflection = new ReflectionClass(\Psr\Log\LoggerInterface::class);
echo $reflection->getFileName();
2. Выполнить через ssh в директории сайта grep -r "namespace Psr\\\\Log;" --include=*.php . 3. Оригинальный psr/log лежит в файле bitrix/modules/main/vendor/psr/log/src/LoggerInterface.php. Если нашли имеено его, воспользуйтесь вторым вариантом поиска.
Что делать: 1. Удалить папку со старым psr/log, если расположена вне модуля. 2. Если расположена внутри модуля, переименовать папку psr/log внутри модуля. Написать разработчикам модуля. 3. Проверить, что сайт продолжает работать. В командной PHP-строке административной панели выполнить throw new RuntimeException('dummy');, проверить результат в логе exception_handling.
Чтобы избежать конфликта, устанавливайте зависимости composer, отключая загрузку пакетов, которые уже есть в главном модуле с помощью параметра replace. Для поддержки старых версий модуля main, реализуйте условный загрузчик на примере модуля techdir.sentry.
Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».