Перейти к содержимому
Поиск
Php Разработка

PHP: полный мануал с примерами, функциями и ООП

Практический мануал PHP: от переменных и читаемого кода до безопасных форм, интеграций, базы данных и ООП на примере магазина. Учебный маршрут, поиск функций, подробные примеры, разбор ошибок и исходники для скачивания.

Александр НекрасовИзменено:
Практический мануал PHP: от переменных и функций к объектной модели интернет-магазина
PHP 8.5.11468 глав6256 карточек справочника
Дерево руководства

Глава 462 · Официальная база → практическое применение

Миграции PHP 8.1–8.3: enum, readonly и уточнение контрактов

Полная карта официальных страниц перехода PHP 8.0 → 8.1, PHP 8.1 → 8.2, PHP 8.2 → 8.3, дополненная проверяемым порядком обновления.

PHP 8.0 → 8.1

Этот узел — контрольная карта перехода PHP 8.0 → 8.1. Начинают не с переписывания всего проекта, а с инвентаризации runtime, расширений и зависимостей, затем включают полную диагностику и прогоняют тесты на копии данных.

Безопасный порядок обновления
  1. Зафиксировать рабочую версию, расширения, php.ini и внешние службы.
  2. Прочитать несовместимости и deprecation именно для следующего шага.
  3. Поднять новую версию рядом, выполнить тесты и сравнить ответы.
  4. Исправить код, повторить проверку, подготовить откат и только затем переключать трафик.
Полный официальный договор страницы

Ниже сохранён официальный русский текст и структура из зафиксированного архива PHP Manual. Отдельные ещё не переведённые страницы официального русского архива могут оставаться на английском.

Миграция с PHP 8.0.x на PHP 8.1.x

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

Смотрите также руководство по миграции для версий PHP 7.1.x, 7.2.x, 7.3.x, 7.4.x, 8.0.x.

Нормативный английский оригинал из frozen baseline

Этот слой сохраняет полный договор, если перевод отстаёт. Источник: английский нормативный оригинал.

Migrating from PHP 8.0.x to PHP 8.1.x

This new minor version brings with it a number of new features and a few incompatibilities that should be tested for before switching PHP versions in production environments.

See also the migration guides for PHP versions 7.1.x, 7.2.x, 7.3.x, 7.4.x, 8.0.x.

ШагЧто зафиксировать до изменения
СредаPHP, SAPI, расширения, php.ini, ОС и библиотеки.
ПоведениеТесты на реальные входы, ошибки, сериализацию и ответы API.
Зависимостиcomposer.lock, системные пакеты и внешние службы.
ВозвратРезервная копия, совместимая схема данных и команда отката.

PHP 8.0 → 8.1: Новые возможности языка и платформы

Страница отвечает на вопрос «что нового можно применять после обновления». Новая запись не должна случайно попасть в код, который ещё запускается на старом runtime: минимальную версию фиксируют в Composer и проверяют в CI.

Полный официальный договор страницы

Ниже сохранён официальный русский текст и структура из зафиксированного архива PHP Manual. Отдельные ещё не переведённые страницы официального русского архива могут оставаться на английском.

Ядро PHP

Буквенный префикс восьмеричных целых чисел

Восьмеричные целые числа теперь могут использовать явный префикс 0o/0O в целочисленных литералах, аналогично двоичным и шестнадцатеричным целочисленным литералам.

<?php
014;  // Восьмеричный литерал без префикса
0o14; // Восьмеричный литерал с префиксом
?>

Распаковка массива с помощью строковых ключей

Добавлена поддержка распаковки массивов со строковыми ключами.

<?php
$arr1 = [1, 'a' => 'b'];
$arr2 = [...$arr1, 'c' => 'd']; //[1, 'a' => 'b', 'c' => 'd']
?>

Именованный аргумент после распаковки аргумента

Теперь можно указать именованные аргументы после распаковки аргументов. например: foo(...$args, named: $arg).

Ключ с полным путём при загрузке файлов

При загрузке файлов появился новый ключ full_path, который содержит полный путь (а не только относительный) загруженного файла. Предназначен для использования вместе с HTML-атрибутом webkitdirectory.

Перечисления

Добавлена поддержка перечислений.

Файберы

Добавлена поддержка файберов.

Callback-функции как объекты первого класса

Замыкания для callback-функций теперь можно создавать с помощью синтаксиса myFunc(...), который идентичен синтаксису Closure::fromCallable('myFunc').

Замечание:

... является частью синтаксиса, а не пропуском.

Пересечение типов

Добавлена поддержка пересечения типов.

Предостережение

Пересечения типов нельзя использовать вместе с объединением типов.

Тип never

Добавлен новый тип возвращаемого значения never. Тип указывает на то, что функция либо вызывает exit(), либо выбрасывает исключение, либо не завершается.

new в инициализации класса

Теперь можно использовать выражения new ClassName() в качестве значения по умолчанию для параметра, статической переменной, инициализаторов глобальных констант и в качестве аргументов атрибутов. Теперь объекты также можно передавать в define().

Readonly-свойства

Добавлена поддержка readonly-свойств.

Окончательные константы класса

Добавлена поддержка модификатора final при определении констант класса. Кроме того, константы интерфейса по умолчанию становятся переопределяемыми.

CURL

Добавлена опция CURLOPT_DOH_URL.

Добавлены параметры для сертификата BLOB-объекта, доступные с libcurl >= 7.71.0:

Добавлен класс CURLStringFile, который можно использовать для отправки файла из строки (string), а не из файла:

<?php
$file = new CURLStringFile($data, 'filename.txt', 'text/plain');
curl_setopt($curl, CURLOPT_POSTFIELDS, ['file' => $file]);
?>

FPM

Добавлен формат статуса openmetrics. Prometheus может использовать его для получения метрик FPM.

Добавлен новый пул для диспетчера динамических процессов под названием pm.max_spawn_rate. Он позволяет запускать несколько дочерних процессов более быстрыми темпами, если выбран динамический pm. Значение по умолчанию - 32, которое ранее было фиксированным значением.

GD

Поддержка Avif теперь доступна с помощью imagecreatefromavif() и imageavif(), если libgd был собран с поддержкой Avif.

Hash

Следующие функции hash(), hash_file() и hash_init() теперь поддерживают дополнительный необязательный аргумент options, который можно использовать для передачи специфичных для алгоритма данных.

MurmurHash3

Добавлена поддержка MurmurHash3 с поддержкой потоковой передачи. Реализованы следующие варианты:

  • murmur3a, 32-битный хеш

  • murmur3c, 128-битный хеш для x86

  • murmur3f, 128-битный хеш для x64

Начальное состояние хеширования можно передать с помощью ключа seed в массиве options, например:

<?php
$h = hash("murmur3f", $data, options: ["seed" => 42]);
echo $h, "\n";
?>
Допустимое начальное значение находится в диапазоне от 0 до определённого платформой значения UINT_MAX, обычно - 4294967295.

xxHash

Добавлена поддержка xxHash. Реализованы следующие варианты:

  • xxh32, 32-bit hash

  • xxh64, 64-bit hash

  • xxh3, 64-bit hash

  • xxh128, 128-bit hash

Начальное состояние хеширования можно передать с помощью ключа seed в массиве options, например:

<?php
$h = hash("xxh3", $data, options: ["seed" => 42]);
echo $h, "\n";
?>
Использование секрета также поддерживается путём передачи ключа secret в массиве options:
<?php
$h = hash("xxh3", $data, options: ["secret" => "как минимум 136 байт секрета"]);
echo $h, "\n";
?>
Качество пользовательского секрета имеет решающее значение для качества хеша результата. Для секрета настоятельно рекомендуется использовать максимально возможную энтропию.

MySQLi

Новая INI-директива mysqli.local_infile_directory

Добавлена INI-директива mysqli.local_infile_directory, с помощью которой можно указать каталог, из которого разрешена загрузка файлов. Это имеет смысл, только если mysqli.allow_local_infile не включён, поскольку в этом случае разрешены все каталоги.

Привязка параметров во время выполнении

Теперь можно привязывать параметры, передав их в виде массива в mysqli_stmt::execute(). Все значения будут привязаны как строки. Разрешены только списочные массивы. Эта новая функция недоступна, если MySQLi скомпилирован с libmysqlclient.

<?php
$stmt = $mysqli->prepare('INSERT INTO users(id, name) VALUES(?,?)');
$stmt->execute([1, $username]);
?>

Новый метод mysqli_result::fetch_column()

Добавлен mysqli_result::fetch_column() для выборки единственного скалярного значения из набора результатов. Новый метод принимает необязательный параметр column, начинающийся с 0, в виде целого числа (int), указывающий из какого столбца производить выборку.

<?php
$result = $mysqli->query('SELECT username FROM users WHERE id = 123');
echo $result->fetch_column();
?>

PDO

Добавлен атрибут PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY, который можно использовать для указания каталога, из которого могут быть загружены файлы. Это имеет смысл только в том случае, если PDO::MYSQL_ATTR_LOCAL_INFILE не включён, поскольку в этом случае разрешены все каталоги.

PDO_SQLite

Поддерживается новый элемент "file:" в DSN-префиксе SQLite, который позволяет указывать дополнительные флаги. Он не будет работать, если включена опция open_basedir.

<?php
new PDO('sqlite:file:path/to/sqlite.db?mode=ro')
?>

POSIX

Добавлены константы POSIX_RLIMIT_KQUEUES и POSIX_RLIMIT_NPTS. Эти ограничения доступны только во FreeBSD.

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

fputcsv() теперь принимает новый аргумент eol, который позволяет определять настраиваемую последовательность конца строки, значение по умолчанию остаётся прежним - "\n".

SPL

SplFileObject::fputcsv() теперь принимает новый аргумент eol, который позволяет определять настраиваемую последовательность конца строки, значение по умолчанию остаётся прежним - "\n".

Нормативный английский оригинал из frozen baseline

Этот слой сохраняет полный договор, если перевод отстаёт. Источник: английский нормативный оригинал.

PHP Core

Integer Octal Literal Prefix

Octal integers can now use an explicit 0o/0O prefix in integer literals, similarly to binary and hexadecimal integer literals.

<?php
014;  // Non-prefix octal literal
0o14; // Prefixed octal literal
?>

Array Unpacking with String Keys

Added support for array unpacking with strings keys.

<?php
$arr1 = [1, 'a' => 'b'];
$arr2 = [...$arr1, 'c' => 'd']; //[1, 'a' => 'b', 'c' => 'd']
?>

Named Argument After Argument Unpacking

It is now possible to specify named arguments after an argument unpack. e.g. foo(...$args, named: $arg).

full-path Key for File Uploads

File uploads now provide an additional full_path key, which contains the full path (rather than just the basename) of the uploaded file. This is intended for use in conjunction with "upload webkitdirectory".

Enumerations

Support for Enumerations has been added.

Fibers

Support for Fibers has been added.

First Class Callable Syntax

Closures for callables can now be created using the syntax myFunc(...), which is identical to Closure::fromCallable('myFunc').

Note:

The ... is part of the syntax, and not an omission.

Intersection Types

Support for intersection types has been added.

Caution

Intersection types cannot be used together with union types

Never type

A new return only type never has been added. This indicates that a function either exit(), throws an exception, or doesn't terminate.

new in Initializers

It is now possible to use new ClassName() expressions as the default value of a parameter, static variable, global constant initializers, and as attribute arguments. Objects can also be passed to define() now.

Readonly properties

Support for readonly has been added.

Final class constants

Added support for the final modifier for class constants. Also, interface constants become overridable by default.

CURL

Added the CURLOPT_DOH_URL option.

Added options for blob certificate when libcurl >= 7.71.0:

Added CURLStringFile, which can be used to post a file from a string rather than a file:

<?php
$file = new CURLStringFile($data, 'filename.txt', 'text/plain');
curl_setopt($curl, CURLOPT_POSTFIELDS, ['file' => $file]);
?>

FPM

Added openmetrics status format. It can be used by Prometheus to fetch FPM metrics.

Added new pool option for the dynamic process manager called pm.max_spawn_rate. It allows to start a number of children at a faster rate when dynamic pm is selected. The default value is 32 which was the previous hard coded value.

GD

Avif support is now available through imagecreatefromavif() and imageavif(), if libgd has been built with Avif support.

Hash

The following functions hash(), hash_file(), and hash_init() now support an additional optional options argument, which can be used to pass algorithm specific data.

MurmurHash3

Added support for MurmurHash3 with streaming support. The following variants are implemented:

  • murmur3a, 32-bit hash

  • murmur3c, 128-bit hash for x86

  • murmur3f, 128-bit hash for x64

The initial hash state can be passed through the seed key in the options array, for example:

<?php
$h = hash("murmur3f", $data, options: ["seed" => 42]);
echo $h, "\n";
?>
A valid seed value is within the range from 0 to the platform defined UINT_MAX, usually 4294967295.

xxHash

Added support for xxHash. The following variants are implemented:

  • xxh32, 32-bit hash

  • xxh64, 64-bit hash

  • xxh3, 64-bit hash

  • xxh128, 128-bit hash

The initial hash state can be passed through the seed key in the options array, for example:

<?php
$h = hash("xxh3", $data, options: ["seed" => 42]);
echo $h, "\n";
?>
Secret usage is supported through passing the secret key in the options array, too:
<?php
$h = hash("xxh3", $data, options: ["secret" => "at least 136 bytes long secret here"]);
echo $h, "\n";
?>
The quality of the custom secret is crucial for the quality of the resulting hash. It is highly recommended for the secret to use the best possible entropy.

MySQLi

New INI directive mysqli.local_infile_directory

The mysqli.local_infile_directory INI directive has been added, which can be used to specify a directory from which files are allowed to be loaded. It is only meaningful if mysqli.allow_local_infile is not enabled, as all directories are allowed in that case.

Binding parameters in execute

It is now possible to bind parameters by passing them as an array to mysqli_stmt::execute(). All values will be bound as strings. Only list arrays are allowed. This new feature is not available when MySQLi is compiled with libmysqlclient.

<?php
$stmt = $mysqli->prepare('INSERT INTO users(id, name) VALUES(?,?)');
$stmt->execute([1, $username]);
?>

New method mysqli_result::fetch_column()

mysqli_result::fetch_column() has been added to allow fetching a single scalar value from the result set. The new method accepts an optional 0-based column parameter of type int specifying which column to fetch from.

<?php
$result = $mysqli->query('SELECT username FROM users WHERE id = 123');
echo $result->fetch_column();
?>

PDO

The PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY attribute has been added, which can be used to specify a directory from which files are allowed to be loaded. It is only meaningful if PDO::MYSQL_ATTR_LOCAL_INFILE is not enabled, as all directories are allowed in that case.

