После перевода нескольких десятков сайтов на 1С Битрикс с php 7.4 на php 8.1 собрал в статье полезные решения ошибок.
Сделаю краткий обзор основных типов ошибок и приведу решения их устранения.
1. Не статичный метод вызывается статично
[TypeError]
call_user_func_array(): Argument #1 ($callback) must be a valid callback, non-static method CKladr::SetLocation() cannot be called statically (0)
Решение:Находим файл, в котором прописан метод CKladr::SetLocation и указываем у него static
Пример:
public static function SetLocation(){
...
}
2. Нет проверки типа данных при использовании функции для определенно типа данных
php 8 стал более строгий, теперь переменные нужно проверять перед использованием методом, относящихся к определенному типу данных
1. Fatal error: Uncaught TypeError: count(): Argument #1 ($value) must be of type Countable|array, bool given in /home/bitrix/ext_www/cin.ru/bitrix/modules/security/classes/general/antivirus.php:559
Решение:Делаем проверку типа данных.
Пример 1. Проверка массива:
[TypeError]
implode(): Argument #2 ($array) must be of type ?array, string given (0)
[TypeError]
array_key_exists(): Argument #2 ($array) must be of type array, string given (0)
[TypeError]
count(): Argument #1 ($value) must be of type Countable|array, null given (0)
[TypeError]
array_filter(): Argument #1 ($array) must be of type array, bool given (0)
[TypeError]
array_multisort(): Argument #1 ($array) must be an array or a sort flag (0)
[TypeError]
array_unique(): Argument #1 ($array) must be of type array, null given (0)
[TypeError]
in_array(): Argument #2 ($haystack) must be of type array, bool given (0)
Решение:
if(is_array($ar) && count($ar)>5){
...
}
Пример 3. Проверка массива:
[TypeError]
array_key_exists(): Argument #2 ($array) must be of type array, string given (0)
Решение:
if(!array_key_exists($arFirstLvl, $arItem['IBLOCK_SECTION_ID'])){
меняем на
if(is_array($arItem['IBLOCK_SECTION_ID']) && !array_key_exists($arFirstLvl, $arItem['IBLOCK_SECTION_ID'])){
Пример 4. Проверка массива:
[TypeError]
array_filter(): Argument #1 ($array) must be of type array, bool given (0)
Решение:
$arItem['PROPERTIES']['SIMILAR_SWITCH']['VALUE'] = array_filter($arItem['PROPERTIES']['SIMILAR_SWITCH']['VALUE']);
меняем на
if(is_array($arItem['PROPERTIES']['SIMILAR_SWITCH']['VALUE'])){
$arItem['PROPERTIES']['SIMILAR_SWITCH']['VALUE'] = array_filter($arItem['PROPERTIES']['SIMILAR_SWITCH']['VALUE']);
}
Пример 5. Проверка числа:
[TypeError]
gmdate(): Argument #2 ($timestamp) must be of type ?int, string given (0)
Решение:
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $lastModified) . ' GMT');
to
if(intval($lastModified)>0){
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $lastModified) . ' GMT');
}
3. Не статичный метод не может быть определен как статичный
[Error]
Non-static method Countrymask\Unitools::isAdminPage() cannot be called statically (0)
Возможно метод по ошибке установлен как static
заменяем
public static function Location(){
...
}
на
public function Location(){
...
}
4. Не отображаются наименования сторонних модулей в меню настроек модулей
В стороннем модуле может не быть конструктора и лэнги задаются в методе одноименным с классом. В php 7.4 это работало, но в php 8.1 нужно использовать __construct():
function recaptchafree()
{
$this->MODULE_NAME = GetMessage("CAPTCHA_INSTALL_NAME");
$this->MODULE_DESCRIPTION = GetMessage("CAPTCHA_INSTALL_DESCRIPTION");
...
}
заменяем на
function __construct()
{
$this->MODULE_NAME = GetMessage("CAPTCHA_INSTALL_NAME");
$this->MODULE_DESCRIPTION = GetMessage("CAPTCHA_INSTALL_DESCRIPTION");
...
}
5. Ключ в массиве, заданный без кавычек, будет обрабатываться как константа.
Если константа не определена, то появляется соответствующая ошибка:
Undefined constant "HTTP_USER_AGENT" (0)
Самая частая ошибка, обязательно у ключа в ассоциативном массиве должны быть кавычки:
$_SERVER[HTTP_USER_AGENT]
заменяем на
$_SERVER['HTTP_USER_AGENT']
6. В некоторых функциях обязательно должен быть задан аргумент.
[ArgumentCountError]
mktime() expects at least 1 argument, 0 given (0)
Пример:
заменяем
mktime()
на
mktime(0)
7. Синтаксис доступа к смещению массива и строки с фигурными скобками больше не поддерживается.
[ErrorException] E_COMPILE_ERROR
Array and string offset access syntax with curly braces is no longer supported (0)
Пример:
$type0 = $type{0};
меняем на
if(!is_array($type[0])){
$type0 = $type[0];
}
8. На php 8.0 работает, ошибки php показывает, но на php 8.1 выдает 502 Bad Gateway
В модуле Проактивная защита ставим исключение: Маски исключения: /bitrix/*Теги: php8, TypeError, Fatal error, Error, ошибки php, Undefined constant, ErrorException