1. Home
  2. Техническое
  3. PHP
  4. Как протестировать и обновить виртуальные серверы с устаревшей версией PHP?

Как протестировать и обновить виртуальные серверы с устаревшей версией PHP?

Тестирование версии PHP

Если на некоторых ваших виртуальных серверах используются устаревшие версии PHP, на странице обзора услуг Мой Zone появится предупреждение.

 

Нажав на кнопку Посмотреть в верхней части страницы, вы попадете на обзорную страницу, показывающую истекшие PHP-хосты (основные и поддомены) на сервере.

Поскольку изменение версии PHP может привести к появлению сообщений об ошибках на сайте, а изменение версии может занять до 3 минут, рекомендуется проверить работоспособность страницы перед внесением изменений.

Для проверки нажмите на нужный адрес в списке:

Откроется тестовая страница с выбором версий PHP в заголовке. Выбирая между ними, вы увидите результат с разными версиями PHP. Например:

PHP 5.6:

PHP 8.1:

Минимальная версия PHP, которую Zone позволяет вам выбрать, это PHP 5.6, но имейте в виду, что она также устарела – в ней больше нет исправлений разработчиков для уязвимостей безопасности, хотя технически ее еще можно поддерживать. Рекомендуется обновить PHP до версии 8.0, поскольку PHP 5.6 также устарел и больше не получает обновлений безопасности.

Для современных веб-приложений, таких как WordPress, мы рекомендуем вам попробовать перейти на PHP 8.0 или 8.1, заранее обновив темы и плагины WordPress.

Для не обновленных веб-приложений переход на PHP 8.x может быть затруднен из-за огромной разницы между 5.6 и 7.x.

Наиболее распространенные ошибки при обновлении версий

Вопросительные знаки вместо диакритических букв (äöüõ и т.д.)

PHP 5.6 добавляет заголовок, указывающий на использование кодировки UTF-8 на страницах по умолчанию; для страниц, использующих более старые кодировки, его следует удалить, а определение кодировки оставить на усмотрение браузера.

Самый простой способ сделать это – добавить в папку htdocs файл .user.ini с настройкой:

default_charset = ''

Ошибка Fatal error […]

Веб-страница не отображается, а в верхней части страницы появляется сообщение, например:

Fatal error: Call to undefined function session_register() in [...]
Fatal error: Call to undefined function sqlite_open() in [...]
Fatal error: Call to undefined function wp_script_add_data() in [...]
Fatal error: Call-time pass-by-reference has been removed in [...]

Это вызов функции, которая была удалена из языка PHP или не может быть зарегистрирована из-за проблем с обновлением.

Исключение Call-time pass-by-reference has been
removed
связано с изменением синтаксиса PHP.

Для того чтобы обновить приложение до новой версии PHP, необходимо определить точную причину ошибки и исправить код.

Ошибка Fatal error: Incompatible file format

Веб-страница не отображается, а в верхней части страницы появляется сообщение об ошибке:

Fatal error: Incompatible file format: The encoded file has
format major ID 1, whereas the Loader expects 7
in /data[...]/htdocs/index.php on line 0

Может встречаться в приложениях, зашифрованных/лицензированных с помощью Zend Guard, особенно в Saurus. Обновление PHP до версии 5.6 возможно только путем замены и обновления кода приложения (Saurus – последняя версия, предлагающая платную поддержку от Bonefarm). Веб можно преобразовать в статический HTML или перенести на современные системы управления контентом, например WordPress.

Ошибка Warning: Cannot modify header information […]

Это предупреждение будет показано, если в процессе создания страницы будут выданы другие предупреждения или сообщения об ошибках, которые не могут отправить заголовки HTTP-запросов:

Warning: Cannot modify header information -
headers already sent by (output started at [...]wp-db.php:57)
in [...]

Не имеет самостоятельного значения, может быть проигнорирована.

Ошибка Warning […]

При открытии веб-сайта в начале страницы или в каком-то ее компоненте появляется сообщение:

Warning: Creating default object from empty value in [...]
Warning: file_put_contents(): Filename cannot be empty in [...]
Warning: get_class() expects parameter 1 to be object, string given in [...]
Warning: getimagesize(): Filename cannot be empty in [...]
Warning: Illegal string offset 'face' in [...]
Warning: Invalid argument supplied for foreach() in [...]

Тип или значение параметра функции не соответствует ожидаемому, что означает, что некоторые функции веб-приложения могут работать не так, как предполагалось (чаще всего просто не предоставляя желаемого контента).

Если функциональность не важна, вы можете игнорировать и отключать Warning сообщения, добавив в корневой каталог веб-сервера htdocs файл .user.ini с конфигурацией:

error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED & ~E_WARNING

Настройка Zone по умолчанию: error_reporting = E_ALL & ~E_NOTICE
& ~E_STRICT & ~E_DEPRECATED