PDO_SQLite

SQLite's "file:" DSN syntax is now supported, which allows specifying additional flags. This feature is not available if open_basedir is set.

<?php
new PDO('sqlite:file:path/to/sqlite.db?mode=ro')
?>

POSIX

Added POSIX_RLIMIT_KQUEUES and POSIX_RLIMIT_NPTS. These rlimits are only available on FreeBSD.

Standard

fputcsv() now accepts a new eol argument which allows to define a custom End of Line sequence, the default remains the same and is "\n".

SPL

SplFileObject::fputcsv() now accepts a new eol argument which allows to define a custom End of Line sequence, the default remains the same and is "\n".

PHP 8.1+: статус как конечный набор значенийСамостоятельный пример
<?php
enum OrderStatus: string
{
    case New = 'new';
    case Paid = 'paid';
}

$status = OrderStatus::from('paid');
echo $status->name, ':', $status->value, "\n";
Ожидаемый результат
Paid:paid

from выбрасывает ValueError для неизвестной строки; tryFrom возвращает null. Выбор зависит от того, является ли неизвестное значение ошибкой контракта.

PHP 8.0 → 8.1: Новые классы, интерфейсы и перечисления

Новые классы, интерфейсы и enum доступны только в указанной ветке PHP или расширения. Перед условной интеграцией проверяют версию и наличие расширения; для обязательной зависимости ранний отказ понятнее тихой деградации.

Полный официальный договор страницы

Ниже сохранён официальный русский текст и структура из зафиксированного архива PHP Manual. Отдельные ещё не переведённые страницы официального русского архива могут оставаться на английском.

PHP 8.0 → 8.1: Новые функции и методы

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

Полный официальный договор страницы

Ниже сохранён официальный русский текст и структура из зафиксированного архива PHP Manual. Отдельные ещё не переведённые страницы официального русского архива могут оставаться на английском.

Нормативный английский оригинал из frozen baseline

Этот слой сохраняет полный договор, если перевод отстаёт. Источник: английский нормативный оригинал.

PHP 8.0 → 8.1: Новые глобальные константы

Новые константы описывают возможности runtime и расширений. Их нельзя считать включёнными только по версии PHP: для расширений дополнительно проверяют загрузку модуля, а для необязательной ветки — defined().

Полный официальный договор страницы

Ниже сохранён официальный русский текст и структура из зафиксированного архива PHP Manual. Отдельные ещё не переведённые страницы официального русского архива могут оставаться на английском.

Модуль MySQLi

  • MYSQLI_REFRESH_REPLICA

    Эта новая константа была добавлена для замены MYSQLI_REFRESH_SLAVE в соответствии с политикой самого MySQL, отказавшегося от использования слова "slave". Старая константа по-прежнему доступна для обратной совместимости, но может быть объявлена устаревшей/удалена в будущем.

Модуль Sockets

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

Стандартные модули

Модуль Tokenizer

Нормативный английский оригинал из frozen baseline

Этот слой сохраняет полный договор, если перевод отстаёт. Источник: английский нормативный оригинал.

PHP 8.0 → 8.1: Обратно несовместимые изменения

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

Полный официальный договор страницы

Ниже сохранён официальный русский текст и структура из зафиксированного архива PHP Manual. Отдельные ещё не переведённые страницы официального русского архива могут оставаться на английском.

Ядро 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).

Нормативный английский оригинал из frozen baseline

Этот слой сохраняет полный договор, если перевод отстаёт. Источник: английский нормативный оригинал.

PHP Core

$GLOBALS Access Restrictions

Access to the $GLOBALS array is now subject to a number of restrictions. Read and write access to individual array elements like $GLOBALS['var'] continues to work as-is. Read-only access to the entire $GLOBALS array also continues to be supported. However, write access to the entire $GLOBALS array is no longer supported. For example, array_pop($GLOBALS) will result in an error.

Usage of static Variables in Inherited Methods

When a method using static variables is inherited (but not overridden), the inherited method will now share static variables with the parent method.

<?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), previously int(1)
var_dump(B::counter()); // int(4), previously int(2)
?>
This means that static variables in methods now behave the same way as static properties.

Optional parameters specified before required parameters

An optional parameter specified before required parameters is now always treated as required, even when called using named arguments. As of PHP 8.0.0, but prior to PHP 8.1.0, the below emits a deprecation notice on the definition, but runs successfully when called. As of PHP 8.1.0, an error of class ArgumentCountError is thrown, as it would be when called with positional arguments.

<?php
function makeyogurt($container = "bowl", $flavour)
{
    return "Making a $container of $flavour yogurt.\n";
}
try
{
    echo makeyogurt(flavour: "raspberry");
}
catch (Error $e)
{
    echo get_class($e), ' - ', $e->getMessage(), "\n";
}
?>

Output of the above example in PHP 8.0:

Deprecated: Required parameter $flavour follows optional parameter $container
 in example.php on line 3
Making a bowl of raspberry yogurt.

Output of the above example in 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

Note that a default value of null can be used before required parameters to specify a nullable type, but the parameter will still be required.

Return Type Compatibility with Internal Classes

Most non-final internal methods now require overriding methods to declare a compatible return type, otherwise a deprecated notice is emitted during inheritance validation. In case the return type cannot be declared for an overriding method due to PHP cross-version compatibility concerns, a ReturnTypeWillChange attribute can be added to silence the deprecation notice.

New Keywords

readonly is a keyword now. However, it still may be used as function name.

never is now a reserved word, so it cannot be used to name a class, interface or trait, and is also prohibited from being used in namespaces.

Resource to Object Migration

Several resources have been migrated to objects. Return value checks using is_resource() should be replaced with checks for false.

MySQLi

mysqli_fetch_fields(), and mysqli_fetch_field_direct() will now always return 0 for the max_length. This information can be computed by iterating over the result set, and taking the maximum length. This is what PHP was doing internally previously.

The MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH option no longer has any effect.

The MYSQLI_STORE_RESULT_COPY_DATA option no longer has any effect. Passing any value to the mode parameter of mysqli::store_result() no longer has any effect.

mysqli::connect() now returns true instead of null on success.

The default error handling mode has been changed from "silent" to "exceptions" See the MySQLi reporting mode page for more details on what this entails, and how to explicitly set this attribute. To restore the previous behaviour use: mysqli_report(MYSQLI_REPORT_OFF);

Classes extending mysqli_stmt::execute() are now required to specify the additional optional parameter.

MySQLnd

The mysqlnd.fetch_data_copy INI directive has been removed. This should not result in user-visible behavior changes.

OpenSSL

EC private keys will now be exported in PKCS#8 format rather than traditional format, just like all other keys.

openssl_pkcs7_encrypt() and openssl_cms_encrypt() will now default to using AES-128-CBC rather than RC2-40. The RC2-40 cipher is considered insecure and not enabled by default by OpenSSL 3.

PHP Data Objects

PDO::ATTR_STRINGIFY_FETCHES now stringifies values of type bool to "0" or "1". Previously bools were not stringified.

Calling PDOStatement::bindColumn() with PDO::PARAM_LOB will now constantly bind a stream result when PDO::ATTR_STRINGIFY_FETCHES is not enabled. Previously, the result would either be a stream or a string depending on the used database driver and the time the binding is performed.

MySQL Driver

Integers and floats in result sets will now be returned using native PHP types instead of strings when using emulated prepared statements. This matches the behavior of native prepared statements. The previous behaviour can be restored by enabling the PDO::ATTR_STRINGIFY_FETCHES option.

SQLite Driver

Integers and floats in results sets will now be returned using native PHP types. The previous behaviour can be restored by enabling the PDO::ATTR_STRINGIFY_FETCHES option.

Phar

To comply with the ArrayAccess interface, Phar::offsetUnset() and PharData::offsetUnset() no longer return a bool.

Standard

version_compare() no longer accepts undocumented operator abbreviations.

htmlspecialchars(), htmlentities(), htmlspecialchars_decode(), html_entity_decode(), and get_html_translation_table() now use ENT_QUOTES | ENT_SUBSTITUTE rather than ENT_COMPAT by default. This means that ' is escaped to &#039; while previously nothing was done. Additionally, malformed UTF-8 will be replaced by a Unicode substitution character, instead of resulting in an empty string.

debug_zval_dump() now prints the refcount of a reference wrappers with their refcount, instead of only prepending & to the value. This more accurately models reference representation since PHP 7.0.

debug_zval_dump() now prints interned instead of a dummy refcount for interned strings and immutable arrays.

Standard PHP Library (SPL)

SplFixedArray, will now be JSON encoded like an array

PHP 8.0 → 8.1: Устаревшие возможности

Устаревание — раннее предупреждение, а не немедленное удаление. На тестовом контуре включают E_ALL, собирают deprecation без подавления, выбирают замену и исправляют собственный код до следующей мажорной версии.

Полный официальный договор страницы

Ниже сохранён официальный русский текст и структура из зафиксированного архива PHP Manual. Отдельные ещё не переведённые страницы официального русского архива могут оставаться на английском.

Ядро PHP

Реализация Serializable без __serialize() и __unserialize()

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

Передача null параметрам встроенных функций, не допускающим значение NULL

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

<?php
var_dump(str_contains("foobar", null));
// Deprecated: Passing null to parameter #2 ($needle) of type string
//             is deprecated
?>

Неявная несовместимость преобразования float к int

Теперь нужно избегать неявного преобразования числа с плавающей точкой (float) к целому числу (int), которое приводит потере точности. Это влияет на ключи массива (array), объявления целочисленных (int) типов в принудительном режиме и операторов, работающие с целыми числами (int).

<?php
$a = [];
$a[15.5]; // устарело, поскольку значение ключа теряет компонент 0.5
$a[15.0]; // работает, так как 15.0 == 15
?>

Вызов static-элемента в трейтах

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

Возврат не массива (array) из __sleep()

Возвращаемое значение __sleep(), не являющееся массивом, теперь сгенерирует уведомление.

Возврат значения по ссылке из функции void

<?php
function &test(): void {}
?>
Такая функция сбивает с толку, поэтому теперь выдаст следующий E_NOTICE: Only variable references should be returned by reference (По ссылке должны возвращаться только ссылки на переменные).

Автовивификация из false

Автовивификация - это процесс создания нового массива (array) при добавлении нового значения. Автовивификация запрещена для скалярных значений, однако false был исключением. Теперь такое поведение устарело.

<?php
$arr = false;
$arr[] = 2;   // устарело
?>

Замечание:

Автовивификация из null и неопределённого значения по-прежнему разрешена:

<?php
// Из неопределённого значения
$arr[] = 'какое-то значение';
$arr['doesNotExist'][] = 2;
// Из null
$arr = null;
$arr[] = 2;
?>

ctype

Проверка нестроковых аргументов

Передача нестрокового аргумента устарела. В будущем аргумент будет интерпретироваться как строка вместо кода ASCII. В зависимости от предполагаемого поведения аргумент должен быть приведён к строке (string) явным образом или через вызов chr(). Это изменение относится ко всем функциям ctype_*().

Date

Функции date_sunrise() и date_sunset() устарели в пользу date_sun_info().

Функция strptime() устарела. Вместо неё используйте date_parse_from_format() (для синтаксического анализа, не зависящего от языкового стандарта) или IntlDateFormatter::parse() (для синтаксического анализа, зависящего от языкового стандарта).

Функция strftime() и gmstrftime() устарели. Используйте вместо них функцию date() (для форматирования, не зависящего от языкового стандарта) или метод IntlDateFormatter::format() (для форматирования, зависящего от языкового стандарта).

Фильтр

Фильтры FILTER_SANITIZE_STRING и FILTER_SANITIZE_STRIPPED устарели.

INI-директива filter.default устарела.

GD

Параметр num_points функции imagepolygon(), imageopenpolygon() и imagefilledpolygon() устарел.

Хеширование

Функции mhash(), mhash_keygen_s2k(), mhash_count(), mhash_get_block_size() и mhash_get_hash_name() устарели. Вместо них используйте функции hash_*().

IMAP

Константа NIL устарела. Вместо неё используйте 0.

Intl

Вызов IntlCalendar::roll() с логическим значением (bool) устарел. Используйте 1 и -1 вместо true и false соответственно.

Многобайтовые строки

Вызов mb_check_encoding() без каких-либо аргументов устарел.

MySQLi

Свойство mysqli_driver::$driver_version устарело. Оно было неактуальным, используйте вместо него PHP_VERSION_ID.

Вызов метода mysqli::get_client_info() или mysqli_get_client_info() с аргументом mysqli устарел. Используйте mysqli_get_client_info() без каких-либо аргументов, чтобы получить информацию о версии клиентской библиотеки.

Метод mysqli::init() устарел. Замените вызовы parent::init() на parent::__construct().

OCI8

INI-директива oci8.old_oci_close_semantics устарела.

ODBC

Функция odbc_result_all() устарела.

PDO

Режим выборки PDO::FETCH_SERIALIZE устарел.

PgSQL

Функциям pgsql_*() теперь нужно явно передавать параметр connection.

SOAP

Параметр ssl_method в SoapClient::__construct() устарел в пользу параметров контекста потока SSL.

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

Вызов key(), current(), next(), prev(), reset() или end() с объектами (object) устарел. Либо сначала преобразуйте объект (object) в массив (array) с помощью функции get_mangled_object_vars(), либо используйте методы, предоставляемые классом, реализующим интерфейс Iterator, например, ArrayIterator.

INI-директива auto_detect_line_endings устарела. При необходимости обработайте разрывы строк "\r" вручную.

Константы FILE_BINARY и FILE_TEXT устарели. Они никогда не имели смысла.

Нормативный английский оригинал из frozen baseline

Этот слой сохраняет полный договор, если перевод отстаёт. Источник: английский нормативный оригинал.

PHP Core

Implementing Serializable without __serialize() and __unserialize()

Either only the new methods should be implemented, if no support for PHP prior to version 7.4 is provided, or both should be implemented.

Passing null to non-nullable parameters of built-in functions

Scalar types for built-in functions are nullable by default. This behaviour is deprecated to align with the behaviour of user-defined functions, where scalar types need to be marked as nullable explicitly.

<?php
var_dump(str_contains("foobar", null));
// Deprecated: Passing null to parameter #2 ($needle) of type string
//             is deprecated
?>

Implicit incompatible float to int conversions

The implicit conversion of float to int which leads to a loss in precision is now deprecated. This affects array keys, int type declarations in coercive mode, and operators working on ints.

<?php
$a = [];
$a[15.5]; // deprecated, as key value loses the 0.5 component
$a[15.0]; // ok, as 15.0 == 15
?>

Calling a static element on a trait

