Многие владельцы Битрикса видят с января 2023 года эту неприятную надпись. Давайте будем разбираться, как технически осуществить данный переезд.
Правильный алгоритм переезда Битрикса на PHP8
- Делаем бэкап текущего сайта
- Разворачиваем его на DEV версии под php7
- Обновляем на DEV ядро Битрикса
- Меняем на DEV сервере версию php на восьмую
- Смотрим, работает ли админка. Если нет - устраняем ошибки (скорее всего они будут в сторонних модулях), добиваемся работоспособности.
- Запускаем проверку системы, не должно быть ошибок
- Переходим в публичную часть сайта и проверяем основной функционал, если есть ошибки - устраняем
- Ещё раз всё перепроверяем, добиваемся отсутствия ошибок
- Переезжаем на PROD (боевой) сервер
Конечно, многие пункты весьма трудоемки. Ниже мы собрали наиболее типовые ошибки, возникающие при обновлении PHP
Ошибки при обновлении версии PHP для Битрикса (обновляется)
1. В списке модулей есть пустые строки
Может проявляться примерно так
[Ux11] Ошибка описания модуля "название.модуля".
Не установлено соединение с сервером обновлений. [Ux11] Ошибка описания модуля "название.модуля"
В этом случае в файле install/index.php функцию module_name() заменяем на __construct()
2. Ошибка работы со статическими методами
Проявляется примерно так:
call_user_func_array(): Argument #1 ($function) must be a valid callback, non-static method
Лечится следующим образом: в папке модуля (/bitrix/modules/проблемный_модуль) нужно в классах найти проблемный метод и дописать слово static. Получится примерно так:
static function MyFunction()
Эту операцию возможно нужно будет повторить много-много раз.
3. Ошибка в функции count()
В php 8 функция count стала требовать строго типизированный параметр. Ранее в случае подачи некорректного параметра функция возвращался false, теперь же возвращает fatal error
count(): Argument #1 ($value) must be of type Countable|array, null given (0)
Проще всего сделать своеобразное "переопределение" функции, например таким образом:
function php7_count($ar) {
if (is_array($ar)) {
return count($ar);
}
return false;
}
И потом рекурсивно пробежать по сторонним модулям и используемым шаблонам, подменить count( на php7_count. Массово это можно сделать с помощью Notepad++.
4. Ошибка в функции impode()
Возникает не так часто, как count(), выглядит примерно так:
implode(): Argument #2 ($array) must be of type ?array, string given (0)
Опять же, нет проверки на массив, который подается на вход функции
Решается следующим образом:
if (is_array ($ar)) {
$arRes = implode(';', $ar);
}
Для уверенности лучше рекурсивно прогнать по всем скриптам сайта и поискать вхождения функции impode.
5. Ошибка с фигурными скобками
В предыдущих версиях PHP к элементам массива можно было обращаться и через квадратные, и через фигурные скобки. В PHP8 поддержка фигурных скобок в этом контексте запрещена.
Ошибка проявляется так:
Fatal error: Array and string offset access syntax with curly braces is no longer supported in путь/к/вашему/скрипту
Решается путем замены фигурных скобок на квадратные
6. Проблема с функцией each()
В версии PHP 8 удалена функция each. Ошибка проявляется так:
Call to undefined function each()
Исправляется заменой функции на следующую:
function php7_each(&$data) {
$key = key($data);
$ret = ($key === null)? false: [$key, current($data), ‘key’ => $key, ‘value’ => current($data)];
next($data);
return $ret;
}
и вызываться она должна с предварительной проверкой на переменную-массив:
if (is_array($arData)) {
$result= php7_each($arData);
}
Всё, это должно помочь
7. Ошибки с преобразованием типов
Данный класс ошибок проявляется примерно так
Unsupported operand types: string * int (0)
Для решения нужно явно привести типы. Например, так:
$int_value = (int)$maybe_string_value
Раньше было допустимо просто строковое значение умножать на единицу и получать int значение. Теперь - нет.
8. Ошибка с типами данных в операциях
Раньше можно было выполнять арифметические операции без явного приведения типов. В PHP8 необходимо строго указать тип, иначе появляется ошибка вида
Fatal error: Uncaught Error: Unsupported operand types: string - string
Вместо минуса может быть любой оператор.
Чтобы устранить ошибку, необходимо явно задать тип переменным, например, так:
$a = (int)$b - (int)$c;
9. Недопустимый тип смещения
Illegal offset type (0)
У меня подобная ситуация встретился в компоненте news.list. Оказалось, что при вызове компонента в качестве PROPERTY_CODE прилетал пустой массив. Ранее это вызывало лишь warning, теперь же в версии php 8 это стало fatal error. Лечится путем анализа каждого конкретного случая отдельно и не поддается общему решению.
10. Ошибка в функции number_format
Проявление ошибки:
[TypeError] number_format(): Argument #1 ($num) must be of type float, string given (0)
В функцию на вход должно подаваться число, если подается строка или null, то теперь выдает ошибку. Решение простое, через явное преобразование типов floatval:
number_format(floatval($price), 2,'.', ' ')
11. Ошибка в присвоении переменной
[TypeError]
Unsupported operand types: bool | array (0)
Это подразумевает выборку одной из двух переменных, следующих после символов. Чаще всего достаточно просто оставить знак равенства
12. Невозможно получить доступ к переменной
[TypeError]
Cannot access offset of type string on string (0)
Решается следующей проверкой
if (!empty($a['VALUE']) && is_array($a['VALUE']))
Продолжение следует..
Полезные SSH команды для упрощения обновления
поиск содержимого в файлах
grep -il *.php "find_text"
Что делать если нет доверенного разработчика?
Можете обратиться в Брейнфорс, помогут аккуратно провести обновление битрикс до php 8
Больше полезных материалов в нашем Telegram канале. Вступайте и будем на связи! https://t.me/bf_conversion
Комментарии 2