Изменения, ломающие обратную совместимость

Ядро PHP

Ограничения доступа к $GLOBALS

Доступ к массиву $GLOBALS теперь имеет ряд ограничений. Чтение и запись отдельных элементов массива, как например, $GLOBALS['var'], по-прежнему работает. Чтение всего массива $GLOBALS также поддерживается. Однако операции, связанные с изменением всего $GLOBALS, запрещены. Например, array_pop($GLOBALS) приведёт к ошибке.

Использование static-переменных в унаследованных методах

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

<?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), ранее было int(1)
var_dump(B::counter()); // int(4), ранее было int(2)
?>
Это означает, что статические переменные в методах теперь ведут себя так же, как статические свойства.

Необязательные параметры, указанные перед обязательными параметрами

Необязательный параметр, указанный перед обязательными параметрами, теперь всегда обрабатывается как обязательный, даже при вызове с использованием именованных аргументов. Начиная с PHP 8.0.0, но до PHP 8.1.0, приведённый ниже код выдаёт предупреждение об устаревании определения, но успешно выполняется при вызове. Начиная с PHP 8.1.0, выдаётся ошибка класса ArgumentCountError, как это было бы при вызове с позиционными аргументами.

<?php
function makeyogurt($container = "миску", $flavour)
{
return
"Готовим $container с $flavour йогуртом.\n";
}
try
{
echo
makeyogurt(flavour: "малиновым");
}
catch (
Error $e)
{
echo
get_class($e), ' - ', $e->getMessage(), "\n";
}
?>

Результат выполнения приведённого примера в PHP 8.0:

Deprecated: Required parameter $flavour follows optional parameter $container
 in example.php on line 3
Готовим миску с малиновым йогуртом.

Результат выполнения приведённого примера в PHP 8.1:

Deprecated: Optional parameter $container declared before required parameter
 $flavour is implicitly treated as a required parameter in example.php on line 3
ArgumentCountError - makeyogurt(): Argument #1 ($container) not passed

Обратите внимание, что значение по умолчанию null может использоваться перед обязательными параметрами для указания типа, допускающего значение null, но этот параметр всё равно будет обязательным.

Совместимость типа возвращаемого значения с внутренними классами

Большинство неокончательных внутренних методов теперь требуют переопределяющих методов для объявления совместимого возвращаемого типа, в противном случае во время проверки наследования выдаётся уведомление об устаревании возможности. В случае, если тип возвращаемого значения не может быть объявлен для метода переопределения из-за проблем совместимости версий PHP, можно добавить атрибут ReturnTypeWillChange, чтобы заглушить уведомление об устаревании.

Новые ключевые слова

readonly теперь является ключевым словом. Однако его можно использовать как имя функции.

never теперь является зарезервированным словом, поэтому его нельзя использовать для названия класса, интерфейса или трейта, а также запрещено использовать в пространствах имён.

Переход от ресурсов к объектам

Несколько ресурсов (resource) теперь представлены как объекты (object). Проверки возвращаемого значения с использованием функции is_resource() следует заменить проверками на false.

  • Функции FileInfo теперь принимают и возвращают объекты finfo вместо ресурсов (resource) fileinfo.

  • Функции FTP теперь принимают и возвращают объекты FTP\Connection вместо ресурсов (resource) ftp.

  • Функции IMAP теперь принимают и возвращают объекты IMAP\Connection вместо ресурсов (resource) imap.

  • The LDAP теперь принимают и возвращают объекты LDAP\Connection вместо ресурсов (resource) ldap link.

  • Функции LDAP теперь принимают и возвращают объекты LDAP\Result вместо ресурсов (resource) ldap result.

  • Функции LDAP теперь принимают и возвращают объекты LDAP\ResultEntry вместо ресурсов (resource) ldap result entry.

  • Функции PgSQL теперь принимают и возвращают объекты PgSql\Connection вместо ресурсов (resource) pgsql link.

  • Функции PgSQL теперь принимают и возвращают объекты PgSql\Result вместо ресурсов (resource) pgsql result.

  • Функции PgSQL теперь принимают и возвращают объекты PgSql\Lob вместо ресурсов (resource) pgsql large object.

  • Функции PSpell теперь принимают и возвращают объекты PSpell\Dictionary вместо ресурсов (resource) pspell.

  • Функции PSpell теперь принимают и возвращают объекты PSpell\Config вместо ресурсов (resource) pspell config.

