Переезд WordPress сайта с PHP 5 на PHP 7 и PHP 8
Статья обновлена 15 января 2021 года.
Судя по многочисленным статьям в интернете переезжать с PHP 5 на PHP 7 и далее на PHP 8 определенно стоит. PHP 7.0 примерно в 2 раза быстрее чем PHP 5. PHP 7.4 уже примерно в 3 раза быстрее чем PHP 5. А PHP 8.0 от 15% до нескольких раз быстрее чем PHP 7.4 - скорость зависит от сложности приложения. Таким образом с помощью обновления версии PHP можно существенно снизить нагрузку на сервер, особенно если у вас достаточно нагруженные проекты.
Оглавление
Переезд с PHP 5 на PHP 7.2
Узнать свою версию PHP можно набрав в консоли сервера команду:
php -v
Сам движок WordPress последней версии поддерживает работу с PHP 7.2, поэтому при переезде проблемы могут возникнуть только с темой или плагинами WordPress, авторы которых не адаптировали их для работы с PHP 7.2. Как правило это старые темы и плагины, которые давно не обновлялись. У меня таких было несколько. К тому же у меня был самописный функционал, который также не вписывался в новые условия. Впрочем все удалось исправить.
Для отлавливания ошибок я использовал log-файл домена, который задан в конфигурации Nginx для домена в секции server вот такой директивой:
error_log /web/domain.ru/logs/error.log;
При открытии какой-либо страницы сайта, если в ней есть ошибки, то о них будет написано в файле /web/domain.ru/logs/error.log - новые записи появляются в конце.
Ниже приведены языковые конструкции в php-файлах сайта, которые необходимо заменить при переезде сайта с PHP 5 на PHP 7.2
В одном из моих самописных скриптов я использовал функцию strpos и на PHP 5 все работало как надо, а на PHP 7.2 все заработало нормально только после замены этой функции на mb_strpos. Видимо, PHP 7.2 строже работает с кодировками в строках.
$pos = strpos($out1, 'data-kor=', $k);
был заменен на:
$pos = mb_strpos($out1, 'data-kor=', $k);
В нескольких старых плагинах WordPress встретилась ошибка, когда параметр функции был указан без кавычек, после окружения его кавычками все наладилось.
function fndkor(par) {
был заменен на:
function fndkor('par') {
В теме одного из сайтов встретились сложносочиненные переменные с двумя знаками $$ в результате чего тему перекосило, после наведения порядка в вызове переменной тема выстроилась так, как было задумано.
$$value['id']
был заменен на:
${$value['id']}
Также в самописных скриптах я использовал прием параметров методом POST, в случае, когда параметр необязательный, то во избежание ошибок в error.log лучше устроить ему проверку на этапе приема.
$pr = $_POST['pr'];
был заменен на:
if (isset($_POST['pr'])) {$pr = $_POST['pr'];} else {$pr = '';}
Аналогично с приемом параметров методом GET:
$fi = (int)$_GET['fi'];
был заменен на:
if (isset($_GET['fi'])) {$fi = (int)$_GET['fi'];} else {$fi = 0;}
Обращение к базе данных в PHP 5 происходило с помощью устаревшей в PHP 7.2 процедуры. Такие обращения я использовал в своих самописных скриптах и пожалуй, адаптация в этой части была самой трудоемкой при переезде на PHP 7.2. Соединение с базой данных.
$connection = mysql_connect($host,$user,$pass); if(!$connection) { die('Соединение с сервером MySQL неудачно: '.mysql_error()); } $select_db = mysql_select_db($db, $connection); if(!$select_db) { die('Соединение с базой данных неудачно: '.mysql_error()); }
был заменен на:
$mysqli = mysqli_connect($host,$user,$pass,$db); if ($mysqli->connect_errno) {printf("Connect failed: %s\n", $mysqli->connect_error); exit();}
Установка кодировки при работе со строками в БД.
mysql_query('SET NAMES utf8 COLLATE utf8_general_ci');
был заменен на:
$mysqli->query('SET NAMES utf8 COLLATE utf8_general_ci');
Получение результата запроса к БД.
$result = mysql_query($query) or die(mysql_error() ." ". $query);
был заменен на:
$result = $mysqli->query($query); if (!$result) {printf("Errormessage: %s\n", $mysqli->error);}
Получение количества строк в результате запроса к БД.
$num_rows = mysql_num_rows($result);
был заменен на:
$num_rows = mysqli_num_rows($result);
Работа с рядом результата запроса к БД.
while ($row = mysql_fetch_assoc($result)) {
был заменен на:
while ($row = mysqli_fetch_assoc($result)) {
Освобождение результата запроса от ранее полученных данных.
mysql_free_result($result);
был заменен на:
mysqli_free_result($result);
Отключение от БД.
$close_result = mysql_close($connection); if (false === $close_result) die ('Error database close');
был заменен на:
mysqli_close($mysqli);
Приведение строки в надлежащий вид перед записью в БД
$str = mysql_escape_string($str);
был заменен на:
// Здесь $mysqli - переменная подключения к БД $str = mysqli_escape_string($mysqli, $str);
Кое-где я использовал функцию mysql_escape_string внутри своей функции, поэтому переменную соединения с базой данных нужно подключить внутри нее как глобальную.
function naborId($str) { $str = mysql_escape_string($str); }
был заменен на:
function naborId($str) { global $mysqli; $str = mysqli_escape_string($mysqli, $str); }
Также при этом нужно учитывать, чтобы вызов функции naborId, в которой используется функция mysqli_escape_string, происходил после того как было установлено соединение с базой данных.
В некоторых своих скриптах я раньше использовал функцию mysql_escape_string вообще не обращаясь к базе данных, в этих местах я заменил ее функцией addslashes.
Переезд с PHP 7.2 на PHP 8.0
WordPress начиная с версии 5.6 официально поддерживает PHP 8.0, значит ошибки могут возникнуть только в старых, давно не обновлявшихся плагинах и таких же WordPress-темах.
У меня в паре старых плагинов WordPress встретилась ошибка, когда значение массива вызывалось в устаревшей записи через фигурные скобки, вместо современного через квадратные скобки. Конструкции подобные этой:
$pr{$type}
были заменены на:
$pr[$type]
При неопределённости в регулярных выражениях PHP 8 выдаёт ошибку. Знак дефиса, если это не указание диапазона, а символ сам по себе, теперь нужно экранировать обратным слэшем. Конструкции подобные этой:
preg_match("/^[\w-:]+$/", $tag)
были заменены на:
preg_match("/^[\w\-:]+$/", $tag)
Кое-где понадобились дополнительные проверки. Такой код:
$settings['parent'] = $this->settings['id'];
был заменён на:
if (isset($settings['parent'])) {$settings['parent'] = $this->settings['id'];}
Также PHP 8 стал строже к неопределённым переменным. Чтобы не было ошибок все переменные перед использованием нужно явно определить. Такой код:
$arr = myfunc();
$k = $arr[1];
был заменён на:
$arr = array();
$arr = myfunc();
$k = $arr[1];
Больше ошибок не было.
Поделиться статьей:
Привет, спасибо за пост !
А насколько увеличилось скорость сайт в целом ?
Почувствовали разницу в скорости после перехода на php 7.2 ?
Хочу понять, стоит ли обновлять версию php na 7.2 ?
Увеличилась, специально не замерял, но например, phpinfo() даже невооруженным глазом видно, что загружается существенно быстрее, чем на PHP5.