Calling a static method, or accessing a static property directly on a trait is deprecated. Static methods and properties should only be accessed on a class using the trait.

Returning a non-array from __sleep()

Returning a value which is not an array from __sleep() now generates a diagnostic.

Returning by reference from a void function

<?php
function &test(): void {}
?>
Such a function is contradictory, and already emits the following E_NOTICE when called: Only variable references should be returned by reference.

Autovivification from false

Autovivification is the process of creating a new array when appending to a value. Autovivification is prohibited from scalar values, false however was an exception. This is now deprecated.

<?php
$arr = false;
$arr[] = 2;   // deprecated
?>

Note:

Autovivification from null and undefined values is still allowed:

<?php
// From undefined
$arr[] = 'some value';
$arr['doesNotExist'][] = 2;
// From null
$arr = null;
$arr[] = 2;
?>

ctype

Verifying non-string arguments

Passing a non-string argument is deprecated. In the future, the argument will be interpreted as a string instead of an ASCII codepoint. Depending on the intended behavior, the argument should either be cast to string or an explicit call to chr() should be made. All ctype_*() functions are affected.

Date

date_sunrise() and date_sunset() have been deprecated in favor of date_sun_info().

strptime() has been deprecated. Use date_parse_from_format() instead (for locale-independent parsing), or IntlDateFormatter::parse() (for locale-dependent parsing).

strftime() and gmstrftime() have been deprecated. Use date() instead (for locale-independent formatting), or IntlDateFormatter::format() (for locale-dependent formatting).

Filter

The FILTER_SANITIZE_STRING and FILTER_SANITIZE_STRIPPED filters are deprecated.

The filter.default INI directive is deprecated.

GD

The num_points of imagepolygon(), imageopenpolygon() and imagefilledpolygon() has been deprecated.

Hash

The mhash(), mhash_keygen_s2k(), mhash_count(), mhash_get_block_size(), and mhash_get_hash_name() functions have been deprecated. Use the hash_*() functions instead.

IMAP

The NIL constant has been deprecated. Use 0 instead.

Intl

Calling IntlCalendar::roll() with a bool argument is deprecated. Use 1 and -1 instead of true and false respectively.

Multibyte String

Calling mb_check_encoding() without any arguments is deprecated.

MySQLi

The mysqli_driver::$driver_version property has been deprecated. It was meaningless and outdated, use PHP_VERSION_ID instead.

Calling mysqli::get_client_info() or mysqli_get_client_info() with the mysqli argument has been deprecated. Call mysqli_get_client_info() without any arguments to obtain the version information of the client library.

The mysqli::init() method has been deprecated. Replace calls to parent::init() with parent::__construct().

OCI8

The oci8.old_oci_close_semantics INI directive is deprecated.

ODBC

odbc_result_all() has been deprecated.

PDO

The PDO::FETCH_SERIALIZE fetch mode has been deprecated.

PgSQL

Not passing the connection argument to all pgsql_*() functions has been deprecated.

SOAP

The ssl_method option of SoapClient::__construct() has been deprecated in favor of SSL stream context options.

Standard

Calling key(), current(), next(), prev(), reset(), or end() on objects is deprecated. Either convert the object to an array using get_mangled_object_vars() first, or use the methods provided by a class that implements Iterator, such as ArrayIterator, instead.

The auto_detect_line_endings INI directive is deprecated. If necessary, handle "\r" line breaks manually instead.

The FILE_BINARY and FILE_TEXT constants have been deprecated. They never had any effect.

PHP 8.0 → 8.1: Другие изменения

Сюда попадают изменения поведения, конфигурации и расширений, которые не образуют новую синтаксическую конструкцию. Их сверяют с фактически установленными модулями и рабочими сценариями проекта.

Полный официальный договор страницы

Ниже сохранён официальный русский текст и структура из зафиксированного архива PHP Manual. Отдельные ещё не переведённые страницы официального русского архива могут оставаться на английском.

Изменения в модулях SAPI-интерфейса

CLI

Использование -a без модуля readline теперь приведёт к ошибке. Ранее использование -a без модуля readline было аналогичным вызову php без каких-либо аргументов, за исключением вывода дополнительного сообщения "Interactive mode enabled". Этот режим был не интерактивным.

PHPDBG

Возможность дистанционной отладки в phpdbg была удалена.

Изменённые функции

Ядро

Порядок свойств, используемых в foreach, var_dump(), serialize(), при сравнении объектов и т.д. был изменён. Теперь свойства упорядочены естественным образом в соответствии с их объявлением и наследованием. Свойства, объявленные в родительском классе, будут перед дочерними.

Этот порядок соответствует внутреннему расположению свойств в структуре zend_object и повторяет порядок в default_properties_table[] и properties_info_table[]. Старый порядок не был задокументирован и был вызван деталями реализации наследования классов.

Фильтрация

Флаг FILTER_FLAG_ALLOW_OCTAL фильтра FILTER_VALIDATE_INT теперь принимает восьмеричную строку с начальным восьмеричным префиксом ("0o"/"0O").

GMP

Все функции GMP теперь принимают восьмеричную строку с начальным восьмеричным префиксом ("0o"/"0O").

PDO ODBC

Вызов PDO::getAttribute() с константой PDO::ATTR_SERVER_INFO и PDO::ATTR_SERVER_VERSION теперь вернёт значение вместо генерации исключения PDOException.

Reflection

Вызов ReflectionProperty::setAccessible() и ReflectionMethod::setAccessible() больше не требуется. Свойства и методы теперь всегда считаются доступными при работе через Reflection.

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

syslog() теперь безопасен для двоичных файлов.

Другие изменения в модулях

GD

imagewebp() теперь может выполнить кодирование WebP без потерь, если передать IMG_WEBP_LOSSLESS параметру quality.

Эта константа определяется только в том случае, если используемый libgd поддерживает кодирование WebP без потерь.

MySQLi

При сборке PHP с библиотекой libmysqlclient теперь доступны функции mysqli_stmt::next_result() и mysqli::fetch_all().

OpenSSL

  • Для модуля OpenSSL теперь требуется OpenSSL версии не ниже 1.0.2.

  • Теперь поддерживается OpenSSL 3.0. Имейте в виду, что многие шифры больше не включены по умолчанию (часть устаревшего провайдера) и проверка параметров (например, минимальные размеры ключей) стала более строгой.

Phar

  • По умолчанию для подписей теперь используется SHA256.

  • Добавлена поддержка подписей OpenSSL_SHA256 и OpenSSL_SHA512.

SNMP

  • Добавлена поддержка SHA256 и SHA512 для протокола безопасности.

Стандартные модули

--with-password-argon2 теперь использует pkg-config для обнаружения libargon2. Таким образом, альтернативный путь к libargon2 теперь должен быть указан в PKG_CONFIG_PATH.