MySQLi

Функции mysqli_fetch_fields() и mysqli_fetch_field_direct() теперь всегда возвращают 0 в свойстве max_length. Это значение можно вычислить, перебирая набор результатов и выбирая максимальную длину. Такой алгоритм раньше использовал PHP.

Опция MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH больше не имеет смысла.

Опция MYSQLI_STORE_RESULT_COPY_DATA больше не имеет смысла. Передача какого-либо значения в параметр mode метода mysqli::store_result() больше не имеет смысла.

mysqli::connect() теперь возвращает true вместо null в случае успешного выполнения.

Режим обработки ошибок по умолчанию был изменён с "silent" на "exceptions". Смотрите страницу Режимы обработки ошибок MySQLi для получения дополнительных сведений о том, что это влечёт за собой и о том, как явно установить этот атрибут. Чтобы восстановить предыдущее поведение, используйте: mysqli_report(MYSQLI_REPORT_OFF);

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

MySQLnd

INI-директива mysqlnd.fetch_data_copy была удалена. Это не должно приводить к видимым для пользователя изменениям в поведении.

OpenSSL

Секретные ключи EC теперь будут экспортироваться в формате PKCS#8, а не в традиционном формате, как и все другие ключи.

Функции openssl_pkcs7_encrypt() и openssl_cms_encrypt() теперь по умолчанию используют шифр AES-128-CBC, а не RC2-40. Шифр RC2-40 считается небезопасным и не включён по умолчанию в OpenSSL 3.

Объекты данных PHP

Атрибут PDO::ATTR_STRINGIFY_FETCHES теперь преобразовывает логические значения (bool) в "0" или "1". Ранее логические значения (bool) не были строковыми.

Вызов PDOStatement::bindColumn() с PDO::PARAM_LOB теперь будет постоянно связывать результат потока, если PDO::ATTR_STRINGIFY_FETCHES не включён. Раньше результатом был либо поток, либо строка в зависимости от используемого драйвера базы данных и времени выполнения привязки.

Драйвер MySQL

Целые числа и числа с плавающей запятой в наборах результатов теперь будут возвращаться с использованием собственных типов PHP вместо строк (string) при использовании эмулированных подготовленных операторов. Это соответствует поведению собственных подготовленных операторов. Предыдущее поведение можно восстановить, включив опцию PDO::ATTR_STRINGIFY_FETCHES.

Драйвер SQLite

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

Phar

Чтобы соответствовать интерфейсу ArrayAccess, Phar::offsetUnset() и PharData::offsetUnset() больше не возвращают логическое значение (bool).

Стандартные функции

version_compare() больше не принимает недокументированные сокращения операторов.

Функции htmlspecialchars(), htmlentities(), htmlspecialchars_decode(), html_entity_decode() и get_html_translation_table() теперь по умолчанию используют ENT_QUOTES | ENT_SUBSTITUTE вместо ENT_COMPAT. Это означает, что теперь ' экранируется в &#039;. Кроме того, в случае неправильного UTF-8 вместо пустой строки будет возвращён замещающий символ Unicode.

debug_zval_dump() теперь выводит refcount ссылочных оболочек с их refcount, вместо того, чтобы просто добавлять & к значению. Это более точно моделирует эталонное представление, начиная с PHP 7.0.

debug_zval_dump() теперь выводит interned вместо фиктивного refcount для интернированных строк и неизменяемых массивов.

Стандартная библиотека PHP (SPL)

SplFixedArray теперь будет закодирован в JSON как массив (array).

add a note add a note

User Contributed Notes

There are no user contributed notes for this page.
To Top