Ошибка Deprecated […]

При открытии веб-сайта в начале страницы или в каком-то ее компоненте появляется сообщение:

Deprecated: Assigning the return value of new by reference is deprecated in [...]
Deprecated: Function set_magic_quotes_runtime() is deprecated in [...]
Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in [...]
Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in [...]

Данная функция, параметр или синтаксис исчезнут в последующих версиях PHP, но это не повлияет на работу выбранной версии.

В виртуальных серверах Zone вывод сообщений Deprecated отключен по умолчанию, скорее всего, из-за изменения конфигурации в коде приложения, реже – через глобальный php.ini или .user.ini (см. пример в сообщении Warning).

Для определения местоположения настройки можно воспользоваться поиском в командной строке:

grep -r E_ALL .

Например, для OpenCart 1.5 это приведет к появлению следующих файлов:

./vqmod/vqcache/vq2-system_startup.php:error_reporting(E_ALL);
./system/startup.php:error_reporting(E_ALL);
./php.ini:;error_reporting = E_ALL;

В код PHP необходимо внести изменения  error_reporting( E_ALL &
~E_NOTICE & ~E_STRICT & ~E_DEPRECATED );
и в .ini файлах error_reporting = E_ALL & ~E_NOTICE &
~E_STRICT & ~E_DEPRECATED

Сбой подключения к базе данных

Если после перехода на версию PHP 5.6+ соединение с базой данных не происходит, проверьте, не использует ли пользователь базы данных старый 6-значный пароль (старый криптографический пароль).
Решение заключается в изменении пароля пользователя базы данных. Новый пароль будет работать и с версиями PHP старше 5.6.

Навигация не работает

Если навигация между страницами не работает или желаемое действие не происходит после отправки формы, это может быть связано с предположением, что суперглобальные массивы GET, POST, Cookie (EGPCS) зарегистрированы как обычные переменные.

Эта функция PHP была устаревшей в версии PHP 5.3.0 и удалена в версии PHP 5.4.0.

Например, меню веб-страницы содержит ссылки в строке запроса формы domeen.ee/?lk=1, а в PHP-файле, содержащем логику загрузки страницы, вместо суперглобального массива $_GET['lk'] используется переменная $lk.
Аналогично для отправки формы, где имя элемента формы <input type="submit"
name="form_1" value="Saada">
проверяется не по суперглобальному массиву $_POST['form_1'], а непосредственно по переменной $form_1.

Как убедиться, что сервер действительно использует новую версию?

Смена версии PHP на сервере занимает до 3 минут. Для проверки внедрения новой версии PHP рекомендуется создать файл .php с любым именем:

<?php
phpinfo();

Перейдя по адресу example.com/suvaline-nimi.php через веб-браузер, вы увидите версию PHP и все настройки (в целях безопасности мы рекомендуем удалить файл после этого).

Если окажется, что сайт не работает с более новой версией PHP, то в течение часа можно изменить версию PHP обратно. Это можно сделать в административном интерфейсе в настройках главного или поддомена.

PHP 5.6 → PHP 7.0

Изменилась обработка ошибок и исключений

<?php
// Код эпохи PHP 5, который больше не работает.
function handler(Exception $e) { ... }
set_exception_handler('handler');

// Совместим с PHP 5 и 7.
function handler($e) { ... }

// PHP 7.
function handler(Throwable $e) { ... }
?>

Устаревшие construktor стиля PHP 4.

Больше нельзя использовать одно и то же имя для функции внутри класса.

<?php
class foo {
    function foo() {
        echo 'I am the constructor';
    }
}
?>

В приведенном выше примере отображается ошибка:

Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; foo has a deprecated constructor in example.php on line 3

list() функция больше не работает в обратном порядке

<?php
list($a[], $a[], $a[]) = [1, 2, 3];
var_dump($a);
?>

Вывод PHP 5.6:

array(3) {
  [0]=>
  int(3)
  [1]=>
  int(2)
  [2]=>
  int(1)
}

Вывод PHP 7.0:

array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
}

Более подробную информацию о миграции 5.6 → 7.0 можно найти в документации по PHP.

PHP 7.0 → PHP 8.0

PHP 7.0 → PHP 7.1

Если раньше при добавлении недостаточного количества аргументов в функцию выдавалось предупреждение, то теперь это fatal ошибка.

<?php
function test($param){}
test();
?>

В приведенном выше примере теперь отображается следующее:

Fatal error: Uncaught ArgumentCountError: Too few arguments to function test(), 0 passed in %s on line %d and exactly 1 expected in %s:%d

Начиная с версии PHP 7.1, перед именем типа можно добавлять вопросительный знак. Добавление вопросительного знака означает, что аргумент и возвращаемое значение функции могут быть либо null, либо указанного типа. Кроме того, был введен тип void.