Изменения в обработке INI-файлов

  • INI-директива log_errors_max_len удалена. Начиная с PHP 8.0.0 она уже перестала работать.

  • Доллар в начале строки в кавычках теперь можно экранировать: "\${" теперь будет интерпретироваться как строка с содержимым ${.

  • Обратные слеши в строках с двойными кавычками теперь более последовательно рассматриваются как экранирующие символы. Раньше "foo\\", за которым следовало что-то, кроме новой строки, не считалось завершённой строкой. Теперь это интерпретируется как строка с содержимым foo\. Однако, как исключение, строка "foo\", за которой следует новая строка, будет по-прежнему рассматриваться как корректная строка с содержимым foo\, а не как незавершённая строка. Это исключение необходимо для поддержки простого использования путей к файлам Windows, таких как "C:\foo\".

Нормативный английский оригинал из frozen baseline

Этот слой сохраняет полный договор, если перевод отстаёт. Источник: английский нормативный оригинал.

Changes in SAPI Modules

CLI

Using -a without the readline extension will now result in an error. Previously, -a without readline had the same behavior as calling php without any arguments, apart from printing an additional "Interactive mode enabled" message. This mode was not interactive.

PHPDBG

Remote functionality from phpdbg has been removed.

Changed Functions

Core

The order of properties used in foreach, var_dump(), serialize(), object comparison, etc. was changed. Properties are now ordered naturally according to their declaration and inheritance. Properties declared in a base class are going to be before the child properties.

This order is consistent with internal layout of properties in zend_object structure and repeats the order in default_properties_table[] and properties_info_table[]. The old order was not documented and was caused by class inheritance implementation details.

Filter

The FILTER_FLAG_ALLOW_OCTAL flag of the FILTER_VALIDATE_INT filter now accept octal string with the leading octal prefix ("0o"/"0O").

GMP

All GMP functions now accept octal string with the leading octal prefix ("0o"/"0O").

PDO ODBC

PDO::getAttribute() with PDO::ATTR_SERVER_INFO and PDO::ATTR_SERVER_VERSION now return values instead of throwing PDOException.

Reflection

ReflectionProperty::setAccessible() and ReflectionMethod::setAccessible() no longer have an effect. Properties and methods are now always considered accessible via Reflection.

Standard

syslog() is now binary safe.

Other Changes to Extensions

GD

imagewebp() can now do lossless WebP encoding by passing IMG_WEBP_LOSSLESS as the quality.

This constant is only defined, if the used libgd supports lossless WebP encoding.

MySQLi

mysqli_stmt::next_result() and mysqli::fetch_all() are now available when linking against libmysqlclient.

OpenSSL

  • The OpenSSL extension now requires at least OpenSSL version 1.0.2.

  • OpenSSL 3.0 is now supported. Be aware that many ciphers are no longer enabled by default (part of the legacy provider), and that parameter validation (e.g. minimum key sizes) is stricter now.

Phar

  • SHA256 is now used by default for signatures.

  • Added support for OpenSSL_SHA256 and OpenSSL_SHA512 signatures.

SNMP

  • Added support for SHA256 and SHA512 for the security protocol.

Standard

--with-password-argon2 now uses pkg-config to detect libargon2. As such, an alternative libargon2 location should now be specified using PKG_CONFIG_PATH.

Changes to INI File Handling

  • The log_errors_max_len INI directive has been removed. It no longer had an effect since PHP 8.0.0.

  • A leading dollar in a quoted string can now be escaped: "\${" will now be interpreted as a string with contents ${.

  • Backslashes in double quoted strings are now more consistently treated as escape characters. Previously, "foo\\" followed by something other than a newline was not considered as a terminated string. It is now interpreted as a string with contents foo\. However, as an exception, the string "foo\" followed by a newline will continue to be treated as a valid string with contents foo\ rather than an unterminated string. This exception exists to support naive uses of Windows file paths such as "C:\foo\".

PHP 8.1 → 8.2

Этот узел — контрольная карта перехода PHP 8.1 → 8.2. Начинают не с переписывания всего проекта, а с инвентаризации runtime, расширений и зависимостей, затем включают полную диагностику и прогоняют тесты на копии данных.

Безопасный порядок обновления
  1. Зафиксировать рабочую версию, расширения, php.ini и внешние службы.
  2. Прочитать несовместимости и deprecation именно для следующего шага.
  3. Поднять новую версию рядом, выполнить тесты и сравнить ответы.
  4. Исправить код, повторить проверку, подготовить откат и только затем переключать трафик.
Полный официальный договор страницы

Ниже сохранён официальный русский текст и структура из зафиксированного архива PHP Manual. Отдельные ещё не переведённые страницы официального русского архива могут оставаться на английском.

Миграция с PHP 8.1.x на PHP 8.2.x

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

Смотрите также руководство по миграции для версий PHP 7.1.x, 7.2.x, 7.3.x, 7.4.x, 8.0.x, 8.1.x.

Нормативный английский оригинал из frozen baseline

Этот слой сохраняет полный договор, если перевод отстаёт. Источник: английский нормативный оригинал.

Migrating from PHP 8.1.x to PHP 8.2.x

This new minor version brings with it a number of new features and a few incompatibilities that should be tested for before switching PHP versions in production environments.

See also the migration guides for PHP versions 7.1.x, 7.2.x, 7.3.x, 7.4.x, 8.0.x, 8.1.x.

PHP 8.1 → 8.2: Новые возможности языка и платформы

Страница отвечает на вопрос «что нового можно применять после обновления». Новая запись не должна случайно попасть в код, который ещё запускается на старом runtime: минимальную версию фиксируют в Composer и проверяют в CI.

Полный официальный договор страницы

Ниже сохранён официальный русский текст и структура из зафиксированного архива PHP Manual. Отдельные ещё не переведённые страницы официального русского архива могут оставаться на английском.

Ядро PHP

Атрибут SensitiveParameter

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

INI-директива error_log_mode

Добавлена INI-директива error_log_mode, которая позволяет установить разрешения для файла журнала ошибок.

Свойства перечислений в константных выражениях

Теперь можно получать свойства перечислений в константных выражениях.

Улучшения системы типов

Теперь можно использовать null и false как самостоятельные типы.

Добавлен тип true.

Теперь можно комбинировать пересечение и объединение типов. Тип должен быть записан в виде DNF.

Константы в трейтах

Теперь в трейтах можно определять константы.

Классы, доступные только для чтения

Добавлена поддержка readonly для классов.

cURL

Добавлена опция CURLINFO_EFFECTIVE_METHOD, которая возвращает последний использованный метод HTTP в возвращаемом значении функции curl_getinfo().

Стало доступно множество новых констант из libcurl 7.62 - 7.80.

Добавлена функция curl_upkeep() для выполнения любых проверок восстановления соединения.

DBA

Драйвер LMDB теперь принимает флаги DBA_LMDB_USE_SUB_DIR или DBA_LMDB_NO_SUB_DIR, чтобы определить, должен ли он создавать подкаталог или нет при создании файла базы данных.

OCI8

Добавлены INI-директива oci8.prefetch_lob_size и функция oci_set_prefetch_lob() для настройки производительности LOB-запросов путём уменьшения количества обходов между PHP и базами данных Oracle при выборке LOBS. Её можно использовать с Oracle Database 12.2 или более поздней версией.

OpenSSL

Добавлена поддержка AEAD-алгоритма chacha20-poly1305.

ODBC

Добавлены функции odbc_connection_string_is_quoted(), odbc_connection_string_should_quote() и odbc_connection_string_quote(). В основном они используются внутри самих модулей ODBC и PDO_ODBC, но для облегчения модульного тестирования теперь доступны извне. Кроме этого, ими можно воспользоваться для экранирования строки из пользовательских приложений.

PCRE

Добавлена поддержка модификатора n (NO_AUTO_CAPTURE), который делает простые группы (xyz) не перехватываемыми. Перехватываются только именованные группы типа (?<name>xyz). Это влияет только на то, какие группы перехватываются, по-прежнему можно использовать нумерованные ссылки на подшаблоны и массив совпадений по-прежнему будет содержать нумерованные результаты.

Random

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

Нормативный английский оригинал из frozen baseline

Этот слой сохраняет полный договор, если перевод отстаёт. Источник: английский нормативный оригинал.

PHP Core

SensitiveParameter Attribute

Added the #[\SensitiveParameter] attribute to redact sensitive data in backtraces.

error_log_mode INI directive

The error_log_mode INI directive has been added which allows setting the permissions for the error log file.

Enumerations properties in constant expressions

It is now possible to fetch properties of Enumerations in constant expressions.

Type System Improvements

It is now possible to use null and false as stand-alone types.

The true type has been added.

It is now possible to combine intersection and union types. The type needs to be written in DNF.

Constants in Traits

It is now possible to define constants in traits.

Readonly Classes

Support for readonly on classes has been added.

cURL

Added the CURLINFO_EFFECTIVE_METHOD option, which returns the effective HTTP method in the return value of curl_getinfo().

Exposed multiple new constants from libcurl 7.62 to 7.80.

Added the curl_upkeep() function to perform any connection upkeep checks.

DBA

The LMDB Driver now accepts the DBA_LMDB_USE_SUB_DIR or DBA_LMDB_NO_SUB_DIR flags to determine if it should create a subdirectory or not when creating a database file.

OCI8

Added the oci8.prefetch_lob_size INI directive and oci_set_prefetch_lob() function to tune LOB query performance by reducing the number of round-trips between PHP and Oracle Databases when fetching LOBS. This is usable with Oracle Database 12.2 or later.

OpenSSL

Added AEAD support for the chacha20-poly1305 algorithm.

ODBC

Added the odbc_connection_string_is_quoted(), odbc_connection_string_should_quote(), and odbc_connection_string_quote() functions. These are primarily used behind the scenes in the ODBC and PDO_ODBC extensions, but are exposed to userland for easier unit testing, and for user applications and libraries to perform quoting themselves.

PCRE

Added support for the n (NO_AUTO_CAPTURE) modifier, which makes simple (xyz) groups non-capturing. Only named groups like (?<name>xyz) are capturing. This only affects which groups are capturing, it is still possible to use numbered subpattern references, and the matches array will still contain numbered results.

Random

This is a new extension which organises and consolidates existing implementations related to random number generators. New and better RNGs are available with scope issues eliminated.

PHP 8.2+: неизменяемое значение после созданияСамостоятельный пример
<?php
readonly class Money
{
    public function __construct(public int $kopecks) {}
}

$price = new Money(129900);
echo $price->kopecks, "\n";
Ожидаемый результат
129900

readonly class запрещает обычную перенастройку свойств после инициализации, но сам по себе не проверяет, что сумма неотрицательна: инвариант добавляет конструктор.

PHP 8.1 → 8.2: Новые функции и методы

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

Полный официальный договор страницы

Ниже сохранён официальный русский текст и структура из зафиксированного архива PHP Manual. Отдельные ещё не переведённые страницы официального русского архива могут оставаться на английском.

Нормативный английский оригинал из frozen baseline

Этот слой сохраняет полный договор, если перевод отстаёт. Источник: английский нормативный оригинал.

PHP 8.1 → 8.2: Новые глобальные константы

Новые константы описывают возможности runtime и расширений. Их нельзя считать включёнными только по версии PHP: для расширений дополнительно проверяют загрузку модуля, а для необязательной ветки — defined().

Полный официальный договор страницы

Ниже сохранён официальный русский текст и структура из зафиксированного архива PHP Manual. Отдельные ещё не переведённые страницы официального русского архива могут оставаться на английском.

cURL

Сокеты

Следующие опции сокетов теперь определяются, если они поддерживаются:

Нормативный английский оригинал из frozen baseline

Этот слой сохраняет полный договор, если перевод отстаёт. Источник: английский нормативный оригинал.

cURL

Sockets

The following socket options are now defined if they are supported:

PHP 8.1 → 8.2: Обратно несовместимые изменения

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

Полный официальный договор страницы

Ниже сохранён официальный русский текст и структура из зафиксированного архива PHP Manual. Отдельные ещё не переведённые страницы официального русского архива могут оставаться на английском.

Date

У метода DateTime::createFromImmutable() теперь предварительный возвращаемый тип static, ранее возвращаемый тип был DateTime.

У метода DateTimeImmutable::createFromMutable() теперь предварительный возвращаемый тип static, ранее возвращаемый тип был DateTimeImmutable.

Символы number в относительных форматах больше не принимают несколько знаков, например, +-2.

ODBC

Модуль ODBC теперь экранирует имя пользователя и пароль в случае, если передаётся строка соединения вместе с именем пользователя/паролем, тогда строка соединения будет изменена. Раньше при использовании пользовательских значений, нуждающихся в экранировании, могли сгенерировать неправильную строку соединения или вставить значения из данных, полученных от пользователя. Правила экранирования должны быть идентичны поведению .NET BCL DbConnectionOptions.

PDO_ODBC

Модуль PDO_ODBC также экранирует имя пользователя и пароль при передаче строки подключения. Дополнительные сведения смотрите в разделе изменение модуля ODBC.

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

Функция glob() теперь возвращает пустой массив (array), если все пути находятся вне пределов директории, определённой в open_basedir. Ранее функция возвращала false. Более того, предупреждение теперь выдаётся, даже если только некоторые пути ограничены с помощью директивы open_basedir.

Метод FilesystemIterator::__construct(): до версии PHP 8.2.0 константа FilesystemIterator::SKIP_DOTS была установлена всегда и не могла быть отключена. Для сохранения прежнего поведения константа должна быть явно установлена при использовании параметра flags. Значение по умолчанию параметра flags не было изменено.

Функции strtolower(), strtoupper(), stristr(), stripos(), strripos(), lcfirst(), ucfirst(), ucwords() и str_ireplace() больше не чувствительны к локализации. Теперь они выполняют преобразование регистра ASCII, как если бы локаль была "C". Локализованные версии этих функций доступны в модуле MBString. Более того, функция array_change_key_case() и сортировка с помощью SORT_FLAG_CASE теперь также используют преобразование регистра ASCII.

Функция str_split() теперь возвращает пустой массив (array), если была вызвана с пустой строки (string). Ранее она возвращала массив с одной пустой строкой. На функцию mb_str_split() это изменение не влияет, так как она уже работала подобным образом.

Функции ksort() и krsort() теперь выполняют сравнение числовых строк при SORT_REGULAR, используя стандартные правила PHP 8.

Функция var_export() больше не опускает ведущий обратный слеш для экспортируемых классов, т.е. они теперь полностью квалифицированы.

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

Следующие методы теперь усиливают свою сигнатуру:

У метода SplFileObject::hasChildren() теперь предварительный возвращаемый тип false, ранее он был bool.

У метода SplFileObject::getChildren() теперь предварительный возвращаемый тип null, ранее он был ?RecursiveIterator.

Класс GlobIterator теперь возвращает пустой массив (array), если все пути находятся вне пределов директории, заданной в open_basedir. Ранее он возвращал false. Более того, теперь выдаётся предупреждение, даже если только некоторые из путей находятся за пределами open_basedir.

Нормативный английский оригинал из frozen baseline

Этот слой сохраняет полный договор, если перевод отстаёт. Источник: английский нормативный оригинал.

Date

DateTime::createFromImmutable() now has a tentative return type of static, previously it was DateTime.

DateTimeImmutable::createFromMutable() now has a tentative return type of static, previously it was DateTimeImmutable.

number symbols in relative formats no longer accept multiple signs, e.g. +-2.

ODBC

The ODBC extension now escapes the username and password for the case when both a connection string and username/password are passed, and the string must be appended to. Before, user values containing values needing escaping could have created a malformed connection string, or injected values from user-provided data. The escaping rules should be identical to the .NET BCL DbConnectionOptions behaviour.

PDO_ODBC

The PDO_ODBC extension also escapes the username and password when a connection string is passed. See the change to the ODBC extension for further details.

Standard

glob() now returns an empty array if all paths are restricted by open_basedir. Previously it returned false. Moreover, a warning is now emitted even if only some paths are restricted by open_basedir.

FilesystemIterator::__construct(): prior to PHP 8.2.0, FilesystemIterator::SKIP_DOTS constant was always set and couldn't be disabled. In order to maintain the previous behaviour the constant must be explicitly set when using the flags parameter. The default value from flags parameter has not been modified.

strtolower(), strtoupper(), stristr(), stripos(), strripos(), lcfirst(), ucfirst(), ucwords(), and str_ireplace() are no longer locale-sensitive. They now perform ASCII case conversion, as if the locale were "C". Localized versions of these functions are available in the MBString extension. Moreover, array_change_key_case(), and sorting with SORT_FLAG_CASE now also use ASCII case conversion.

str_split() returns an empty array for an empty string now. Previously it returned an array with a single empty string entry. mb_str_split() is not affected by this change as it was already behaving like that.

ksort() and krsort() now do numeric string comparison under SORT_REGULAR using the standard PHP 8 rules now.

var_export() no longer omits the leading backslash for exported classes, i.e. these are now fully qualified.

Standard PHP Library (SPL)

The following methods now enforce their signature:

SplFileObject::hasChildren() now has a tentative return type of false, previously it was bool.

SplFileObject::getChildren() now has a tentative return type of null, previously it was ?RecursiveIterator.

GlobIterator now returns an empty array if all paths are restricted by open_basedir. Previously it returned false. Moreover, a warning is now emitted even if only some paths are restricted by open_basedir.

PHP 8.1 → 8.2: Устаревшие возможности

Устаревание — раннее предупреждение, а не немедленное удаление. На тестовом контуре включают E_ALL, собирают deprecation без подавления, выбирают замену и исправляют собственный код до следующей мажорной версии.

Полный официальный договор страницы

Ниже сохранён официальный русский текст и структура из зафиксированного архива PHP Manual. Отдельные ещё не переведённые страницы официального русского архива могут оставаться на английском.

Ядро PHP

Использование динамических свойств

Создание динамических свойств объявлено устаревшим, за исключением, если класс не обрабатывает их использование с помощью атрибута #[\AllowDynamicProperties]. На экземплярах stdClass по-прежнему можно использовать динамические свойства. Изменение не влияет на использование магических методов __get()/__set(). Предупреждение об устаревании динамических свойств можно устранить с помощью:

  • Объявления свойства (лучше всего).
  • Добавления атрибута #[\AllowDynamicProperties] к классу (который также применяется ко всем дочерним классам).
  • Использования WeakMap, если необходимо связать дополнительные данные с объектом, который не принадлежит пользователю.

Вызовы методов с относительным именем

Вызываемые методы, не соответствующие синтаксису $callable() (но работают с call_user_func()), объявлены устаревшими. В частности:

  • "self::method"
  • "parent::method"
  • "static::method"
  • ["self", "method"]
  • ["parent", "method"]
  • ["static", "method"]
  • ["Foo", "Bar::method"]
  • [new Foo, "Bar::method"]
Это изменение не влияет на обычные вызываемые методы, такие как "A::method" или ["A", "method"].

Интерполяция вида "${var}" и "${expr}"

Стиль интерполяции строк "${var}" и "${expr}" объявлен устаревшим. Используйте "$var"/"{$var}" и "{${expr}}" соответственно.

MBString

Использование кодировок текста QPrint, Base64, Uuencode и HTML-ENTITIES объявлено устаревшим для всех функций MBString. В отличие от остальных текстовых кодировок, поддерживаемых MBString, эти кодировки не кодируют последовательность кодовых точек Unicode, а только последовательность необработанных байтов. Неясно, какими должны быть правильные возвращаемые значения для большинства функций MBString, если указана одна из этих кодировок. Более того, в PHP есть встроенные реализации всех этих кодировок; например, UU-закодированные данные можно обрабатывать с помощью функций convert_uuencode()/convert_uudecode().

SPL

Внутренний метод SplFileInfo::_bad_state_ex() объявлен устаревшим.

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

Функции utf8_encode() и utf8_decode() объявлены устаревшими.

Нормативный английский оригинал из frozen baseline

Этот слой сохраняет полный договор, если перевод отстаёт. Источник: английский нормативный оригинал.

PHP Core

Usage of dynamic properties

The creation of dynamic properties is deprecated, unless the class opts in by using the #[\AllowDynamicProperties] attribute. stdClass allows dynamic properties. Usage of the __get()/__set() magic methods is not affected by this change. A dynamic properties deprecation warning can be addressed by:

  • Declaring the property (preferred).
  • Adding the #[\AllowDynamicProperties] attribute to the class (which also applies to all child classes).
  • Using a WeakMap if additional data needs to be associated with an object which one does not own.

Relative callables

Callables that are not accepted by the $callable() syntax (but are accepted by call_user_func()) are deprecated. In particular:

  • "self::method"
  • "parent::method"
  • "static::method"
  • ["self", "method"]
  • ["parent", "method"]
  • ["static", "method"]
  • ["Foo", "Bar::method"]
  • [new Foo, "Bar::method"]
This does not affect normal method callables such as "A::method" or ["A", "method"].

"${var}" and "${expr}" style interpolation

The "${var}" and "${expr}" style of string interpolation is deprecated. Use "$var"/"{$var}" and "{${expr}}", respectively.

MBString

Usage of the QPrint, Base64, Uuencode, and HTML-ENTITIES 'text encodings' is deprecated for all MBString functions. Unlike all the other text encodings supported by MBString, these do not encode a sequence of Unicode codepoints, but rather a sequence of raw bytes. It is not clear what the correct return values for most MBString functions should be when one of these non-encodings is specified. Moreover, PHP has separate, built-in implementations of all of them; for example, UUencoded data can be handled using convert_uuencode()/convert_uudecode().

SPL

The internal SplFileInfo::_bad_state_ex() method has been deprecated.

Standard

utf8_encode() and utf8_decode() have been deprecated.

PHP 8.1 → 8.2: Другие изменения

Сюда попадают изменения поведения, конфигурации и расширений, которые не образуют новую синтаксическую конструкцию. Их сверяют с фактически установленными модулями и рабочими сценариями проекта.

Полный официальный договор страницы

Ниже сохранён официальный русский текст и структура из зафиксированного архива PHP Manual. Отдельные ещё не переведённые страницы официального русского архива могут оставаться на английском.

Изменения в ядре

Тип iterable теперь — встроенный во время компиляции псевдоним для типа array|Traversable. Поэтому сообщения об ошибках, которые связаны с типом iterable, теперь будут использовать сигнатуру array|Traversable. Тип Reflection сохраняется для одиночного iterable (и ?iterable) для создания ReflectionNamedType с именем iterable, однако использование iterable в объединениях типов будет преобразовано в array|Traversable.

Формат даты отправляемых файлов cookie теперь 'D, d M Y H:i:s \G\M\T'; ранее он был 'D, d-M-Y H:i:s T'.

Изменения в модулях SAPI

CLI

Потоки STDOUT, STDERR и STDIN больше не закрываются при уничтожении ресурсов, что чаще всего происходит при завершении работы CLI. Однако по-прежнему можно явно закрыть эти потоки с помощью функции fclose() и подобных функций.

Изменённые функции

Ядро PHP

Функции strcmp(), strcasecmp(), strncmp(), strncasecmp() и substr_compare(), которые сравнивают строки бинарно-безопасным способом, больше не гарантируют возврат результата strlen($string1) - strlen($string2), когда длины строк не равны, но теперь вместо этого могут возвращать значения -1 или 1. Вместо зависимости от какого-либо конкретного значения, возвращаемое значение должно сравниваться со значением 0.

DBA

У функции dba_open() и dba_popen() теперь следующая принудительная сигнатура:

functiondba_open(
string$path,
string$mode,
?string$handler = null,
int$permission = 0644,
int$map_size = 0,
?int$flags = null
): resource|false

Необязательный аргумент skip функции dba_fetch() теперь находится в конце в соответствии с семантикой пользовательского пространства PHP. Теперь его сигнатура выглядит следующим образом:

functiondba_fetch(string|array$key, resource$handle, int$skip): string|false
Предыдущая сигнатура:
functiondba_fetch(string|array$key, int$skip, resource$handle): string|false
по-прежнему принимается, но рекомендуется использовать новый стандартный вариант.

Random

Функции random_bytes() и random_int() теперь выбрасывают исключение \Random\RandomException в случае возникновения ошибок CSPRNG. Ранее вместо этого выбрасывалось обычное исключение \Exception.

SPL

Параметр iterator функций iterator_to_array() и iterator_count() расширен до iterable из Iterator, позволяя передавать массивы.

Другие изменения в модулях

Date

Свойства DatePeriod теперь объявлены правильно.

Intl

Экземпляры IntlBreakIterator, IntlRuleBasedBreakIterator, IntlCodePointBreakIterator, IntlPartsIterator, IntlCalendar, Collator, IntlIterator, UConverter, IntlDateFormatter, IntlDatePatternGenerator, MessageFormatter, ResourceBundle, Spoofchecker, IntlTimeZone и Transliterator больше не являются сериализуемыми. Ранее их можно было сериализовать, но при десериализации получались непригодные объекты или возникали ошибки.

MySQLi

Поддержка libmysql была удалена и теперь невозможно скомпилировать mysqli с libmysql. С этого момента модуль mysqli можно компилировать только с помощью mysqlnd. Все функции libmysql, недоступные в mysqlnd, были удалены:

OCI8

Минимальная необходимая версия библиотеки Oracle Client теперь 11.2.

PCRE

Теперь поддерживаются символы NUL (\0) в строках шаблонов.

Сессия

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

SQLite3

sqlite3.defensive теперь INI_USER.

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

Функция getimagesize() теперь сообщает фактические размеры, биты и каналы изображений AVIF. Ранее размеры сообщались как 0x0, а биты и каналы вообще не сообщались.

Tidy

Свойства класса tidy теперь объявлены правильно. А свойства класса tidyNode теперь правильно объявлены как доступные только для чтения.

Zip

Модуль Zip был обновлён до версии 1.20.0, в которой добавлены следующие методы:

Изменения в работе с INI-файлами

К целочисленным INI-параметрам добавлена поддержка двоичных (0b/0B) и восьмеричных (0o/0O) префиксов. Целочисленные INI-параметры, начинающиеся с нуля (0), продолжают интерпретироваться как восьмеричное целое число.

При разборе некоторых неправильно отформатированных значений теперь будет выдаваться предупреждение, если раньше это молча игнорировалось. Для обратной совместимости интерпретация этих значений не изменилась. Это влияет на следующие настройки:

Нормативный английский оригинал из frozen baseline

Этот слой сохраняет полный договор, если перевод отстаёт. Источник: английский нормативный оригинал.

Core changes

The iterable type is now a built-in compile time alias for array|Traversable. Error messages relating to iterable will therefore now use array|Traversable. Type Reflection is preserved for single iterable (and ?iterable) to produce a ReflectionNamedType with name iterable, however usage of iterable in union types will be converted to array|Traversable.

The date format of sent cookies is now 'D, d M Y H:i:s \G\M\T'; previously it was 'D, d-M-Y H:i:s T'.

Changes in SAPI Modules

CLI

The STDOUT, STDERR and STDIN streams are no longer closed on resource destruction which is mostly when the CLI finishes. It is however still possible to explicitly close those streams using fclose() and similar.

Changed Functions

Core

The strcmp(), strcasecmp(), strncmp(), strncasecmp(), and substr_compare() functions, using binary safe string comparison is no longer guaranteed to return strlen($string1) - strlen($string2) when string lengths are not equal, but may now return -1 or 1 instead. Instead of depending on any concrete value, the return value should be compared to 0.

DBA

dba_open() and dba_popen() now have the following enforced signature:

functiondba_open(
string$path,
string$mode,
?string$handler = null,
int$permission = 0644,
int$map_size = 0,
?int$flags = null
): resource|false

dba_fetch()'s optional skip argument is now at the end in line with PHP userland semantics. Its signature is now:

functiondba_fetch(string|array$key, resource$handle, int$skip): string|false
The overloaded signature:
functiondba_fetch(string|array$key, int$skip, resource$handle): string|false
is still accepted, but it is recommended to use the new standard variant.

Random

random_bytes() and random_int() now throw a \Random\RandomException on CSPRNG failures. Previously a plain \Exception was thrown instead.

SPL

The iterator parameter of iterator_to_array() and iterator_count() is widened to iterable from Iterator, allowing arrays to be passed.

Other Changes to Extensions

Date

The properties of DatePeriod are now properly declared.

Default timezone will fall back to UTC if the date.timezone ini setting is not set.

Intl

Instances of IntlBreakIterator, IntlRuleBasedBreakIterator, IntlCodePointBreakIterator, IntlPartsIterator, IntlCalendar, Collator, IntlIterator, UConverter, IntlDateFormatter, IntlDatePatternGenerator, MessageFormatter, ResourceBundle, Spoofchecker, IntlTimeZone, and Transliterator are no longer serializable. Previously, they could be serialized, but unserialization yielded unusable objects or failed.

MySQLi

The support for libmysql has been removed and it is no longer possible to compile mysqli with libmysql. From now on, the mysqli extension can be compiled only with mysqlnd. All libmysql features unavailable in mysqlnd have been removed:

OCI8

The minimum Oracle Client library version required is now 11.2.

PCRE

NUL characters (\0) in pattern strings are now supported.

Session

Trying to change the session.cookie_samesite INI directive while the session is active or output has already been sent will now fail and emit a warning. This aligns the behaviour with all other session INI settings.

SQLite3

sqlite3.defensive is now INI_USER.

Standard

getimagesize() now reports the actual image dimensions, bits and channels of AVIF images. Previously, the dimensions have been reported as 0x0, and bits and channels have not been reported at all.

Tidy

The properties of the tidy class are now properly declared. And those of the tidyNode class are now properly declared as readonly.

Zip

The Zip extension has been updated to version 1.20.0, which adds the following methods:

Changes to INI File Handling

Support for binary (0b/0B) and octal (0o/0O) prefixes has been added to integer INI settings. Integer INI settings that start with a zero (0) continue to be interpreted as an octal integer.

Parsing of some ill-formatted values will now trigger a warning when this was silently ignored before. For backwards compatibility, interpretation of these values has not changed. This affects the following settings:

PHP 8.1 → 8.2: Изменения поддержки Windows

Платформенные изменения проверяют в Windows-ветке CI: пути, кодировки, DLL, сигналы и сетевые детали нельзя надёжно подтвердить только Linux-тестом.

Полный официальный договор страницы

Ниже сохранён официальный русский текст и структура из зафиксированного архива PHP Manual. Отдельные ещё не переведённые страницы официального русского архива могут оставаться на английском.

Ядро

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

Добавлена предварительная и экспериментальная поддержка сборки на ARM64.

OCI8

Поскольку сборка на Oracle Client 10g больше не поддерживается, опция конфигурации --with-oci8 была исключена. Опции конфигурации --with-oci8-11g, --with-oci8-12c и --with-oci8-19 по-прежнему поддерживаются.

Zip

Модуль Zip обновлён до версии 1.21.0 и теперь по умолчанию собирается как разделяемая библиотека (DLL).

Нормативный английский оригинал из frozen baseline

Этот слой сохраняет полный договор, если перевод отстаёт. Источник: английский нормативный оригинал.

Core

Windows specific error messages are no longer localized, but instead always displayed in English to better match PHP error messages.

Preliminary and highly experimental support for building on ARM64 has been added.

OCI8

Because building against Oracle Client 10g is no longer supported anyway, the configuration option --with-oci8 has been dropped. The --with-oci8-11g, --with-oci8-12c and --with-oci8-19 configuration options are still supported.

Zip

The Zip extension is upgraded to version 1.21.0, and is now built as shared library (DLL) by default.

PHP 8.2 → 8.3

Этот узел — контрольная карта перехода PHP 8.2 → 8.3. Начинают не с переписывания всего проекта, а с инвентаризации runtime, расширений и зависимостей, затем включают полную диагностику и прогоняют тесты на копии данных.

Безопасный порядок обновления
  1. Зафиксировать рабочую версию, расширения, php.ini и внешние службы.
  2. Прочитать несовместимости и deprecation именно для следующего шага.
  3. Поднять новую версию рядом, выполнить тесты и сравнить ответы.
  4. Исправить код, повторить проверку, подготовить откат и только затем переключать трафик.
Полный официальный договор страницы

Ниже сохранён официальный русский текст и структура из зафиксированного архива PHP Manual. Отдельные ещё не переведённые страницы официального русского архива могут оставаться на английском.

Миграция с PHP 8.2.x на PHP 8.3.x

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

Смотрите также руководство по миграции для версий PHP 7.1.x, 7.2.x, 7.3.x, 7.4.x, 8.0.x, 8.1.x, 8.2.x.

Нормативный английский оригинал из frozen baseline

Этот слой сохраняет полный договор, если перевод отстаёт. Источник: английский нормативный оригинал.

Migrating from PHP 8.2.x to PHP 8.3.x

This new minor version brings with it a number of new features and a few incompatibilities that should be tested for before switching PHP versions in production environments.

See also the migration guides for PHP versions 7.1.x, 7.2.x, 7.3.x, 7.4.x, 8.0.x, 8.1.x, 8.2.x.

PHP 8.2 → 8.3: Новые возможности языка и платформы

Страница отвечает на вопрос «что нового можно применять после обновления». Новая запись не должна случайно попасть в код, который ещё запускается на старом runtime: минимальную версию фиксируют в Composer и проверяют в CI.

Полный официальный договор страницы

Ниже сохранён официальный русский текст и структура из зафиксированного архива PHP Manual. Отдельные ещё не переведённые страницы официального русского архива могут оставаться на английском.

Ядро PHP

Изменения Readonly

Анонимные классы теперь могут быть помечены как доступные только для чтения.

Свойства с доступом только для чтения теперь можно повторно инициализировать при клонировании.

Типизированные константы класса

Классы, интерфейсы, трейты и константы перечислений теперь поддерживают объявления типов.

Замыкания, которые создали в магических методах

Замыкания, которые создали в магических методах, теперь принимают именованные аргументы.

Модификатор final в блоках адаптации трейтов

Блоки адаптации трейтов стали поддерживать конструкцию as final, которая внедряет неокончательный метод трейта как окончательный и запрещает переопределение метода в производных классах.

Атрибут Override

Добавили атрибут #[\Override], который проверяет объявление метода в родительском классе или интерфейсе.

получение констант классов динамическим синтаксисом

Появилась поддержка доступа к константам класса через переменные: C::{$name}.

Инициализация статических переменных

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

Синтаксис резервных значений для ini-переменных

Файл php.ini теперь поддерживает синтаксис резервных и установленных по умолчанию значений.

<?php

/*
Путь /path/to/user.ini содержит следующие настройки:

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

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

Командная строка CLI

В режиме CLI теперь поддерживается множественная проверка синтаксиса файлов: php -l file1.php file2.php.

Модуль DOM

Добавили свойства DOMElement::$className и DOMElement::$id. Пока они не бинарно-безопасные из-за общих ограничений библиотеки libxml2. Это означает, что значения свойств будут обрезаны на NUL-байте.

Добавили свойства DOMNode::$isConnected и DOMNameSpaceNode::$isConnected.

Добавили свойства DOMNode::$parentElement и DOMNameSpaceNode::$parentElement.

Модуль FFI

Модуль теперь поддерживает присваивание объектов FFI\CData другим объектам FFI\CData — структурам и полям.

Модуль Opcache

Элементы opcache_get_status()['scripts'][n]['revalidate'] теперь содержат метку времени Unix, которая генерируется на основе значения INI-директивы opcache.revalidate_freq и указывает время следующей проверки метки времени скриптов.

Модуль POSIX

Функция posix_getrlimit() теперь содержит необязательный параметр $resource, чтобы разрешить получение ограничения отдельного ресурса.

Функция posix_isatty() теперь выдаёт предупреждения о типе целых чисел, следуя обычной семантике ZPP.

Функция posix_ttyname() теперь выдаёт предупреждения о типе целых чисел, следуя обычной семантике класса ZPP, и предупреждения о значениях для недействительных целых чисел дескриптора файла.

Потоки

Потоки теперь выдают уведомление STREAM_NOTIFY_COMPLETED. Раньше это не было реализовано.

Нормативный английский оригинал из frozen baseline

Этот слой сохраняет полный договор, если перевод отстаёт. Источник: английский нормативный оригинал.

PHP Core

Readonly Amendments

Anonymous classes may now be marked as readonly.

Readonly properties can now be reinitialized during cloning.

Typed Class Constants

Class, interface, trait, and enum constants now support type declarations.

Closures created from magic methods

Closures created from magic methods can now accept named arguments.

The final modifier with a method from a trait

The final modifier may now be used when using a method from a trait.

Override Attribute

Added the #[\Override] attribute to check that a method exists in a parent class or implemented interface.

Fetch class constant dynamically syntax

Class constants can now be accessed dynamically using the C::{$name} syntax.

Static variable Initializers

Static variable initializers can now contain arbitrary expressions.

Fallback value syntax for ini variables

php.ini now supports fallback/default value syntax.

<?php
/*
/path/to/user.ini contains the following settings:

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

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

CLI

It is now possible to lint multiple files.

DOM

Added properties DOMElement::$className and DOMElement::$id. These are not binary-safe at the moment because of underlying limitations of libxml2. This means that the property values will be cut off at a NUL byte.

Added properties DOMNode::$isConnected and DOMNameSpaceNode::$isConnected.

Added properties DOMNode::$parentElement and DOMNameSpaceNode::$parentElement.

FFI

It is now possible to assign FFI\CData to other FFI\CData. Meaning CData can now be assigned to structs and fields.

Opcache

opcache_get_status()['scripts'][n]['revalidate'] now contains a Unix timestamp of when the next revalidation of the scripts timestamp is due, dictated by the opcache.revalidate_freq INI directive.

POSIX

posix_getrlimit() now takes an optional resource parameter to allow fetching a single resource limit.

posix_isatty() now raises type warnings for integers following the usual ZPP semantics.

posix_ttyname() now raises type warnings for integers following the usual ZPP semantics and value warnings for invalid file descriptor integers.

Streams

Streams can now emit the STREAM_NOTIFY_COMPLETED notification. This was previously not implemented.

PHP 8.2 → 8.3: Новые классы, интерфейсы и перечисления

Новые классы, интерфейсы и enum доступны только в указанной ветке PHP или расширения. Перед условной интеграцией проверяют версию и наличие расширения; для обязательной зависимости ранний отказ понятнее тихой деградации.

Полный официальный договор страницы

Ниже сохранён официальный русский текст и структура из зафиксированного архива PHP Manual. Отдельные ещё не переведённые страницы официального русского архива могут оставаться на английском.

PHP 8.2 → 8.3: Новые функции и методы

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

Полный официальный договор страницы

Ниже сохранён официальный русский текст и структура из зафиксированного архива PHP Manual. Отдельные ещё не переведённые страницы официального русского архива могут оставаться на английском.

Нормативный английский оригинал из frozen baseline

Этот слой сохраняет полный договор, если перевод отстаёт. Источник: английский нормативный оригинал.

PHP 8.2 → 8.3: Новые глобальные константы

Новые константы описывают возможности runtime и расширений. Их нельзя считать включёнными только по версии PHP: для расширений дополнительно проверяют загрузку модуля, а для необязательной ветки — defined().

Полный официальный договор страницы

Ниже сохранён официальный русский текст и структура из зафиксированного архива PHP Manual. Отдельные ещё не переведённые страницы официального русского архива могут оставаться на английском.

cURL

Intl

PCNTL

Sockets

Следующие опции сокетов теперь определяются, если они поддерживаются:

Нормативный английский оригинал из frozen baseline

Этот слой сохраняет полный договор, если перевод отстаёт. Источник: английский нормативный оригинал.

cURL

Intl

PCNTL

Sockets

The following socket options are now defined if they are supported:

PHP 8.2 → 8.3: Обратно несовместимые изменения

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

Полный официальный договор страницы

Ниже сохранён официальный русский текст и структура из зафиксированного архива PHP Manual. Отдельные ещё не переведённые страницы официального русского архива могут оставаться на английском.

Ядро PHP

Программы, которые были очень близки к переполнению стека вызовов

Программы, которые были очень близки к переполнению стека вызовов, теперь могут выбрасывать исключение Error, когда занятый в байтах размер стека больше, чем определено в настройке zend.max_allowed_stack_size-zend.reserved_stack_size (fiber.stack_size-zend.reserved_stack_size для файберов).

Выполнение функции proc_get_status() несколько раз

Выполнение функции proc_get_status() несколько раз теперь всегда возвращает правильное значение в POSIX-системах. Ранее только первый вызов функции возвращал правильное значение. Выполнение функции proc_close() после функции proc_get_status() теперь также возвращает правильный код выхода. Ранее это вернуло бы значение -1. Внутренне это работает через кеширование результата на POSIX-системах. Если требуется прежнее поведение, можно проверить ключ «cached» в массиве, который возвращает функция proc_get_status(), чтобы проверить, был ли кеширован результат.

Таймеры Zend Max Execution

Таймеры Zend Max Execution теперь по умолчанию включены для сборок ZTS в системах Linux.

Включение трейтов со статическими свойствами

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

Присваивание отрицательного индекса пустому массиву

При добавлении в массив с занятым отрицательным индексом, который, предположим, хранится в переменной $n, нового значения, следующий индекс получит значение $n + 1, а не 0.

Проверка несоответствия видимости констант классов

Несоответствия видимости констант классов теперь будет корректно проверено при реализации интерфейсов.

Записи WeakMap, ключ которых соответствует самим себе

Записи объекта WeakMap, ключ которых сопоставлен с самим собой, (возможно, транзитивно) теперь можно удалить во время сбора цикла если ключ недоступен, кроме как путём перебора значений WeakMap (доступность во время перебора считается слабой). Ранее такие записи не были бы удалены автоматически.

Модуль Date

Вместо предупреждений и общих исключений в модуль DateTime были добавлены свойственные только ему исключения и ошибки в иерархии классов DateError и DateException. Это улучшает обработку ошибок и исключений, когда нужно проверить их существование.

Модуль DOM

Вызов методов DOMChildNode::after(), DOMChildNode::before() и DOMChildNode::replaceWith() на узле, у которого нет родительского узла теперь неработоспособно, а не исключением иерархии, чтобы поведение было совместимым со спецификацией DOM.

Вызов методов классов DOMParentNode и DOMChildNode без документа теперь работает, а не выбрасывает исключения DOM_HIERARCHY_REQUEST_ERR класса DOMException. Это соответствует поведению спецификации DOM.

Вызов метода DOMDocument::createAttributeNS() без префикса неправильно бы создал пространство имён по умолчанию, помещая элемент внутрь пространства имён вместо атрибута. Эта ошибка теперь исправлена.

Метод DOMDocument::createAttributeNS() раньше неправильно бросал исключение DOM_NAMESPACE_ERRNAMESPACE_ERR класса DOMException, когда префикс уже был занят другим URI. Теперь он правильно выбирает другой префикс при конфликте префиксов.

Новые методы и свойства были добавлены в ряд классов DOM. Если пользовательский класс наследуется от этих классов и объявляет метод или свойство с таким же именем, оно должно быть совместимым. В других случаях будет выброшена типичная ошибка компиляции о несовместимости. Познакомиться со списком новых методов и свойств можно в разделах список новой функциональности и новые функции.

Класс FFI

Функции языка Си, для которых задан возвращаемый тип void, теперь возвращают значение null вместо вместо объекта object(FFI\CData:void) { }.

Модуль Opcache

Настройка INI-директивы opcache.consistency_checks была удалена. Эта функция не работала при трассировке JIT, а также с кешем наследования, и была отключена в PHP 8.1.18 и PHP 8.2.5; теперь её невозможно включить. И трассирующий JIT, и кеш наследования могут изменить разделяемую память (shm) после сохранения скрипта путём аннулирования его контрольной суммы. Были попытки исправить пропуски через модифицируемые указатели, но была отклонена из-за сложности. Из-за этого решили удалить эту функцию.

Модуль Phar

Тип констант класса Phar теперь объявлен.

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

В функцию range() был внесён ряд изменений:

  • Теперь выбрасывается исключение TypeError, когда объекты (object), ресурсы (resource) или массивы (array) передаются в качестве граничных значений.
  • Теперь при передаче в параметр $step значения 0 выбрасывается подробнее описанное исключение ValueError.
  • Теперь выбрасывается исключение ValueError, когда в параметр $step передаются отрицательные значения для увеличения диапазонов.
  • Если в параметр $step передаётся число с плавающей точкой, которое может быть интерпретировано как целое число, то оно так и оценивается.
  • Теперь выбрасывается исключение ValueError, если любой аргумент представляет бесконечное число или нечисло (NAN).
  • Теперь вызвается ошибка уровня E_WARNING, если параметр $start или $end принимает значение пустой строки. Значение продолжает приводиться к значению 0.
  • Теперь вызвается ошибка уровня E_WARNING, если параметр $start или $end принимает нечисловую строку размером более одного байта.
  • Теперь вызвается ошибка уровня E_WARNING, если значение, переданное в параметр $start или $end, приводится к целому числу из-за того, что другое значение — число (например, range(5, 'z');).
  • Теперь при попытке сгенерировать диапазон символов вызвается ошибка уровня E_WARNING, если значение параметра $step — число с плавающей точкой, кроме случаев, когда оба входных значения — числовые строки (например, range('5', '9', 0.5); не вызовет предупреждения).
  • Теперь вместо приведения одного из значений к целому числу функция range() создаёт список символов, если одно из них — числовая строка (например, range('9', 'A');).
<?php

range('9', 'A');  // ["9", ":", ";", "<", "=", ">", "?", "@", "A"], начиная с PHP 8.3.0
range('9', 'A');  // [9, 8, 7, 6, 5, 4, 3, 2, 1, 0], до PHP 8.3.0

Теперь функция number_format() обрабатывает отрицательные значения $decimals и округляет значения $num до abs($decimals) знаков перед десятичной точкой. Раньше функция игнорировала отрицательные значения $decimals.

Флаги проверки ошибок в функции file() теперь перехватывает все недопустимые флаги. Константа FILE_APPEND раньше без предупреждения принималась.

SNMP

Тип констант класса SNMP теперь объявлен.

Нормативный английский оригинал из frozen baseline

Этот слой сохраняет полный договор, если перевод отстаёт. Источник: английский нормативный оригинал.

PHP Core

Programs that were very close to overflowing the call stack

Programs that were very close to overflowing the call stack may now throw an Error when using more than zend.max_allowed_stack_size-zend.reserved_stack_size bytes of stack (fiber.stack_size-zend.reserved_stack_size for fibers).

Executing proc_get_status() multiple times

Executing proc_get_status() multiple times will now always return the right value on POSIX systems. Previously, only the first call of the function returned the right value. Executing proc_close() after proc_get_status() will now also return the right exit code. Previously this would return -1. Internally, this works by caching the result on POSIX systems. If the previous behaviour is required, it is possible to check the "cached" key in the array returned by proc_get_status() to check whether the result was cached.

Zend Max Execution Timers

Zend Max Execution Timers is now enabled by default for ZTS builds on Linux.

Uses of traits with static properties

Uses of traits with static properties will now redeclare static properties inherited from the parent class. This will create a separate static property storage for the current class. This is analogous to adding the static property to the class directly without traits.

Assigning a negative index to an empty array

Assigning a negative index $n to an empty array will now make sure that the next index is $n+1 instead of 0.

Class constant visibility variance check

Class constant visibility variance is now correctly checked when inherited from interfaces.

WeakMap entries whose key maps to itself

WeakMap entries whose key maps to itself (possibly transitively) may now be removed during cycle collection if the key is not reachable except by iterating over the WeakMap (reachability via iteration is considered weak). Previously, such entries would never be automatically removed.

Date

The DateTime extension has introduced Date extension specific exceptions and errors under the DateError and DateException hierarchies, instead of warnings and generic exceptions. This improves error handling, at the expense of having to check for errors and exceptions.

DOM

Calling DOMChildNode::after(), DOMChildNode::before(), DOMChildNode::replaceWith() on a node that has no parent is now a no-op instead of a hierarchy exception, which is the behaviour demanded by the DOM specification.

Using the DOMParentNode and DOMChildNode methods without a document now works instead of throwing a DOM_HIERARCHY_REQUEST_ERRDOMException. This is in line with the behaviour demanded by the DOM specification.

Calling DOMDocument::createAttributeNS() without specifying a prefix would incorrectly create a default namespace, placing the element inside the namespace instead of the attribute. This bug is now fixed.

DOMDocument::createAttributeNS() would previously incorrectly throw a DOM_NAMESPACE_ERRNAMESPACE_ERRDOMException when the prefix was already used for a different URI. It now correctly chooses a different prefix when there's a prefix name conflict.

New methods and properties were added to some DOM classes. If a userland class inherits from these classes and declare a method or property with the same name, the declarations must be compatible. Otherwise, a typical compile error about incompatible declarations will be thrown. See the list of new features and new functions for a list of the newly implemented methods and properties.

FFI

C functions that have a return type of void now return null instead of returning the following object object(FFI\CData:void) { }

Opcache

The opcache.consistency_checks INI directive was removed. This feature was broken with the tracing JIT, as well as with inheritance cache, and has been disabled without a way to enable it since PHP 8.1.18 and PHP 8.2.5. Both the tracing JIT and inheritance cache may modify shm after the script has been persisted by invalidating its checksum. The attempted fix skipped over the modifiable pointers but was rejected due to complexity. For this reason, it was decided to remove the feature instead.

Phar

The type of Phar class constants are now declared.

Standard

The range() function has had various changes:

  • A TypeError is now thrown when passing objects, resources, or arrays as the boundary inputs.
  • A more descriptive ValueError is thrown when passing 0 for step.
  • A ValueError is now thrown when using a negative step for increasing ranges.
  • If step is a float that can be interpreted as an int, it is now done so.
  • A ValueError is now thrown if any argument is infinity or NAN.
  • An E_WARNING is now emitted if start or end is the empty string. The value continues to be cast to the value 0.
  • An E_WARNING is now emitted if start or end has more than one byte, only if it is a non-numeric string.
  • An E_WARNING is now emitted if start or end is cast to an integer because the other boundary input is a number. (e.g. range(5, 'z');).
  • An E_WARNING is now emitted if step is a float when trying to generate a range of characters, except if both boundary inputs are numeric strings (e.g. range('5', '9', 0.5); does not produce a warning).
  • range() now produce a list of characters if one of the boundary inputs is a string digit instead of casting the other input to int (e.g. range('9', 'A');).
<?php
range('9', 'A');  // ["9", ":", ";", "<", "=", ">", "?", "@", "A"], as of PHP 8.3.0
range('9', 'A');  // [9, 8, 7, 6, 5, 4, 3, 2, 1, 0], prior to PHP 8.3.0
?>

number_format() now handles negative decimals values by rounding num to abs($decimals) digits before the decimal point. Previously, negative decimals values were ignored.

The file() flags error check now catches all invalid flags. Notably FILE_APPEND was previously silently accepted.

SNMP

The type of SNMP class constants are now declared.

PHP 8.2 → 8.3: Устаревшие возможности

Устаревание — раннее предупреждение, а не немедленное удаление. На тестовом контуре включают E_ALL, собирают deprecation без подавления, выбирают замену и исправляют собственный код до следующей мажорной версии.

Полный официальный договор страницы

Ниже сохранён официальный русский текст и структура из зафиксированного архива PHP Manual. Отдельные ещё не переведённые страницы официального русского архива могут оставаться на английском.

Ядро PHP

Операторы Increment/Decrement

Передача оператору increment (++) пустых, нечисловых или не буквенно-числовых строк устарела. Притом инкрементирование нечисловых строк устарело мягко. Понятие «мягкое устаревание» означает, что диагностика уровня E_DEPRECATED выполняться не будет, но нужно отказаться от устаревших правил в новом коде. Вместо устаревшего способа инкрементирования необходимо вызывать новую функцию str_increment().

Использование оператора decrement (--) для пустых или нечисловых строк теперь неактуально.

Вызов функции get_class()/get_parent_class() без аргументов

Вызов функций get_class() и get_parent_class() без аргументов устарел.

DBA

Вызов функции dba_fetch() с параметром $dba в качестве третьего аргумента устарел.

FFI

Статический вызов метода FFI::cast(), FFI::new() и FFI::type() устарел.

Intl

Константа U_MULTIPLE_DECIMAL_SEP*E*RATORS устарела, вместо неё рекомендуется использовать константу U_MULTIPLE_DECIMAL_SEP*A*RATORS.

Константа NumberFormatter::TYPE_CURRENCY устарела.

LDAP

Вызов функции ldap_connect() с отдельными параметрами $hostname и $port устарел.

MBString

Передача отрицательного значения в параметр $width функции mb_strimwidth() устарела.

Phar

Вызов метода Phar::setStub() с типом resource и параметром $length устарел. Такие вызовы должны быть заменены на: $phar->setStub(stream_get_contents($resource));.

Random

Вариант константы MT_RAND_PHP Mt19937 устарел.

Reflection

Вызов метода ReflectionProperty::setValue() только с одним параметром устарел. Чтобы установить статические свойства, передайте null в качестве первого параметра.

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

Функция assert_options() устарела.

Константы ASSERT_ACTIVE, ASSERT_BAIL, ASSERT_CALLBACK, ASSERT_EXCEPTION и ASSERT_WARNING устарели.

INI-параметры assert.* устарели. Смотрите изменения в работе с INI-файлами для более подробной информации.

SQLite3

Работа с исключениями теперь предпочтительнее, предупреждения будут удалены в будущем. Вызов SQLite3::enableExceptions(false) в этой версии выдаст предупреждение об устаревании.

Zip

Константа ZipArchive::FL_RECOMPRESS устарела и будет удалена в будущей версии libzip.

Нормативный английский оригинал из frozen baseline

Этот слой сохраняет полный договор, если перевод отстаёт. Источник: английский нормативный оригинал.

PHP Core

Saner Increment/Decrement operators

Using the increment operator (++) on empty, non-numeric, or non-alphanumeric strings is now deprecated. Moreover, incrementing non-numeric strings is soft deprecated. That means no E_DEPRECATED diagnostic is emitted, but this feature should not be used when producing new code. The new str_increment() function should be used instead.

Using the decrement operator (--) on empty or non-numeric strings is now deprecated.

get_class()/get_parent_class() call without arguments

Calling get_class() and get_parent_class() without arguments is now deprecated.

DBA

Calling dba_fetch() with dba as the 3rd argument is now deprecated.

FFI

Calling FFI::cast(), FFI::new(), and FFI::type() statically is now deprecated.

Intl

The U_MULTIPLE_DECIMAL_SEP*E*RATORS constant had been deprecated, using the U_MULTIPLE_DECIMAL_SEP*A*RATORS constant instead is recommended.

The NumberFormatter::TYPE_CURRENCY constant has been deprecated.

LDAP

Calling ldap_connect() with separate hostname and port is deprecated.

MBString

Passing a negative width to mb_strimwidth() is now deprecated.

Phar

Calling Phar::setStub() with a resource and a length is now deprecated. Such calls should be replaced by: $phar->setStub(stream_get_contents($resource));

Random

The MT_RAND_PHP Mt19937 variant is deprecated.

Reflection

Calling ReflectionProperty::setValue() with only one parameter is deprecated. To set static properties, pass null as the first parameter.

Standard

The assert_options() function is now deprecated.

The ASSERT_ACTIVE, ASSERT_BAIL, ASSERT_CALLBACK, ASSERT_EXCEPTION, and ASSERT_WARNING constants have been deprecated.

The assert.* INI settings have been deprecated. See the Changes to INI File Handling page for further details.

SQLite3

Using exceptions is now preferred, warnings will be removed in the future. Calling SQLite3::enableExceptions(false) will trigger a deprecation warning in this version.

Zip

The ZipArchive::FL_RECOMPRESS constant is deprecated and will be removed in a future version of libzip.

PHP 8.2 → 8.3: Другие изменения

Сюда попадают изменения поведения, конфигурации и расширений, которые не образуют новую синтаксическую конструкцию. Их сверяют с фактически установленными модулями и рабочими сценариями проекта.

Полный официальный договор страницы — большой справочник, раскрывается по запросу

Ниже сохранён официальный русский текст и структура из зафиксированного архива PHP Manual. Отдельные ещё не переведённые страницы официального русского архива могут оставаться на английском.

Изменения в ядре

Класс FFI

Метод FFI::load() теперь разрешён в режиме предварительной загрузки, когда опция opcache.preload_user — это текущий пользователь системы. Ранее вызов метода FFI::load() не был возможен во время предзагрузки, если настройка директивы opcache.preload_user была установлена.

Менеджер процессов FPM

Проверка FPM CLI теперь завершается неудачей, если путь к сокету длиннее, чем поддерживает операционная система.

Модуль Opcache

В CLI и phpdbg SAPIs предварительная загрузка больше не требует настройки директивы opcache.preload_user при запуске от имени пользователя root. В других SAPIs эта директива нужна при запуске от имени пользователя root, потому что предзагрузка выполнялась до того, как SAPI переключится на непривилегированного пользователя.

Потоки

Блокировка функцией fread() при подключении к сокету возвращается немедленно, если есть любые буферизованные данные, вместо ожидания дополнительных данных.

Поток памяти больше не завершается сбоем, если смещение поиска превысило конечное значение. Вместо этого память будет увеличена при следующей записи, а данные между старым концом и смещением заполнятся нулевыми байтами, аналогично работе файлов.

Операции доступа функции stat() наподобие функции file_exists() и похожие теперь пользуются реальным путём вместо фактического пути потока. Это соответствует открытию потока.

Изменения в модулях SAPI

Командная строка (CLI)

Потоки STDOUT, STDERR и STDIN больше не закрываются при уничтожении ресурсов, что обычно случается при завершении работы CLI. Однако всё ещё можно явно закрыть эти потоки через функцию fclose() и похожие.

Изменённые функции

Ядро

В функцию gc_status() добавлено 8 следующих полей:

  • running => bool
  • protected => bool
  • full => bool
  • buffer_size => int
  • application_time => float: Полное время работы приложения в секундах (включая время, затраченное полем collector_time)
  • collector_time => float: Время в секундах, затраченное циклами сборки (включая время, затраченное полями destructor_time и free_time)
  • destructor_time => float: Время в секундах, затраченное деструкторами в течение цикла сборки
  • free_time => float: Время в секундах, затраченное на освобождение значений во время цикла сборки

Функция class_alias() теперь поддерживает создание псевдонимов внутреннего класса.

Настройка open_basedir с вызовом во время выполнения функции ini_set('open_basedir', ...); больше не принимает пути, содержащие родительскую директорию (..). Ранее запрещались только пути, начинающиеся с ... Это можно легко обойти, добавив ./ к пути.

Обработчики пользовательских исключений теперь перехватывают их во время завершения работы.

Результирующий HTML в функциях highlight_string() и highlight_file() был изменён. Пробел между внешними HTML-тегами удалены. Новые строки и пробелы больше не преобразовываются в HTML-сущности. Полный HTML теперь обёрнут тегом <pre>. Внешний тег <span> был слит с тегом <code>.

Модуль Calendar

Функция easter_date() теперь поддерживает годы с 1970 по 2 000 000 000 на 64-битных системах, ранее она поддерживала только годы в диапазоне 1970—2037.

Модуль Curl

Функция curl_getinfo() теперь поддерживает две новых константы: CURLINFO_CAPATH и CURLINFO_CAINFO. Если параметр option принимает значение null, будут представлены два следующих дополнительных ключа: capath и cainfo.

Модуль DOM

У метода DOMCharacterData::appendData() предопределённый тип возвращаемого значения изменился на true.

У методов DOMDocument::loadHTML(), DOMDocument::loadHTMLFile() и DOMDocument::loadXML() предварительный тип возвращаемого значения был изменён на bool. Раньше это было задокументировано как DOMDocument|bool, но начиная с PHP 8.0.0 объект класса DOMDocument не может быть возвращён, поскольку он больше не может быть вызван статически.

Модуль Gd

Сигнатура функции imagerotate() изменилась. Параметр $ignore_transparent был удалён, поскольку он игнорировался с версии PHP 5.5.0.

Модуль интернационализации Intl

Функция datefmt_set_timezone() (и её псевдоним — метод IntlDateformatter::setTimeZone()) теперь возвращают значение true при успешном выполнении, ранее они возвращали значение null.

Метод IntlBreakiterator::setText() теперь возвращает значение false при сбое, ранее он возвращал значение null. Теперь он возвращает значение true при успешном выполнении, ранее возвращалось значение null.

Метод IntlChar::enumCharNames() теперь возвращает логическое значение. Ранее он возвращал значение null при успешном выполнении и значение false при неудачном завершении.

Метод IntlDateFormatter::__construct() выбрасывает исключение U_ILLEGAL_ARGUMENT_ERROR при установке недопустимого языкового стандарта (локали).

Модуль MBString

Функции mb_strtolower() и mb_convert_case() соблюдают правила условного регистра для греческой буквы сигма (Σ → σ). В функции mb_convert_case() условный регистр применяется только для режимов MB_CASE_LOWER и MB_CASE_TITLE, но не для MB_CASE_LOWER_SIMPLE и MB_CASE_TITLE_SIMPLE.

Функция mb_decode_mimeheader() интерпретирует подчёркивание в QPrint-кодированной MIME-кодировке слов так, как требует стандарт RFC 2047; они преобразовываются в пробелы. Подчёркивания должны быть закодированы в «=5F» с таких MIME-кодированных словах.

В редких случаях функция mb_encode_mimeheader() будет применять кодировку передачи к своей входной строке, чтобы она могла передать её как необработанный ASCII в PHP 8.2.

Функция mb_encode_mimeheader() больше не сбрасывает NUL-байты при QPrint-кодировании входной строки. Ранее это иногда приводило к повреждению функцией mb_encode_mimeheader строк в ряде текстовых кодировок, особенно UTF-16 и UTF-32.

«Нестрогий» режим функции mb_detect_encoding() теперь ведёт себя как описано в документации. Ранее она возвращала значение false, если тот же байт (например, первый) входной строки был недопустимым во всех проверяемых кодировках. В общем смысле, она исключала предложенные кодировки из рассмотрения, если был обнаружен недопустимый байт, и если тот же входной байт исключил все оставшиеся кодировки, всё ещё находящиеся на рассмотрении, она могла вернуть значение false. С другой стороны, если все предложенные кроме одной кодировки были исключены из рассмотрения, она возвращала последнюю оставшуюся, без учёта того, сколько ошибок кодирования может встретиться позже в строке. Это отличается от поведения, описанного в документации, которое говорило: «Если параметр strict установлен в значение false, будет возвращена первая совпадающая кодировка».

Модуль mysqli

Функция mysqli_fetch_object() теперь выбрасывает исключение ValueError вместо исключения Exception, когда в параметр $constructor_args передан непустой аргумент, а в классе не определён конструктор.

Функция mysqli_poll() теперь выбрасывает исключение ValueError, когда не переданы ни аргументы параметра $read, ни аргументы параметра $error.

В функции mysqli_field_seek() и методе mysqli_result::field_seek() возвращаемый тип теперь определён как true вместо bool.

Программный интерфейс ODBC

Теперь для параметра $enable функция odbc_autocommit() принимает значение null. При передаче значения null функция будет вести себя так же, как и при передаче значения только для одного параметра, то есть — укажет, включена ли автофиксация или нет.

Модуль PGSQL

Функция pg_fetch_object() теперь выбрасывает исключение ValueError вместо исключения Exception, когда в параметр $constructor_args передаётся непустой аргумент, а в классе не определён конструктор.

Функция pg_insert() теперь выбрасывает исключение ValueError вместо ошибки уровня E_WARNING, когда указанная таблица недопустима.

Функции pg_insert() и pg_convert() выбрасывают исключения ValueError или TypeError вместо ошибки уровня E_WARNING, когда значение/тип поля правильно не совпадает с типом PostgreSQL.

Параметр $row функций pg_fetch_result(), pg_field_prtlen() и pg_field_is_null() теперь может принимать значение null.

Модуль Random

Изменены функции mt_srand() и srand(), чтобы не проверять количество аргументов для определения, надо ли использовать случайное начальное число. Передача значения null сгенерирует случайное начальное число, при передаче значения 0 оно и будет выбрано случайным числом. Работа функции теперь согласована с методом Random\Engine\Mt19937::__construct().

Класс Reflection

Возвращаемый тип метода ReflectionClass::getStaticProperties() больше не может принимать значение null.

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

Вызов ошибки уровня E_NOTICE в функции unserialize() был повышен до E_WARNING.

Функция unserialize() теперь выдаёт ошибку уровня E_WARNING, если входные данные содержат неиспользованные байты.

Функция array_pad() теперь ограничена только максимальным количеством элементов, которые может содержать массив. Раньше за один раз она могла добавить только 1 048 576 элементов.

Функция strtok() выдаёт ошибку уровня E_WARNING, если токен не предоставлен при запуске токенизации.

Функция password_hash() теперь будет связывать в цепочку базовое исключение Random\RandomException как исключение Exception свойства $previous исключения ValueError, когда генерация соли завершится неудачей.

Передаваемый в параметр $command функции proc_open() массив теперь должен содержать хотя бы один непустой элемент. Или будет выброшено исключение ValueError.

Функция proc_open() возвращает значение false, если переданный в параметр $command массив — это не допустимая команда, а объект ресурса, который выдаёт предупреждение позже. Это уже было в Windows, но теперь это также имеет место, если выбрана реализация posix_spawn (бо́льшая часть платформ Linux, BSD и MacOS). Всё ещё существуют старые платформы, на которых это поведение не изменено, поскольку posix_spawn на них не поддерживается.

Функции array_sum() и array_product() теперь предупреждают, когда значения в массиве не могут быть преобразованы в целое число/число с плавающей точкой. Раньше массивы и объекты игнорировались, тогда как все остальные значения приводились к целым числам (int). Больше того, объекты, определяющие числовое приведение (например, GMP), теперь приводятся, а не игнорируются.

Параметр $decimals функции number_format() теперь правильно обрабатывает отрицательные целые числа. Округление с отрицательным значением для параметра $decimals означает, что значение параметра $num округляется до установленных в параметре $decimals значащих цифр перед десятичной точкой. Ранее отрицательные значения параметра $decimals молча игнорировались и число округлялось до нуля десятичных знаков.

Новый параметр $before_needle был добавлен в функцию strrchr(). Он ведет себя так же, как его аналог в функциях strstr() или stristr().

Функции str_getcsv() и fgetcsv() теперь возвращают пустую строку вместо строки с одним нулевым байтом для последнего поля, которое содержит только незавершенное вложение.

Другие изменения в модулях

Ядро

Указание операторов инкремента/декремента (++/--) на логических значениях (bool) теперь выдаёт предупреждения. Это потому, что пока это не даёт эффекта, но в будущем будет вести себя как $bool += 1.

Указание оператора декремента (--) на значения null теперь выдаёт предупреждения. Это потому, что пока это не даёт эффекта, но в будущем будет вести себя как $null -= 1.

Внутренние объекты, которые реализуют приведение _IS_NUMBER, но не обработчик do_operator, который переопределяет сложение и вычитание, теперь можно увеличивать или уменьшать на единицу, как если бы выполнялись выражения $o += 1 или $o -= 1.

Модуль DOM

Механизм жизненного цикла модуля DOM был переработан так, чтобы неявно удалённые узлы по-прежнему можно было получить. Ранее это приводило к исключению.

Класс SQLite3

Класс SQLite3 теперь вместо исключения Exception выбрасывает исключение SQLite3Exception (расширяя класс исключения Exception).

Код ошибки класса SQLite теперь передаётся в коде ошибки исключения, а не включается в сообщение об ошибке.

Изменения обработки INI-файла

  • INI-директивы assert.* устарели для настроек конфигурации. Сюда входят следующие настройки INI:

    Если значение настройки равно значению по умолчанию, уведомления об устаревании не будет выдано. Вместо них нужно пользоваться INI-директивой zend.assertions.
  • zend.max_allowed_stack_size — это новая INI-директива, которая устанавливает максимальный размер стека. Возможные значения — это 0 (определяет максимальный размер стека процессов или потоков), -1 (без ограничений) или положительное целое число байтов. Значение по умолчанию — 0. Когда она не может определить максимальный размер стека процессов или потоков, будет выбрано известное системное значение по умолчанию. Установка чрезмерно большого значения даст тот же эффект, что и отключение ограничения размера стека. Максимальный размер стека для файберов устанавливают директивой fiber.stack_size. Выбрасывается ошибка Error когда стек вызовов процессов превышает установленный директивой zend.max_allowed_stack_size-zend.reserved_stack_size размер байтов, для предотвращения ошибок сегментации, вызванных переполнением стека, для упрощения процесса отладки. Размер стека увеличивается во время неконтролируемых рекурсий с участием внутренних функций, или магических методов __toString(), __clone(), __sleep(), __destruct(). Это не связано с переполнением буфера стека и не связано с безопасностью.

  • zend.reserved_stack_size — это новая INI-директива, которая устанавливает зарезервированный размер стека в байтах. Это значение вычитается из максимального размера стека в качестве буфера при проверке размера стека.

Производительность

Модуль DOM

При циклическом просмотре списка узлов в объекте DOMNodeList теперь работает кеширование. Поэтому запрос элементов по умолчанию больше не занимает квадратичное время.

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

Метод DOMChildNode::remove() теперь работает с производительностью O(1).

Standard

Проверка ошибок флагов в функции file() теперь примерно на 7 % быстрее.

Библиотека SPL

Класс RecursiveDirectoryIterator теперь выполняет меньше операций ввода-вывода при циклическом переборе каталога.

Нормативный английский оригинал из frozen baseline

Этот слой сохраняет полный договор, если перевод отстаёт. Источник: английский нормативный оригинал.

Core changes

FFI

FFI::load() is now allowed during preloading when opcache.preload_user is the current system user. Previously, calling FFI::load() was not possible during preloading if the opcache.preload_user directive was set.

FPM

FPM CLI test now fails if the socket path is longer than supported by the OS.

Opcache

In the CLI and phpdbg SAPIs, preloading does not require the opcache.preload_user directive to be set anymore when running as root. In other SAPIs, this directive is required when running as root because preloading is done before the SAPI switches to an unprivileged user.

Streams

Blocking fread() on a socket connection returns immediately if there are any buffered data instead of waiting for more data.

A memory stream no longer fails if the seek offset is past the end. Instead, the memory will be increased on the next write and the data between the old end and the offset is filled with zero bytes, similar to how files work.

stat() access operations like file_exists() and similar will now use real path instead of the actual stream path. This is consistent with stream opening.

Changes in SAPI Modules

CLI

The STDOUT, STDERR and STDIN streams are no longer closed on resource destruction which is mostly when the CLI finishes. It is however still possible to explicitly close those streams using fclose() and similar.

Changed Functions

Core

gc_status() has added the following 8 fields:

  • "running" => bool
  • "protected" => bool
  • "full" => bool
  • "buffer_size" => int
  • "application_time" => float: Total application time, in seconds (including collector_time)
  • "collector_time" => float: Time spent collecting cycles, in seconds (including destructor_time and free_time)
  • "destructor_time" => float: Time spent executing destructors during cycle collection, in seconds
  • "free_time" => float: Time spent freeing values during cycle collection, in seconds

class_alias() now supports creating an alias of an internal class.

Setting open_basedir at runtime using ini_set('open_basedir', ...); no longer accepts paths containing the parent directory (..). Previously, only paths starting with .. were disallowed. This could easily be circumvented by prepending ./ to the path.

User exception handlers now catch exceptions during shutdown.

The resultant HTML of highlight_string() and highlight_file() has changed. Whitespace between outer HTML tags is removed. Newlines and spaces are no longer converted to HTML entities. The whole HTML is now wrapped in a <pre> tag. The outer <span> tag has been merged with the <code> tag.

Calendar

easter_date() now supports years from 1970 to 2,000,000,000 on 64-bit systems, previously it only supported years in the range from 1970 to 2037.

Curl

curl_getinfo() now supports two new constants: CURLINFO_CAPATH and CURLINFO_CAINFO. If option is null, the following two additional keys are present: "capath" and "cainfo".

DOM

Changed DOMCharacterData::appendData() tentative return type to true.

DOMDocument::loadHTML(), DOMDocument::loadHTMLFile(), and DOMDocument::loadXML() now have a tentative return type of bool. Previously, this was documented as having a return type of DOMDocument|bool, but, as of PHP 8.0.0, DOMDocument cannot be returned as it is no longer statically callable.

Gd

The signature of imagerotate() has changed. The ignore_transparent parameter has been removed, as it was ignored since PHP 5.5.0.

Intl

datefmt_set_timezone() (and its alias IntlDateformatter::setTimeZone()) now returns true on success, previously null was returned.

IntlBreakiterator::setText() now returns false on failure, previously null was returned. It now returns true on success, previously null was returned.

IntlChar::enumCharNames() is now returning a boolean. Previously it returned null on success and false on failure.

IntlDateFormatter::__construct() throws an U_ILLEGAL_ARGUMENT_ERROR exception when an invalid locale had been set.

MBString

mb_strtolower() and mb_convert_case() implement conditional casing rules for the Greek letter sigma. For mb_convert_case(), conditional casing only applies to MB_CASE_LOWER and MB_CASE_TITLE modes, not to MB_CASE_LOWER_SIMPLE and MB_CASE_TITLE_SIMPLE.

mb_decode_mimeheader() interprets underscores in QPrint-encoded MIME encoded words as required by RFC 2047; they are converted to spaces. Underscores must be encoded as "=5F" in such MIME encoded words.

In rare cases, mb_encode_mimeheader() will transfer-encode its input string where it would pass it through as raw ASCII in PHP 8.2.

mb_encode_mimeheader() no longer drops NUL (zero) bytes when QPrint-encoding the input string. This previously caused strings in certain text encodings, especially UTF-16 and UTF-32, to be corrupted by mb_encode_mimeheader.

mb_detect_encoding()'s "non-strict" mode now behaves as described in the documentation. Previously, it would return false if the same byte (for example, the first byte) of the input string was invalid in all candidate encodings. More generally, it would eliminate candidate encodings from consideration when an invalid byte was seen, and if the same input byte eliminated all remaining encodings still under consideration, it would return false. On the other hand, if all candidate encodings but one were eliminated from consideration, it would return the last remaining one without regard for how many encoding errors might be encountered later in the string. This is different from the behavior described in the documentation, which says: "If strict is set to false, the closest matching encoding will be returned."

mysqli

mysqli_fetch_object() now raises a ValueError instead of an Exception when the constructor_args argument is non empty with the class not having a constructor.

mysqli_poll() now raises a ValueError when neither the read nor the error arguments are passed.

mysqli_field_seek() and mysqli_result::field_seek() now specify the return type as true instead of bool.

ODBC

odbc_autocommit() now accepts null for the enable parameter. Passing null has the same behaviour as passing only 1 parameter, namely indicating if the autocommit feature is enabled or not.

PGSQL

pg_fetch_object() now raises a ValueError instead of an Exception when the constructor_args argument is non empty with the class not having a constructor.

pg_insert() now raises a ValueError instead of a E_WARNING when the table specified is invalid.

pg_insert() and pg_convert() raises a ValueError or a TypeError instead of a E_WARNING when the value/type of a field does not match properly with a PostgreSQL's type.

The row parameter of pg_fetch_result(), pg_field_prtlen(), and pg_field_is_null() is now nullable.

Random

Changed mt_srand() and srand() to not check the number of arguments to determine whether a random seed should be used. Passing null will generate a random seed, 0 will use zero as the seed. The functions are now consistent with Random\Engine\Mt19937::__construct().

Reflection

Return type of ReflectionClass::getStaticProperties() is no longer nullable.

Standard

E_NOTICEs emitted by unserialize() have been promoted to E_WARNING.

unserialize() now emits a new E_WARNING if the input contains unconsumed bytes.

array_pad() is now only limited by the maximum number of elements an array can have. Before, it was only possible to add at most 1048576 elements at a time.

strtok() raises an E_WARNING in the case token is not provided when starting tokenization.

password_hash() will now chain the underlying Random\RandomException as the ValueError's previousException when salt generation fails.

If using an array as the command for proc_open(), it must now have at least one non empty element. Otherwise a ValueError is thrown.

proc_open() returns false if command array is invalid command instead of resource object that produces warning later. This was already the case for Windows but it is now also the case if a posix_spawn implementation is in use (most Linux, BSD and MacOS platforms). There are still some old platforms where this behavior is not changed as posix_spawn is not supported there.

array_sum() and array_product() now warn when values in the array cannot be converted to int/float. Previously arrays and objects where ignored whilst every other value was cast to int. Moreover, objects that define a numeric cast (e.g. GMP) are now casted instead of ignored.

The decimals of number_format() now properly handles negative integers. Rounding with a negative value for decimals means that num is rounded to decimals significant digits before the decimal point. Previously negative decimals were silently ignored and the number got rounded to zero decimal places.

A new before_needle argument has been added to strrchr(). It behaves like its counterpart in the strstr() or stristr() functions.

str_getcsv() and fgetcsv() now return an empty string instead of a string with a single null byte for the last field which only contains an unterminated enclosure.

Other Changes to Extensions

Core

Using the increment/decrement operators (++/--) on values of type bool now emit warnings. This is because it currently has no effect, but will behave like $bool += 1 in the future.

Using the decrement operator (--) on values of type null now emit warnings. This is because it currently has no effect, but will behave like $null -= 1 in the future.

Internal objects that implement an _IS_NUMBER cast but not a do_operator handler that overrides addition and subtraction now can be incremented and decrement as if one would do $o += 1 or $o -= 1

DOM

The DOM lifetime mechanism has been reworked such that implicitly removed nodes can still be fetched. Previously this resulted in an exception.

SQLite3

The SQLite3 class now throws SQLite3Exception (extends Exception) instead of Exception.

The SQLite error code is now passed in the exception error code instead of being included in the error message.

Changes to INI File Handling

  • The assert.* INI settings have been deprecated. This comprises the following INI settings:

    If the value of the setting is equal to the default value, no deprecation notice is emitted. The zend.assertions INI setting should be used instead.
  • zend.max_allowed_stack_size is a new INI directive to set the maximum allowed stack size. Possible values are 0 (detect the process or thread maximum stack size), -1 (no limit), or a positive number of bytes. The default is 0. When it is not possible to detect the process or thread maximum stack size, a known system default is used. Setting this value too high has the same effect as disabling the stack size limit. Fibers use fiber.stack_size as maximum allowed stack size. An Error is thrown when the process call stack exceeds zend.max_allowed_stack_size-zend.reserved_stack_size bytes, to prevent stack-overflow-induced segmentation faults, with the goal of making debugging easier. The stack size increases during uncontrolled recursions involving internal functions or the magic methods __toString(), __clone(), __sleep(), __destruct(). This is not related to stack buffer overflows, and is not a security feature.

  • zend.reserved_stack_size is a new INI directive to set the reserved stack size, in bytes. This is subtracted from the max allowed stack size, as a buffer, when checking the stack size.

Performance

DOM

Looping over a DOMNodeList now uses caching. Therefore requesting items no longer takes quadratic time by default.

Getting text content from nodes now avoids an allocation, resulting in a performance gain.

DOMChildNode::remove() now runs in O(1) performance.

Standard

The file() flags error check is now about 7% faster.

SPL

RecursiveDirectoryIterator now performs less I/O when looping over a directory.

PHP 8.2 → 8.3: Изменения поддержки Windows

Платформенные изменения проверяют в Windows-ветке CI: пути, кодировки, DLL, сигналы и сетевые детали нельзя надёжно подтвердить только Linux-тестом.

Полный официальный договор страницы

Ниже сохранён официальный русский текст и структура из зафиксированного архива PHP Manual. Отдельные ещё не переведённые страницы официального русского архива могут оставаться на английском.

Ядро

Минимальная поддерживаемая версия Windows увеличена до Windows 8 или Windows Server 2012.

Нормативный английский оригинал из frozen baseline

Этот слой сохраняет полный договор, если перевод отстаёт. Источник: английский нормативный оригинал.

Core

Minimum supported Windows version has been bumped to Windows 8 or Windows Server 2012.

Контроль перед переключением production

Все относящиеся к проекту несовместимости должны иметь воспроизводимый тест. Deprecation не подавляют: его устраняют или записывают владельца и срок. Новые функции применяют только после повышения минимальной версии. Затем повторяют smoke-тест в том же SAPI и на том же типе данных, что используется в production.

Источники и обсуждения

Код и руководство с собой

Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.

Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.

Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.