Более подробную информацию о переходе с версии 7.0 → 7.1 вы можете найти в документации по PHP.

PHP 7.1 → PHP 7.2

Ранее с помощью функции number_format(-0.01) можно было вернуть «-0», но теперь это исправлено и возвращается «0».

Больше не может быть функции parse_str() без второго аргумента.

Добавлен новый тип object.
Общие расширения больше не требуют указания расширений файлов (.so в Unix и .dll в Windows). Это включается в файле php.ini, а также в функции dl().

Более подробную информацию о переходе с версии 7.1 → 7.2 вы можете найти в документации по PHP.

PHP 7.2 → PHP 7.3

Объявление констант, не зависящих от регистра, было устаревшим. Передача true в качестве третьего аргумента в define() теперь будет генерировать предупреждение об устаревании.

В связи с введением гибкого синтаксиса heredoc/nowdoc строки doc, содержащие в своем теле завершающую метку, могут вызывать синтаксические ошибки или изменения в интерпретации. Например, в:

<?php
$str = <<<FOO
    abcdefg
    FOO
FOO;
?>

Вхождение FOO с отступом ранее не имело никакого специального значения. Теперь она будет интерпретироваться как конец строки heredoc, а следующая за ней FOO; вызовет синтаксическую ошибку. Эту проблему всегда можно решить, выбрав завершающую метку, которая не встречается в содержимом строки.

Более подробную информацию о переходе с версии 7.2 → 7.3 вы можете найти в документации по PHP.

PHP 7.3 → PHP 7.4

В версии 7.4 классы получили поддержку присвоения типов:

<?php
class User {
    public int $id;
    public string $name;
}
?>

Устранены nested ternary операторы без явных круглых скобок:

<?php
1 ? 2 : 3 ? 4 : 5; // deprecated
(1 ? 2 : 3) ? 4 : 5; // ok
1 ? 2 : (3 ? 4 : 5); // ok
?>

Скобки не нужны при вложении в средний операнд, так как это всегда однозначно и не зависит от ассоциативности:

<?php
1 ? 2 ? 3 : 4 : 5 // ok
?>

Синтаксис доступа к массивам и строкам offset, использующий фигурные скобки, устарел. Используйте $var[$idx] вместо $var{$idx}.

PHP Fatal error: Array and string offset access syntax with curly braces is no longer supported in

Утратила силу функция is_real(), теперь вместо нее используется is_float().

Более подробную информацию о переходе с версии 7.3 → 7.4 вы можете найти в документации по PHP.

PHP 7.4 → PHP 8.0

Наибольшие изменения происходят при сравнении строк и чисел. Часто можно использовать 0 == "not-a-number", которое раньше было истинным, а теперь стало ложным.

Сравнение До После
0 ==
"0"
true true
0 ==
"0.0"
true true
0 ==
"foo"
true false
0 ==
""
true false
42 ==
" 42"
true true
42 ==
"42foo"
true false

Зарезервированы новые слова: match и mixed.

Методы с тем же именем, что и у класса, больше не интерпретируются как конструкторы. Вместо них следует использовать метод __construct().

Возможность определять константы без учета регистра была удалена. Третий аргумент define() больше не может быть истинным.

Более подробную информацию о переходе с версии 7.4 → 8.0 вы можете найти в документации по PHP.

PHP 8.0 → PHP 8.3

PHP 8.0 → PHP 8.1

Когда метод, использующий статические переменные, наследуется (но не переопределяется), унаследованный метод теперь будет совместно использовать статические переменные с родительским методом:

<?php
class A {
    public static function counter() {
        static $counter = 0;
        $counter++;
        return $counter;
    }
}

class B extends A {}
var_dump(A::counter()); // int(1)
var_dump(A::counter()); // int(2)
var_dump(B::counter()); // int(3), eelnevalt int(1)
var_dump(B::counter()); // int(4), eelnevalt int(2)
?>

Более подробную информацию о переходе с версии 8.0 → 8.1 вы можете найти в документации по PHP.

PHP 8.1 → PHP 8.2

Добавлен атрибут для скрытия чувствительных параметров

Добавлен атрибут #[\SensitiveParameter] для редактирования конфиденциальных данных в backtrace.

Более подробную информацию о переходе с версии 8.1 → 8.2 вы можете найти в документации по PHP.

PHP 8.2→ PHP 8.3

php.ini теперь поддерживает синтаксис fallback/default value:

<?php
/*
/path/to/user.ini sisaldab järgmist seadistust:

listen = localhost:${DRUPAL_FPM_PORT:-9000}
*/

$user_ini = parse_ini_file('/path/to/user.ini');
echo $user_ini['listen']; // localhost:9000
?>

Более подробную информацию о переходе с версии 8.1 → 8.2 вы можете найти в документации по PHP.

Updated on 26. Apr 2024

Was this article helpful?

Related Articles