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

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

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

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

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

Миграции PHP 7.3–8.0: синтаксис, типы и новый договор ошибок

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

PHP 7.2 → 7.3

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

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

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

Миграция с PHP 7.2.x на PHP 7.3.x

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

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

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

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

Migrating from PHP 7.2.x to PHP 7.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.0.x, 7.1.x and 7.2.x.

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

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

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

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

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

Ядро PHP

Более гибкий синтаксис Heredoc и Nowdoc

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

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

Деструктурирование массива теперь поддерживает присвоение по ссылкам с помощью синтаксиса [&$a, [$b, &$c]] = $d. То же самое поддерживается и для list().

Оператор instanceof принимает литералы

Оператор instanceof теперь поддерживает литералы в качестве первого операнда, и в этом случае результат будет всегда false.

Исключение CompileError вместо некоторых ошибок компиляции

Добавлено новое исключение CompileError, которое наследуется от ParseError. Небольшое количество ошибок компиляции теперь будет выбрасывать CompileError вместо создания фатальной ошибки. В настоящее время это влияет только на ошибки компиляции, которые могут быть созданы token_get_all() в режиме TOKEN_PARSE, но в будущем может быть преобразовано больше ошибок.

В вызовах разрешена завершающая запятая

Завершающие запятые в вызовах функций и методов теперь разрешены.

Поддержка Argon2id

С аргументом --with-password-argon2[=dir] скрипта configure теперь поддерживаются оба хеша, как Argon2i, так и Argon2id, в функциях password_hash(), password_verify(), password_get_info() и password_needs_rehash(). Пароли могут быть хешированы и проверены, используя константу PASSWORD_ARGON2ID. Поддержка обоих алгоритмов Argon2i и Argon2id в функциях семейства password_*() теперь требует, чтобы PHP был скомпилирован с библиотекой libargon2 версии ≥ 20161029.

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

Для настройки логирования FPM были добавлены новые опции:

log_limit

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

log_buffering

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

decorate_workers_output

Этот вариант пула позволяет отключить отметку вывода (output decoration) для обработчиков, когда catch_workers_output включена.

Функции BC Math

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

Облегчённый протокол доступа к каталогам (LDAP)

Была добавлена полная поддержка LDAP Controls к функциям запросов LDAP и ldap_parse_result():

Функции мультибайтовых строк

Полная поддержка case-mapping и case-folding

Добавили поддержку полного сопоставления регистра символов (англ. case-mapping) и преобразования регистра из нижнего в верхний и наоборот (англ. case-folding). В отличие от простого сопоставления регистра, полное сопоставление регистра иногда изменяет длину строки. Пример:

<?php

mb_strtoupper("Straße");
// Выведет STRAßE в PHP 7.2
// Выведет STRASSE в PHP 7.3

?>
Различные режимы преобразования и сравнения регистра символов доступны в функции mb_convert_case(): Выполняет только безусловный, независимый от языка, полный процесс преобразования.

Операции, нечувствительные к регистру используют case-folding

Строковые операции без учёта регистра теперь используют case-folding вместо case-mapping регистра при сравнении. Это означает, что теперь больше символов будут считаться (без учёта регистра) равными.

MB_CASE_TITLE выполняет преобразование title-case

Функция mb_convert_case() с MB_CASE_TITLE теперь выполняет преобразование title-case в зависимости от свойств Unicode, основанных на Cased и CaseIgnorable. В частности, это также улучшает обработку кавычек и апострофов.

Поддержка Unicode 11

Таблицы данных мультибайтовых строк были обновлены до Юникода версии 11.

Поддержка больших строк

Функции мультибайтовых строк теперь корректно поддерживают строки размером более 2 Гб.

Улучшение производительности

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

Поддержка именованных фрагментов

Функции mb_ereg_* теперь поддерживают именованные фрагменты. Соответствующие функции, такие как mb_ereg(), теперь будут возвращать именованные фрагменты как с их номером группы, так и с их именем, аналогично PCRE:

<?php
mb_ereg('(?<word>\w+)', '国', $matches);
// => [0 => "国", 1 => "国", "word" => "国"];
?>
Кроме того, функция mb_ereg_replace() теперь поддерживает обозначения \k<> и \k'' для ссылки на именованные фрагменты в заменяющей строке:
<?php
mb_ereg_replace('\s*(?<word>\w+)\s*', "_\k<word>_\k'word'_", ' foo ');
// => "_foo_foo_"
?>
\k<> и \k'' также могут использоваться для нумерованных ссылок, которые также работают с номерами групп больше 9.

Readline

В функции readline_info() добавлена поддержка параметров completion_append_character и completion_suppress_append. Эти опции доступны, только если PHP скомпилирован с библиотекой libreadline (а не libedit).

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

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

PHP Core

More Flexible Heredoc and Nowdoc Syntax

The closing marker for doc strings is no longer required to be followed by a semicolon or newline. Additionally the closing marker may be indented, in which case the indentation will be stripped from all lines in the doc string.

Array Destructuring supports Reference Assignments

Array destructuring now supports reference assignments using the syntax [&$a, [$b, &$c]] = $d. The same is also supported for list().

Instanceof Operator accepts Literals

instanceof now allows literals as the first operand, in which case the result is always false.

CompileError Exception instead of some Compilation Errors

A new CompileError exception has been added, from which ParseError inherits. A small number of compilation errors will now throw a CompileError instead of generating a fatal error. Currently this only affects compilation errors that may be thrown by token_get_all() in TOKEN_PARSE mode, but more errors may be converted in the future.

Trailing Commas are allowed in Calls

Trailing commas in function and method calls are now allowed.

Argon2id Support

The --with-password-argon2[=dir] configure argument now provides support for both Argon2i and Argon2id hashes in the password_hash(), password_verify(), password_get_info(), and password_needs_rehash() functions. Passwords may be hashed and verified using the PASSWORD_ARGON2ID constant. Support for both Argon2i and Argon2id in the password_*() functions now requires PHP be linked against libargon2 reference library ≥ 20161029.

FastCGI Process Manager

New options have been added to customize the FPM logging:

log_limit

This global option can be used for setting the log limit for the logged line which allows to log messages longer than 1024 characters without wrapping. It also fixes various wrapping issues.

log_buffering

This global option allows an experimental logging without extra buffering.

decorate_workers_output

This pool option allows to disable the output decoration for workers output when catch_workers_output is enabled.

BC Math Functions

bcscale() can now also be used as getter to retrieve the current scale in use.

Lightweight Directory Access Protocol

Full support for LDAP Controls has been added to the LDAP querying functions and ldap_parse_result():

Multibyte String Functions

Full Case-Mapping and Case-Folding Support

Support for full case-mapping and case-folding has been added. Unlike simple case-mapping, full case-mapping may change the length of the string. For example:

<?php
mb_strtoupper("Straße");
// Produces STRAßE on PHP 7.2
// Produces STRASSE on PHP 7.3
?>
The different casing mapping and folding modes are available through mb_convert_case(): Only unconditional, language agnostic full case-mapping is performed.

Case-Insensitive String Operations use Case-Folding

Case-insensitive string operations now use case-folding instead of case- mapping during comparisons. This means that more characters will be considered (case insensitively) equal now.

MB_CASE_TITLE performs Title-Case Conversion

mb_convert_case() with MB_CASE_TITLE now performs title-case conversion based on the Cased and CaseIgnorable derived Unicode properties. In particular this also improves handling of quotes and apostrophes.

Unicode 11 Support

The Multibyte String data tables have been updated for Unicode 11.

Long String Support

The Multibyte String Functions now correctly support strings larger than 2GB.

Performance Improvements

Performance of the Multibyte String extension has been significantly improved across the board. The largest improvements are in case conversion functions.

Named Captures Support

The mb_ereg_* functions now support named captures. Matching functions like mb_ereg() will now return named captures both using their group number and their name, similar to PCRE:

<?php
mb_ereg('(?<word>\w+)', '国', $matches);
// => [0 => "国", 1 => "国", "word" => "国"];
?>
Additionally, mb_ereg_replace() now supports the \k<> and \k'' notations to reference named captures in the replacement string:
<?php
mb_ereg_replace('\s*(?<word>\w+)\s*', "_\k<word>_\k'word'_", ' foo ');
// => "_foo_foo_"
?>
\k<> and \k'' can also be used for numbered references, which also works with group numbers greater than 9.

Readline

Support for the completion_append_character and completion_suppress_append options has been added to readline_info(). These options are only available if PHP is linked against libreadline (rather than libedit).

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

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

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

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

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

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

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

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

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

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

Ядро PHP

Библиотека Client URL (cURL)

Фильтрация данных

Объектная нотация JavaScript (JSON)

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

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

Client URL Library

JavaScript Object Notation

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

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

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

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

Ядро PHP

Интерпретация закрывающего идентификатора Heredoc/Nowdoc

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

<?php

$str = <<<FOO
abcdefg
   FOO
FOO;

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

Генерирование предупреждения в continue, используемом в switch

Выражения continue, используемые в структурах управления потока switch теперь будет выдавать предупреждение. В PHP такие выражения continue эквиваленты break, в то время, как в других языках они ведут себя как continue 2.

<?php

while ($foo) {
    switch ($bar) {
      case "baz":
         continue;
         // Предупреждение: "continue" эквивалентен
         //          "break". Возможно, вы имели в виду "continue 2"?
   }
}

?>

Строгая интерпретация целых строковых ключей на ArrayAccess

Доступ к массиву типа $obj["123"], где $obj реализует интерфейс ArrayAccess, а "123" — целочисленный строковый литерал, больше не приведёт к неявному преобразованию в целое число, т. е. $obj->offsetGet("123") вместо $obj->offsetGet(123). Это соответствует существующему поведению для нелитеральных значений. Поведение массивов никак не изменилось, они продолжают неявно преобразовывать целые строковые ключи в целые числа.

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

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

<?php

class Test
{
    public static $x = 0;
}

class Test2 extends Test { }

Test2::$x = &$x;
$x = 1;

var_dump(Test::$x, Test2::$x);
// Раньше:  int(0), int(1)
// Теперь: int(1), int(1)

?>

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

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

<?php

$arr = [1];
$ref =& $arr[0];
var_dump($arr[0] + ($arr[0] = 2));
// Раньше: int(4), Теперь: int(3)

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

Распаковка аргумента со значением Traversable с нечисловыми ключами больше не поддерживается

Распаковка аргументов перестала работать со значением Traversable с нечисловыми ключами. Следующий код работает в PHP 5.6-7.2 по ошибке.

<?php

function foo(...$args)
{
    var_dump($args);
}

function gen()
{
    yield 1.23 => 123;
}

foo(...gen());

?>

Разное

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

Поддержка BeOS была прекращена.

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

Исключение TypeError теперь указывает на правильные типы int и bool вместо integer и boolean, соответственно.

Про неопределённые переменные, переданные в compact(), теперь будет сообщено уведомлением.

Функция getimagesize() и связанные с ней функции теперь сообщают mime-типы изображений BMP как image/bmp вместо image/x-ms-bmp, поскольку первый зарегистрирован в IANA (смотрите » RFC 7903).

Функция stream_socket_get_name() теперь возвращает адреса IPv6, заключённые в квадратные скобки. Например, будет возвращена строка "[::1]:1337" вместо "::1:1337".

Произвольной точности математика BCMath

Все предупреждения, выброшенные функциями BCMath, теперь используют обработку ошибок PHP. Раньше некоторые предупреждения были непосредственно отправлены в поток stderr.

Функции bcmul() и bcpow() теперь возвращают числа с запрошенным масштабом. Раньше возвращаемые числа могли опускать завершающие десятичные нули.

IMAP, POP3 и NNTP

Логины rsh/ssh по умолчанию отключены. Используйте imap.enable_insecure_rsh, если вы хотите включить их. Обратите внимание, что библиотека IMAP не фильтрует имена почтовых ящиков перед передачей их команде rsh/ssh, таким образом, передача ненадёжных данных этой функции с включённым rsh/ssh небезопасна.

Мультибайтовые строки

Из-за дополнительной поддержки именованных фрагментов, паттерны mb_ereg_*() с использованием именованных фрагментов будут вести себя по-разному. В частности, именованные фрагменты будут частью совпадений, а функция mb_ereg_replace() будет интерпретировать дополнительный синтаксис. Смотрите Именованные фрагменты для получения дополнительной информации.

Улучшенный модуль MySQL

Подготовленные запросы теперь правильно указывают на дробные секунды для столбцов DATETIME, TIME и TIMESTAMP с указателем десятичных знаков (например, TIMESTAMP(6) при использовании микросекунд). Раньше часть дробных секунд была просто опущена из возвращаемых значений.

Функции MySQL (PDO_MYSQL)

Подготовленные запросы теперь правильно указывают на дробные секунды для столбцов DATETIME, TIME и TIMESTAMP со спецификатором десятичных знаков (например, TIMESTAMP(6) при использовании микросекунд). Ранее, дробная часть секунд была просто опущена из возвращаемых значений. Обратите внимание, что это влияет только на использование PDO_MYSQL с отключённой эмуляцией подготовленных запросов (например, с использованием нативной функциональности). Запросы, использующие соединения, у которых задана опция PDO::ATTR_EMULATE_PREPARES=true (значение по умолчанию), не были затронуты данным исправлением ошибки и уже получали корректные значения долей секунды от движка.

Reflection

Экспорт объектов Reflection в строку теперь использует int) и bool) вместо integer and boolean, соответственно.

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

Если автозагрузчик SPL выбрасывает исключение, последующие автозагрузчики не будут выполняться. Раньше все автозагрузчики выполнялись, а исключения объединялись в цепочку вызовов.

SimpleXML

Математические операции, которые включают объекты SimpleXML, теперь будут обрабатывать текст как целое число (int) или число с плавающей точкой (float), в зависимости от того, что является более подходящим. Раньше значения обрабатывались как целые числа (integer) без каких-либо условий.

Входящие Cookies

Начиная с PHP 7.3.23 имена входящих cookie больше не декодируются из URL-закодированной строки из соображений безопасности.

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

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

PHP Core

Heredoc/Nowdoc Ending Label Interpretation

Due to the introduction of flexible heredoc/nowdoc syntax, doc strings that contain the ending label inside their body may cause syntax errors or change in interpretation. For example in:

<?php
$str = <<<FOO
abcdefg
   FOO
FOO;
?>
the indented occurrence of FOO did not previously have any special meaning. Now it will be interpreted as the end of the heredoc string and the following FOO; will cause a syntax error. This issue can always be resolved by choosing an ending label that does not occur within the contents of the string.

Continue Targeting Switch issues Warning

continue statements targeting switch control flow structures will now generate a warning. In PHP such continue statements are equivalent to break, while they behave as continue 2 in other languages.

<?php
while ($foo) {
    switch ($bar) {
      case "baz":
         continue;
         // Warning: "continue" targeting switch is equivalent to
         //          "break". Did you mean to use "continue 2"?
   }
}
?>

Strict Interpretation of Integer String Keys on ArrayAccess

Array accesses of type $obj["123"], where $obj implements ArrayAccess and "123" is an integer string literal will no longer result in an implicit conversion to integer, i.e., $obj->offsetGet("123") will be called instead of $obj->offsetGet(123). This matches existing behavior for non-literals. The behavior of arrays is not affected in any way, they continue to implicitly convert integral string keys to integers.

Static Properties no longer separated by Reference Assignment

In PHP, static properties are shared between inheriting classes, unless the static property is explicitly overridden in a child class. However, due to an implementation artifact it was possible to separate the static properties by assigning a reference. This loophole has been fixed.

<?php
class Test {
    public static $x = 0;
}
class Test2 extends Test { }

Test2::$x = &$x;
$x = 1;

var_dump(Test::$x, Test2::$x);
// Previously: int(0), int(1)
// Now:        int(1), int(1)
?>

References returned by Array and Property Accesses are immediately unwrapped

References returned by array and property accesses are now unwrapped as part of the access. This means that it is no longer possible to modify the reference between the access and the use of the accessed value:

<?php
$arr = [1];
$ref =& $arr[0];
var_dump($arr[0] + ($arr[0] = 2));
// Previously: int(4), Now: int(3)
?>
This makes the behavior of references and non-references consistent. Please note that reading and writing a value inside a single expression remains undefined behavior and may change again in the future.

Argument Unpacking of Traversables with non-Integer Keys no longer supported

Argument unpacking stopped working with Traversables with non-integer keys. The following code worked in PHP 5.6-7.2 by accident.

<?php
function foo(...$args) {
    var_dump($args);
}
function gen() {
    yield 1.23 => 123;
}
foo(...gen());
?>

Miscellaneous

The ext_skel utility has been completely redesigned with new options and some old options removed. This is now written in PHP and has no external dependencies.

Support for BeOS has been dropped.

Exceptions thrown due to automatic conversion of warnings into exceptions in EH_THROW mode (e.g. some DateTime exceptions) no longer populate error_get_last() state. As such, they now work the same way as manually thrown exceptions.

TypeError now reports wrong types as int and bool instead of integer and boolean, respectively.

Undefined variables passed to compact() will now be reported as a notice.

getimagesize() and related functions now report the mime type of BMP images as image/bmp instead of image/x-ms-bmp, since the former has been registered with the IANA (see » RFC 7903).

stream_socket_get_name() will now return IPv6 addresses wrapped in brackets. For example "[::1]:1337" will be returned instead of "::1:1337".

BCMath Arbitrary Precision Mathematics

All warnings thrown by BCMath functions are now using PHP's error handling. Formerly some warnings have directly been written to stderr.

bcmul() and bcpow() now return numbers with the requested scale. Formerly, the returned numbers may have omitted trailing decimal zeroes.

IMAP, POP3 and NNTP

rsh/ssh logins are disabled by default. Use imap.enable_insecure_rsh if you want to enable them. Note that the IMAP library does not filter mailbox names before passing them to the rsh/ssh command, thus passing untrusted data to this function with rsh/ssh enabled is insecure.

Multibyte String

Due to added support for named captures, mb_ereg_*() patterns using named captures will behave differently. In particular named captures will be part of matches and mb_ereg_replace() will interpret additional syntax. See Named Captures for more information.

MySQL Improved Extension

Prepared statements now properly report the fractional seconds for DATETIME, TIME and TIMESTAMP columns with decimals specifier (e.g. TIMESTAMP(6) when using microseconds). Formerly, the fractional seconds part was simply omitted from the returned values.

MySQL Functions (PDO_MYSQL)

Prepared statements now properly report the fractional seconds for DATETIME, TIME and TIMESTAMP columns with decimals specifier (e.g. TIMESTAMP(6) when using microseconds). Formerly, the fractional seconds part was simply omitted from the returned values. Please note that this only affects the usage of PDO_MYSQL with emulated prepares turned off (e.g. using the native preparation functionality). Statements using connections having PDO::ATTR_EMULATE_PREPARES=true (which is the default) were not affected by the bug fixed and have already been getting the proper fractional seconds values from the engine.

Reflection

Reflection export to string now uses int and bool instead of integer and boolean, respectively.

Standard PHP Library (SPL)

If an SPL autoloader throws an exception, following autoloaders will not be executed. Previously all autoloaders were executed and exceptions were chained.

SimpleXML

Mathematic operations involving SimpleXML objects will now treat the text as an int or float, whichever is more appropriate. Previously values were treated as ints unconditionally.

Incoming Cookies

As of PHP 7.3.23, the names of incoming cookies are no longer url-decoded for security reasons.

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

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

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

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

Ядро PHP

Нечувствительные к регистру константы

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

Использование assert() внутри пространств имён

Объявление функции с именем assert() внутри пространства имён объявлено устаревшим. Функция assert() подвержена специальной обработке движком, что может привести к несогласованному поведению при определении функции в пространстве имён с тем же именем.

Поиск строк для нестрочного параметра needle

Передача нестрокового параметра needle в строковые функции поиска объявлено устаревшим. В будущем данный параметр будет интерпретироваться как строка, а не как точка кода ASCII. В зависимости от предполагаемого поведения необходимо либо явно привести параметр к строке, либо выполнить явный вызов chr(). Затронуты следующие функции:

Изменения в удалении тегов

Функция fgetss() и фильтр потока string.strip_tags объявлены устаревшим. Это также влияет на метод SplFileObject::fgetss() и на функцию gzgetss().

Фильтрация данных

Явное использование констант FILTER_FLAG_SCHEME_REQUIRED и FILTER_FLAG_HOST_REQUIRED теперь объявлено устаревшим; так или иначе, они подразумевают использование FILTER_VALIDATE_URL.

Обработка изображений и GD

Функция image2wbmp() объявлена устаревшей.

Функции интернационализации

Использование Normalizer::NONE вызывает предупреждение об устаревшем поведении, если PHP не скомпилирован с ICU версии ≥ 56.

Мультибайтовые строки

Следующие недокументированные псевдонимы mbereg_*() объявлены устаревшими. Вместо этого используйте соответствующие варианты mb_ereg_*().

  • mbregex_encoding()

  • mbereg()

  • mberegi()

  • mbereg_replace()

  • mberegi_replace()

  • mbsplit()

  • mbereg_match()

  • mbereg_search()

  • mbereg_search_pos()

  • mbereg_search_regs()

  • mbereg_search_init()

  • mbereg_search_getregs()

  • mbereg_search_getpos()

  • mbereg_search_setpos()

Функции ODBC и DB2 (PDO_ODBC)

Настройка ini-файла pdo_odbc.db2_instance_name официально объявлено устаревшим. Опция устарела в документации, начиная с PHP 5.1.1.

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

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

PHP Core

Case-Insensitive Constants

The declaration of case-insensitive constants has been deprecated. Passing true as the third argument to define() will now generate a deprecation warning. The use of case-insensitive constants with a case that differs from the declaration is also deprecated.

Namespaced assert()

Declaring a function called assert() inside a namespace is deprecated. The assert() function is subject to special handling by the engine, which may lead to inconsistent behavior when defining a namespaced function with the same name.

Searching Strings for non-string Needle

Passing a non-string needle to string search functions is deprecated. In the future the needle will be interpreted as a string instead of an ASCII codepoint. Depending on the intended behavior, you should either explicitly cast the needle to string or perform an explicit call to chr(). The following functions are affected:

Strip-Tags Streaming

The fgetss() function and the string.strip_tags stream filter have been deprecated. This also affects the SplFileObject::fgetss() method and gzgetss() function.

Data Filtering

The explicit usage of the constants FILTER_FLAG_SCHEME_REQUIRED and FILTER_FLAG_HOST_REQUIRED is now deprecated; both are implied for FILTER_VALIDATE_URL anyway.

Image Processing and GD

image2wbmp() has been deprecated.

Internationalization Functions

Usage of the Normalizer::NONE form throws a deprecation warning, if PHP is linked with ICU ≥ 56.

Multibyte String

The following undocumented mbereg_*() aliases have been deprecated. Use the corresponding mb_ereg_*() variants instead.

  • mbregex_encoding()

  • mbereg()

  • mberegi()

  • mbereg_replace()

  • mberegi_replace()

  • mbsplit()

  • mbereg_match()

  • mbereg_search()

  • mbereg_search_pos()

  • mbereg_search_regs()

  • mbereg_search_init()

  • mbereg_search_getregs()

  • mbereg_search_getpos()

  • mbereg_search_setpos()

ODBC and DB2 Functions (PDO_ODBC)

The pdo_odbc.db2_instance_name ini setting has been formally deprecated. It is deprecated in the documentation as of PHP 5.1.1.

PHP 7.2 → 7.3: Другие изменения

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

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

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

Ядро PHP

Функция set(raw)cookie принимает аргумент $option

Функции setcookie() и setrawcookie() теперь также поддерживают следующее объявление (сигнатуру):

functionsetcookie(string$name, string$value = "", array$options = []): bool
где $options - ассоциативный массив, который может иметь любой из ключей "expires", "path", "domain", "secure", "httponly" и "samesite".

Новые ini-директивы syslog

Следующие ini-директивы добавлены для настройки логирования, если для опции error_log установлено значение syslog:

syslog.facility

Указывает тип программы, регистрирующей сообщение.

syslog.filter

Задаёт тип фильтра для фильтрации сообщений с поддерживаемыми типами фильтров - all, no-ctrl и ascii. Начиная с PHP 7.3.8, также доступен тип raw, восстанавливающий поведение системного журнала в предыдущих версиях PHP. Этот фильтр также повлияет на вызовы syslog().

syslog.ident

Задаёт строку ident, добавляемую перед каждым сообщением.

Сборщик мусора

Улучшен сбор циклических ссылок, что может привести к значительным улучшениям производительности.

Разное

Функция var_export() теперь экспортирует объекты stdClass в качестве массива, приведённых к объекту ((object) array( ... )), вместо использования несуществующего метода stdClass::__setState().

Функция debug_zval_dump() изменена для отображения рекурсивных массивов и объектов так же, как и var_dump(). Теперь она не отображает их дважды.

Функции array_push() и array_unshift() теперь также могут быть вызваны с одним аргументом, что особенно удобно в сочетании с оператором распространения.

Интерактивный отладчик PHP

Удалены неиспользуемые константы PHPDBG_FILE, PHPDBG_METHOD, PHPDBG_LINENO и PHPDBG_FUNC.

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

Теперь также доступна функция getallheaders().

Библиотека Client URL (cURL)

Теперь требуется библиотека libcurl версии ≥ 7.15.5.

Фильтрация данных

FILTER_VALIDATE_FLOAT теперь также поддерживает параметр thousand, который определяет набор разрешённых символов-разделителей для тысяч. Значение по умолчанию ("',.") полностью обратно совместимо с предыдущими версиями PHP.

FILTER_SANITIZE_ADD_SLASHES был добавлен в качестве псевдонима фильтра magic_quotes (FILTER_SANITIZE_MAGIC_QUOTES). Фильтр magic_quotes подлежит удалению в будущих версиях PHP.

FTP

Режим по умолчанию изменён на binary.

Функции интернационализации

Константа Normalizer::NONE объявлена устаревшей, когда PHP скомпилирован с ICU версии ≥ 56.

Введена константа Normalizer::FORM_KC_CF в качестве аргумента Normalizer::normalize() для нормализации NFKC_Casefold; доступна, когда есть ICU ≥ 56.

Объектная нотация JavaScript (JSON)

Добавлен новый флаг JSON_THROW_ON_ERROR, который можно использовать с json_decode() или json_encode() и заставляет эти функции выбрасывать новое исключение JsonException в случае возникновения ошибки, вместо того, чтобы устанавливать глобальное состояние ошибки, которое извлекается с помощью json_last_error() и json_last_error_msg(). JSON_PARTIAL_OUTPUT_ON_ERROR имеет приоритет над JSON_THROW_ON_ERROR.

Мультибайтовые строки

Конфигурационная опция --with-libmbfl больше недоступна.

ODBC (Unified)

Поддержка ODBCRouter и Birdstep, включая ini-директиву birdstep.max_links была удалена.

OPcache

Удалена ini-директива opcache.inherited_hack. Это значение уже игнорировалось с PHP 5.3.0.

OpenSSL

Добавлены опции потока ssl min_proto_version и max_proto_version, а также соответствующие с ними константы для возможных значений протокола TLS.

Регулярные выражения (совместимые с Perl)

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

Функция preg_quote() теперь также экранирует символ '#'.

Microsoft SQL Server и функции Sybase (PDO_DBLIB)

Добавлен атрибут PDO::DBLIB_ATTR_SKIP_EMPTY_ROWSETS для автоматического пропуска пустых наборов строк.

Добавлен атрибут PDO::DBLIB_ATTR_TDS_VERSION который представляет версию TDS.

Столбцы DATETIME2 теперь обрабатываются как столбцы DATETIME.

Функции SQLite (PDO_SQLITE)

Базы данных SQLite3 теперь можно открыть в режиме только для чтения, установив новый атрибут PDO::SQLITE_ATTR_OPEN_FLAGS на значение PDO::SQLITE_OPEN_READONLY.

Обработка сессий

Функция session_set_cookie_params() теперь также поддерживает следующее объявление (сигнатуру):

где $options - ассоциативный массив, который может иметь любой из ключей "lifetime", "path", "domain", "secure", "httponly" и "samesite". Соответственно, возвращаемое значение session_get_cookie_params() теперь также имеет элемент с ключом "samesite". Кроме того, новая ini-опция session.cookie_samesite для установки по умолчанию директивы SameSite для cookies. По умолчанию используется значение "" (пустая строка), поэтому директива SameSite не задана. Может быть установлена на значение "Lax" или "Strict", которое устанавливает соответствующее значение директиве SameSite.

Tidy

Сборка вместе » tidyp теперь также поддерживается прозрачно. Поскольку tidyp не предлагает API для получения даты релиза, tidy_get_release() и tidy::getRelease() возвращает значение 'unknown' в этом случае.

XML-парсер

Возвращаемое значение callback-функции xml_set_external_entity_ref_handler() больше не игнорируется, если модуль был собран с библиотекой libxml. Ранее возвращаемое значение игнорировалось, а парсинг никогда не прекращался.

Zip

Сборка с использованием libzip, входящего в PHP, не рекомендуется, но всё же возможна путём добавления --without-libzip в конфигурацию.

Сжатие Zlib

Добавлен параметр контекста zlib/level для обёртки compress.zlib, чтобы облегчить установку желаемого уровня сжатия.

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

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

PHP Core

Set(raw)cookie accepts $option Argument

setcookie() and setrawcookie() now also support the following signature:

functionsetcookie(string$name, string$value = "", array$options = []): bool
where $options is an associative array which may have any of the keys "expires", "path", "domain", "secure", "httponly" and "samesite".

New Syslog ini Directives

The following ini Directives have been added to customize logging, if error_log is set to syslog:

syslog.facility

Specifies what type of program is logging the message.

syslog.filter

Specifies the filter type to filter the logged messages, with the supported filter types - all, no-ctrl and ascii. Starting with PHP 7.3.8, raw is also available, restoring the way syslog behaved in previous PHP versions. This filter will also affect calls to syslog().

syslog.ident

Specifies the ident string which is prepended to every message.

Garbage Collection

The cyclic GC has been enhanced, which may result in considerable performance improvements.

Miscellaneous

var_export() now exports stdClass objects as an array cast to an object ((object) array( ... )), rather than using the nonexistent method stdClass::__setState().

debug_zval_dump() was changed to display recursive arrays and objects in the same way as var_dump(). Now, it doesn't display them twice.

array_push() and array_unshift() can now also be called with a single argument, which is particularly convenient wrt. the spread operator.

Interactive PHP Debugger

The unused constants PHPDBG_FILE, PHPDBG_METHOD, PHPDBG_LINENO and PHPDBG_FUNC have been removed.

FastCGI Process Manager

The getallheaders() function is now also available.

Client URL Library

libcurl ≥ 7.15.5 is now required.

Data Filtering

FILTER_VALIDATE_FLOAT now also supports a thousand option, which defines the set of allowed thousand separator chars. The default ("',.") is fully backward compatible with former PHP versions.

FILTER_SANITIZE_ADD_SLASHES has been added as an alias of the magic_quotes filter (FILTER_SANITIZE_MAGIC_QUOTES). The magic_quotes filter is subject to removal in future versions of PHP.

FTP

The default transfer mode has been changed to binary.

Internationalization Functions

Normalizer::NONE is deprecated, when PHP is linked with ICU ≥ 56.

Introduced Normalizer::FORM_KC_CF as Normalizer::normalize() argument for NFKC_Casefold normalization; available when linked with ICU ≥ 56.

JavaScript Object Notation

A new flag has been added, JSON_THROW_ON_ERROR, which can be used with json_decode() or json_encode() and causes these functions to throw the new JsonException upon an error, instead of setting the global error state that is retrieved with json_last_error() and json_last_error_msg(). JSON_PARTIAL_OUTPUT_ON_ERROR takes precedence over JSON_THROW_ON_ERROR.

Multibyte String

The configuration option --with-libmbfl is no longer available.

ODBC (Unified)

Support for ODBCRouter and Birdstep including the birdstep.max_links ini directive has been removed.

OPcache

The opcache.inherited_hack ini directive has been removed. The value has already been ignored since PHP 5.3.0.

OpenSSL

The min_proto_version and max_proto_version ssl stream options as well as related constants for possible TLS protocol values have been added.

Regular Expressions (Perl-Compatible)

The PCRE extension has been upgraded to PCRE2, which may cause minor behavioral changes (for instance, character ranges in classes are now more strictly interpreted), and augments the existing regular expression syntax.

preg_quote() now also escapes the '#' character.

Microsoft SQL Server and Sybase Functions (PDO_DBLIB)

The attribute PDO::DBLIB_ATTR_SKIP_EMPTY_ROWSETS to enable automatic skipping of empty rowsets has been added.

The PDO::DBLIB_ATTR_TDS_VERSION attribute which exposes the TDS version has been added.

DATETIME2 columns are now treated like DATETIME columns.

SQLite Functions (PDO_SQLITE)

SQLite3 databases can now be opened in read-only mode by setting the new PDO::SQLITE_ATTR_OPEN_FLAGS attribute to PDO::SQLITE_OPEN_READONLY.

Session Handling

session_set_cookie_params() now also supports the following signature:

where $options is an associative array which may have any of the keys "lifetime", "path", "domain", "secure", "httponly" and "samesite". Accordingly, the return value of session_get_cookie_params() now also has an element with the key "samesite". Furthermore, the new session.cookie_samesite ini option to set the default of the SameSite directive for cookies has been added. It defaults to "" (empty string), so no SameSite directive is set. Can be set to "Lax" or "Strict", which sets the respective SameSite directive.

Tidy

Building against » tidyp is now also supported transparently. Since tidyp offers no API to get the release date, tidy_get_release() and tidy::getRelease() return 'unknown' in this case.

XML Parser

The return value of the xml_set_external_entity_ref_handler() callback is no longer ignored if the extension has been built against libxml. Formerly, the return value has been ignored, and parsing did never stop.

Zip

Building against the bundled libzip is discouraged, but still possible by adding --without-libzip to the configuration.

Zlib Compression

The zlib/level context option for the compress.zlib wrapper to facilitate setting the desired compression level has been added.

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

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

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

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

Ядро PHP

Удаление файлов, соответствующих POSIX

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

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

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

PHP Core

More POSIX Conforming File Deletion

File descriptors are opened in shared read/write/delete mode by default. This effectively maps the POSIX semantics and allows to delete files with handles in use. It is not 100% same, some platform differences still persist. After the deletion, the filename entry is blocked, until all the opened handles to it are closed.

PHP 7.3 → 7.4

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

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

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

Миграция с PHP 7.3.x на PHP 7.4.x

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

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

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

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

Migrating from PHP 7.3.x to PHP 7.4.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.0.x, 7.1.x, 7.2.x and 7.3.x.

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

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

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

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

Ядро PHP

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

Свойства класса теперь поддерживают объявления типов.

<?php

class User
{
    public int $id;
    public string $name;
}
Приведённый пример показывает, что свойству $user->id получится присвоить только значения с типом int, тогда как свойству $user->name — только значения с типом string.

Стрелочные функции

Стрелочные функции — сокращённая запись для определения функций с неявной привязкой родительской области видимости по значению.

<?php

$factor = 10;
$nums = array_map(fn ($n) => $n * $factor, [1, 2, 3, 4]);
// $nums = array(10, 20, 30, 40);

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

Следующий код теперь будет работать:

<?php

class A {}
class B extends A {}

class Producer
{
    public function method(): A {}
}

class ChildProducer extends Producer
{
    public function method(): B {}
}
Полная поддержка вариантности доступна только при автозагрузке классов. Нельзя ссылаться на типы циклически внутри одного файла, поскольку при ссылке на класс, который пока недоступен, возникает фатальная ошибка.
<?php

/**
 * Класс удовлетворяет принципу подстановки Б. Ли́сков (англ. Liskov Substitution Principle, LSP),
 * поскольку класс C принадлежит подтипу A,
 * но при объявлении класса B класс C ещё недоступен
 */
class A
{
    public function method(): A {}
}

class B extends A
{
    // Fatal error: Could not check compatibility between B::method():C and
    // A::method(): A, because class C is not available
    public function method(): С {}
}

class C extends B {}

Присваивающий оператор объединения с null

<?php

$array['key'] ??= computeDefault();

// Предыдущая проверка на null с присваиванием — примерно то же, что:
if (!isset($array['key'])) {
    $array['key'] = computeDefault();
}

Распаковка внутри массивов

<?php

$parts = ['apple', 'pear'];

$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
// ['banana', 'orange', 'apple', 'pear', 'watermelon'];

Разделитель в числовых литералах

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

<?php

6.674_083e-11; // число с плавающей точкой
299_792_458;   // десятичное число
0xCAFE_F00D;   // шестнадцатеричное число
0b0101_1111;   // двоичное число

Слабые ссылки

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

Исключения в магическом методе __toString()

В магическом методе __toString() разрешили выбрасывать исключения. Раньше это вызывало фатальную ошибку. Существующие отлавливаемые фатальные ошибки при преобразовании объекта в строку преобразовали в исключения класса Error.

Модуль cURL

В дополнение к станадртным названиям файлов класс CURLFile теперь поддерживает потоковые обёртки, если модуль собрали с библиотекой libcurl >= 7.56.0.

Модуль Filter

Фильтр FILTER_VALIDATE_FLOAT теперь поддерживает параметры min_range и max_range, с тем же смыслом, что и фильтр FILTER_VALIDATE_INT.

Модуль FFI

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

Модуль GD

Добавили константу IMG_FILTER_SCATTER для применения рассеивающегося фильтра к изображениям.

Модуль Hash

Добавили поддержку алгоритма crc32c, который вычисляет «хеш» на основе полинома Кастаноли. С этой реализацией алгоритма CRC32 работают системы хранения наподобие iSCSI, SCTP, Btrfs и ext4.

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

Добавили функцию mb_str_split(), которая выполняет то же, что и функция str_split(), но работает с кодовыми точками, а не с байтами.

Модуль OPcache

Добавили поддержку предварительной загрузки кода.

Регулярные выражения, совместимые с синтаксисом языка Perl

Функции preg_replace_callback() и preg_replace_callback_array() теперь принимают дополнительный аргумент flags с поддержкой флагов PREG_OFFSET_CAPTURE и PREG_UNMATCHED_AS_NULL. Он повлияет на формат массива совпавших значений, передаваемого в callback-функцию.

Модуль PDO

Имя пользователя и пароль как часть DSN-строки разрешили указывать для драйверов mysql, mssql, sybase, dblib, firebird и oci. Раньше это поддерживалось только для драйвера pgsql. Конструктор будет приоритетнее, если имя пользователя с паролем указали и в конструкторе, и в DSN-строке.

В SQL-запросах разрешили экранировать вопросительные знаки, чтобы они не воспринимались как заполнители параметров. Запись ?? отправит один знак вопроса в базу данных, и разрешит, например при работе с СУБД PostgreSQL, указывать оператор ?, чтобы проверить, содержит ли столбец JSON конкретный ключ.

Драйвер PDO_OCI

Для драйвера теперь доступен метод PDOStatement::getColumnMeta().

Драйвер PDO_SQLite

Вызов PDOStatement::getAttribute(PDO::SQLITE_ATTR_READONLY_STATEMENT) проверит, доступен ли подготовленный запрос только для чтения, т. е. не изменяет ли запрос базу данных.

При установке PDO::setAttribute(PDO::SQLITE_ATTR_EXTENDED_RESULT_CODES, true) методы PDO::errorInfo() и PDOStatement::errorInfo() возвращают расширенные коды ошибок СУБД SQLite3.

SQLite3

Добавили метод SQLite3::lastExtendedErrorCode(), который получает последний расширенный код ошибки.

Добавили метод SQLite3::enableExtendedResultCodes($enable = true), который заставит метод SQLite3::lastErrorCode() возвращать расширенные коды ошибок.

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

Функция strip_tags() с массивом имён тегов

Функция strip_tags() теперь также принимает массив разрешённых тегов: вместо strip_tags($str, '<a><p>') теперь можно написать strip_tags($str, ['a', 'p']).

Пользовательская сериализация объектов

Добавили новый механизм сериализации пользовательских объектов через два новых магических метода: __serialize и __unserialize.

<?php

// Метод возвращает массив с данными для сохранения целостного состояния объекта
public function __serialize(): array {}

// Восстанавливает состояние объекта из массива данных
public function __unserialize(array $data): void {}
Новый механизм сериализации заменяет интерфейс Serializable, который в будущем объявят устаревшим.

Функции слияния массивов без аргументов

Функции array_merge() и array_merge_recursive() стали поддерживать вызов без аргументов. При вызове без аргументов функции возвращают пустой массив. Функции также полезно вызывать с распаковкой аргумента spread-оператором: array_merge(...$arrays).

Функция proc_open()

Функция proc_open() теперь принимает массив вместо строки для выполнения команды. При таком вызове процесс открывается напрямую, без командной оболочки, а PHP экранирует аргументы, если потребуется.

<?php

proc_open(['php', '-r', 'echo "Привет, мир\n";'], $descriptors, $pipes);

Функция proc_open() теперь поддерживает дескрипторы redirect и null.

<?php

// То же самое, что и 2>&1 в командной оболочке
proc_open($cmd, [1 => ['pipe', 'w'], 2 => ['redirect', 1]], $pipes);

// То же самое, что и 2>/dev/null или 2>nul в командной оболочке
proc_open($cmd, [1 => ['pipe', 'w'], 2 => ['null']], $pipes);

Алгоритмы Argon2i и argon2id без библиотеки libargon

Функция password_hash() теперь поддерживает варианты хеширования argon2i и argon2id из модуля Sodium, если PHP собрали без библиотеки libargon.

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

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

PHP Core

Typed properties

Class properties now support type declarations.

<?php
class User {
    public int $id;
    public string $name;
}
?>
The above example will enforce that $user->id can only be assigned int values and $user->name can only be assigned string values.

Arrow functions

Arrow functions provide a shorthand syntax for defining functions with implicit by-value scope binding.

<?php
$factor = 10;
$nums = array_map(fn($n) => $n * $factor, [1, 2, 3, 4]);
// $nums = array(10, 20, 30, 40);
?>

Limited return type covariance and argument type contravariance

The following code will now work:

<?php
class A {}
class B extends A {}

class Producer {
    public function method(): A {}
}
class ChildProducer extends Producer {
    public function method(): B {}
}
?>
Full variance support is only available if autoloading is used. Inside a single file only non-cyclic type references are possible, because all classes need to be available before they are referenced.
<?php

/**
 * These classes satisfy the LSP requirements, because C is a subtype of A.
 * However, at the time class B is declared, class C is not yet available
 */
class A
{
    public function method(): A {}
}

class B extends A
{
    // Fatal error: Could not check compatibility between B::method():C and
    // A::method(): A, because class C is not available
    public function method(): C {}
}

class C extends B {}

?>

Null coalescing assignment operator

<?php
$array['key'] ??= computeDefault();
// is roughly equivalent to
if (!isset($array['key'])) {
    $array['key'] = computeDefault();
}
?>

Unpacking inside arrays

<?php
$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
// ['banana', 'orange', 'apple', 'pear', 'watermelon'];
?>

Numeric literal separator

Numeric literals can contain underscores between digits.

<?php
6.674_083e-11; // float
299_792_458;   // decimal
0xCAFE_F00D;   // hexadecimal
0b0101_1111;   // binary
?>

Weak references

Weak references allow the programmer to retain a reference to an object that does not prevent the object from being destroyed.

Allow exceptions from __toString()

Throwing exceptions from __toString() is now permitted. Previously this resulted in a fatal error. Existing recoverable fatal errors in string conversions have been converted to Error exceptions.

CURL

CURLFile now supports stream wrappers in addition to plain file names, if the extension has been built against libcurl >= 7.56.0.

Filter

The FILTER_VALIDATE_FLOAT filter now supports the min_range and max_range options, with the same semantics as FILTER_VALIDATE_INT.

FFI

FFI is a new extension, which provides a simple way to call native functions, access native variables, and create/access data structures defined in C libraries.

GD

Added the IMG_FILTER_SCATTER image filter to apply a scatter filter to images.

Hash

Added crc32c hash using Castagnoli's polynomial. This CRC32 variant is used by storage systems, such as iSCSI, SCTP, Btrfs and ext4.

Multibyte String

Added the mb_str_split() function, which provides the same functionality as str_split(), but operating on code points rather than bytes.

OPcache

Support for preloading code has been added.

Regular Expressions (Perl-Compatible)

The preg_replace_callback() and preg_replace_callback_array() functions now accept an additional flags argument, with support for the PREG_OFFSET_CAPTURE and PREG_UNMATCHED_AS_NULL flags. This influences the format of the matches array passed to the callback function.

PDO

The username and password can now be specified as part of the PDO DSN for the mysql, mssql, sybase, dblib, firebird and oci drivers. Previously this was only supported by the pgsql driver. If a username/password is specified both in the constructor and the DSN, the constructor takes precedence.

It is now possible to escape question marks in SQL queries to avoid them being interpreted as parameter placeholders. Writing ?? allows sending a single question mark to the database and e.g. use the PostgreSQL JSON key exists (?) operator.

PDO_OCI

PDOStatement::getColumnMeta() is now available.

PDO_SQLite

PDOStatement::getAttribute(PDO::SQLITE_ATTR_READONLY_STATEMENT) allows checking whether the statement is read-only, i.e. if it doesn't modify the database.

PDO::setAttribute(PDO::SQLITE_ATTR_EXTENDED_RESULT_CODES, true) enables the use of SQLite3 extended result codes in PDO::errorInfo() and PDOStatement::errorInfo().

SQLite3

Added SQLite3::lastExtendedErrorCode() to fetch the last extended result code.

Added SQLite3::enableExtendedResultCodes($enable = true), which will make SQLite3::lastErrorCode() return extended result codes.

Standard

strip_tags() with array of tag names

strip_tags() now also accepts an array of allowed tags: instead of strip_tags($str, '<a><p>') you can now write strip_tags($str, ['a', 'p']).

Custom object serialization

A new mechanism for custom object serialization has been added, which uses two new magic methods: __serialize and __unserialize.

<?php
// Returns array containing all the necessary state of the object.
public function __serialize(): array
{
}

// Restores the object state from the given data array.
public function __unserialize(array $data): void
{
}
?>
The new serialization mechanism supersedes the Serializable interface, which will be deprecated in the future.

Array merge functions without arguments

array_merge() and array_merge_recursive() may now be called without any arguments, in which case they will return an empty array. This is useful in conjunction with the spread operator, e.g. array_merge(...$arrays).

proc_open() function

proc_open() now accepts an array instead of a string for the command. In this case the process will be opened directly (without going through a shell) and PHP will take care of any necessary argument escaping.

<?php
proc_open(['php', '-r', 'echo "Hello World\n";'], $descriptors, $pipes);
?>

proc_open() now supports redirect and null descriptors.

<?php
// Like 2>&1 on the shell
proc_open($cmd, [1 => ['pipe', 'w'], 2 => ['redirect', 1]], $pipes);
// Like 2>/dev/null or 2>nul on the shell
proc_open($cmd, [1 => ['pipe', 'w'], 2 => ['null']], $pipes);
?>

argon2i(d) without libargon

password_hash() now has the argon2i and argon2id implementations from the sodium extension when PHP is built without libargon.

PHP 7.4+: короткое преобразование спискаСамостоятельный пример
<?php
$vat = 1.2;
$prices = [100, 250];
$withVat = array_map(fn (int $price): int => (int) ($price * $vat), $prices);
echo implode(', ', $withVat), "\n";
Ожидаемый результат
120, 300

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Ядро PHP

Массивоподобное обращение к немассивам

Попытка использовать значения с типом null, bool, int, float или resource как массив (например, $null["key"]) теперь создаст уведомление.

Функция get_declared_classes()

Функция get_declared_classes() больше не возвращает анонимные классы, которые ещё не были созданы.

Ключевое слово fn

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

Тег <?php в конце файла

Запись <?php в конце файла (без завершающей новой строки) теперь будет интерпретироваться как открывающий тег PHP. Ранее она обрабатывалась либо как короткий открывающий тег с последующим литералом php и приводил к синтаксической ошибке (при short_open_tag=1), либо воспринимался как строковый литерал <?php (в случае short_open_tag=0).

Потоковые обёртки

При включении данных потока выражениями include или require метод streamWrapper::stream_set_option() будет вызываться с параметром STREAM_OPTION_READ_BUFFER. Для пользовательских потоковых обёрток, возможно, потребуется реализация метода streamWrapper::stream_set_option(), чтобы убрать предупреждение (как правило, хватает только возврата false).

Сериализация

Удалён формат сериализации o. Поскольку сам PHP им не пользуется, он мог только нарушить десериализацию строк, созданных вручную.

Константы алгоритма пароля

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

  • PASSWORD_DEFAULT раньше было целочисленным 1; теперь строка '2y' (в PHP 7.4.0, 7.4.1 и 7.4.2 было null)

  • PASSWORD_BCRYPT раньше было целочисленным 1; теперь строка '2y'

  • PASSWORD_ARGON2I раньше было целочисленным 2; теперь строка 'argon2i'

  • PASSWORD_ARGON2ID раньше было целочисленным 3; теперь строка 'argon2id'

Приложения, правильно использующие константы PASSWORD_DEFAULT, PASSWORD_BCRYPT, PASSWORD_ARGON2I и PASSWORD_ARGON2ID, будут работать как и раньше.

Функция htmlentities()

Функция htmlentities() теперь будет выдавать уведомление (вместо предупреждения уровня E_STRICT), если она используется с кодировкой, для которой поддерживается только преобразование основных символов. В этом случае она эквивалентна использованию htmlspecialchars().

Функции fread() и fwrite()

Функции fread() и fwrite() теперь будут возвращать false, если операция не удалась. Ранее возвращалась пустая строка или 0. К ошибкам EAGAIN/EWOULDBLOCK это не относится.

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

Вычисления над числами с произвольной точностью BCMath

Теперь функции BCMath будут выдавать предупреждения, если передано число с ошибкой, например, "32foo". Подобный аргумент, как и раньше, будет интерпретирован как ноль.

CURL

Попытка сериализации класса CURLFile теперь создаст исключение. Ранее исключение выбрасывалось только при десериализации.

Использование CURLPIPE_HTTP1 объявлено устаревшим, и не будет поддерживаться с версии cURL 7.62.0.

Параметр $version функции curl_version() объявлен устаревшим. Если передаётся значение, не равное CURLVERSION_NOW по умолчанию, будет вызвано предупреждение, а параметр проигнорирован.

Дата и время

Вызов функции var_dump() или похожих отладочных функций на экземпляре класса DateTime или DateTimeImmutable больше не оставляет внутренние свойства объекта доступными для прямого считывания или записи при очередном обращении.

Сравнение объектов DateInterval (с использованием ==, < и т.д.) теперь создаёт предупреждение и всегда возвращает false. Ранее все объекты DateInterval считались одинаковыми, если у них не было свойств.

Intl

Значение параметров по умолчанию в функциях idn_to_ascii() и idn_to_utf8() теперь INTL_IDNA_VARIANT_UTS46 вместо устаревшего INTL_IDNA_VARIANT_2003.

MySQLi

Функциональность встроенного сервера была удалена. Она была сломана как минимум с PHP 7.0.

Недокументированное свойство mysqli::$stat было удалено в пользу использования mysqli::stat().

OpenSSL

Функция openssl_random_pseudo_bytes() теперь будет выбрасывать исключение в тех же ситуациях, что и функция random_bytes(). В частности, выбрасывается исключение Error, если количество запрошенных байтов меньше или равно нулю. Исключение Exception выбрасывается, если не получена достаточная случайность. Аргумент $crypto_strong гарантированно будет равен true, если функция ничего не выбрасывает, поэтому явно проверять его не нужно.

Регулярные выражения (совместимые Perl)

При использовании флага PREG_UNMATCHED_AS_NULL, завершающие несовпадающие подмаски теперь будут иметь значение null (или [null, -1], если включено сохранение позиции подмаски). Это означает, что размер $matches всегда будет одинаковым.

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

Попытка сериализовать экземпляр PDO или PDOStatement теперь создаст Exception, а не PDOException, по аналогии с другими внутренними классами, которые не поддерживают сериализацию.

Reflection

Объекты Reflection теперь создают исключение, если попробовать их сериализовать. Сериализация объектов Reflection никогда не поддерживалась и приводила к повреждению объектов Reflection. Сейчас это было явно запрещено.

Изменились значения констант классов ReflectionClassConstant, ReflectionMethod и ReflectionProperty.

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

Вызов get_object_vars() с экземпляром ArrayObject теперь всегда будет возвращать свойства самого ArrayObject (или подкласса). Ранее он возвращал значения упакованного массива/объекта, если не был указан флаг ArrayObject::STD_PROP_LIST.

Другие затронутые операции:

  • ReflectionObject::getProperties()

  • reset(), current() и т.д. Используйте вместо этого методы Iterator.

  • Вероятно, все остальное работает со свойствами объекта при доступе в виде списка, например, array_walk().

На приведение типа (array) эти изменения не повлияют. Они по-прежнему возвращают либо упакованный массив, либо свойства ArrayObject, в зависимости от того, используется ли флаг ArrayObject::STD_PROP_LIST.

Метод SplPriorityQueue::setExtractFlags() выбросит исключение, если передан ноль. Ранее это приводило к отлавливаемой фатальной ошибке при следующей операции извлечения.

ArrayObject, ArrayIterator, SplDoublyLinkedList и SplObjectStorage теперь поддерживают __serialize() и __unserialize() в дополнение к интерфейсу Serializable. Поэтому теперь созданные в более старых версиях PHP сериализованные данные, всё ещё могут быть неверно обработаны. Однако новые созданные сериализованные данные в PHP 7.4, не будут восприниматься в более старых версиях.

Лексер (Tokenizer)

Функция token_get_all() теперь отобразит метку T_BAD_CHARACTER в случае обнаружения непредвиденных символов в потоке меток.

Входящие Cookies

Начиная с PHP 7.4.11 имена входящих cookie больше не декодируются из URL-закодированной строки из соображений безопасности.

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

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

PHP Core

Array-style access of non-arrays

Trying to use values of type null, bool, int, float or resource as an array (such as $null["key"]) will now generate a notice.

get_declared_classes() function

The get_declared_classes() function no longer returns anonymous classes that have not been instantiated yet.

fn keyword

fn is now a reserved keyword. In particular, it can no longer be used as a function or class name. It can still be used as a method or class constant name.

<?php tag at end of file

<?php at the end of the file (without trailing newline) will now be interpreted as an opening PHP tag. Previously it was interpreted either as a short opening tag followed by literal php and resulted in a syntax error (with short_open_tag=1) or was interpreted as a literal <?php string (with short_open_tag=0).

Stream wrappers

When using include/require on a stream, streamWrapper::stream_set_option() will be invoked with the STREAM_OPTION_READ_BUFFER option. Custom stream wrapper implementations may need to implement the streamWrapper::stream_set_option() method to avoid a warning (always returning false is a sufficient implementation).

Serialization

The o serialization format has been removed. As it is never produced by PHP, this may only break unserialization of manually crafted strings.

Password algorithm constants

Password hashing algorithm identifiers are now nullable strings rather than integers.

Applications correctly using the constants PASSWORD_DEFAULT, PASSWORD_BCRYPT, PASSWORD_ARGON2I, and PASSWORD_ARGON2ID will continue to function correctly.

htmlentities() function

htmlentities() will now raise a notice (instead of a strict standards warning) if it is used with an encoding for which only basic entity substitution is supported, in which case it is equivalent to htmlspecialchars().

fread() and fwrite() function

fread() and fwrite() will now return false if the operation failed. Previously an empty string or 0 was returned. EAGAIN/EWOULDBLOCK are not considered failures.

These functions now also raise a notice on failure, such as when trying to write to a read-only file resource.

BCMath Arbitrary Precision Mathematics

BCMath functions will now warn if a non well-formed number is passed, such as "32foo". The argument will be interpreted as zero, as before.

CURL

Attempting to serialize a CURLFile class will now generate an exception. Previously the exception was only thrown on unserialization.

Using CURLPIPE_HTTP1 is deprecated, and is no longer supported as of cURL 7.62.0.

The $version parameter of curl_version() is deprecated. If any value not equal to the default CURLVERSION_NOW is passed, a warning is raised and the parameter is ignored.

Date and Time

Calling var_dump() or similar on a DateTime or DateTimeImmutable instance will no longer leave behind accessible properties on the object.

Comparison of DateInterval objects (using ==, <, and so on) will now generate a warning and always return false. Previously all DateInterval objects were considered equal, unless they had properties.

Intl

The default parameter value of idn_to_ascii() and idn_to_utf8() is now INTL_IDNA_VARIANT_UTS46 instead of the deprecated INTL_IDNA_VARIANT_2003.

MySQLi

The embedded server functionality has been removed. It was broken since at least PHP 7.0.

The undocumented mysqli::$stat property has been removed in favor of mysqli::stat().

OpenSSL

The openssl_random_pseudo_bytes() function will now throw an exception in error situations, similar to random_bytes(). In particular, an Error is thrown if the number of requested bytes is less than or equal to zero, and an Exception is thrown if sufficient randomness cannot be gathered. The $crypto_strong output argument is guaranteed to always be true if the function does not throw, so explicitly checking it is not necessary.

Regular Expressions (Perl-Compatible)

When PREG_UNMATCHED_AS_NULL mode is used, trailing unmatched capturing groups will now also be set to null (or [null, -1] if offset capture is enabled). This means that the size of the $matches will always be the same.

PHP Data Objects

Attempting to serialize a PDO or PDOStatement instance will now generate an Exception rather than a PDOException, consistent with other internal classes which do not support serialization.

Reflection

Reflection objects will now generate an exception if an attempt is made to serialize them. Serialization for reflection objects was never supported and resulted in corrupted reflection objects. It has been explicitly prohibited now.

The values of the class constant of ReflectionClassConstant, ReflectionMethod and ReflectionProperty have changed.

Standard PHP Library (SPL)

Calling get_object_vars() on an ArrayObject instance will now always return the properties of the ArrayObject itself (or a subclass). Previously it returned the values of the wrapped array/object unless the ArrayObject::STD_PROP_LIST flag was specified.

Other affected operations are:

(array) casts are not affected. They will continue to return either the wrapped array, or the ArrayObject properties, depending on whether the ArrayObject::STD_PROP_LIST flag is used.

SplPriorityQueue::setExtractFlags() will throw an exception if zero is passed. Previously this would generate a recoverable fatal error on the next extraction operation.

ArrayObject, ArrayIterator, SplDoublyLinkedList and SplObjectStorage now support the __serialize() and __unserialize() mechanism in addition to the Serializable interface. This means that serialization payloads created on older PHP versions can still be unserialized, but new payloads created by PHP 7.4 will not be understood by older versions.

Tokenizer

token_get_all() will now emit a T_BAD_CHARACTER token for unexpected characters instead of leaving behind holes in the token stream.

Incoming Cookies

As of PHP 7.4.11, the names of incoming cookies are no longer url-decoded for security reasons.

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

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

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

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

Ядро PHP

Вложенные тернарные операторы без явного указания скобок

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

<?php
1 ? 2 : 3 ? 4 : 5;   // устарело
(1 ? 2 : 3) ? 4 : 5; // хорошо
1 ? 2 : (3 ? 4 : 5); // хорошо
?>

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

1 ? 2 ? 3 : 4 : 5 // хорошо

Обращение к индексу массива и строки через фигурные скобки

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

Приведение типа (real) и функция is_real()

Приведение типа (real) объявлено устаревшим, вместо этого используйте (float).

Функция is_real() также объявлена устаревшей, вместо неё используйте is_float().

Отмена привязки $this при использовании $this

Отмена привязки $this в нестатическом замыкании, которое использует $this, объявлена устаревшей.

Ключевое слово parent вне родительского класса

Использование parent внутри класса, у которого нет родителя, объявлено устаревшим, а в будущем произойдёт ошибка компиляции. А пока ошибка будет только при обращении к родителю во время выполнения.

INI-опция allow_url_include

Конфигурационная директива allow_url_include объявлена устаревшей. При включённой опции будет вызвано уведомление об устаревшей возможности во время загрузки.

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

Передача недопустимых символов в base_convert(), bindec(), octdec() теперь вызывает уведомление об устаревшей возможности. Результат всё равно будет вычислен так, как если бы недопустимых символов не было. Ведущие и завершающие пробелы, а также префиксы типа 0x (в зависимости от системы счисления) по-прежнему разрешены.

Использование array_key_exists() с объектом

Использование array_key_exists() с объектом объявлено устаревшим. Вместо этого следует использовать либо isset(), либо property_exists().

Функции, связанные с волшебными кавычками

Функции get_magic_quotes_gpc() и get_magic_quotes_runtime() объявлены устаревшими. Они всегда возвращают false.

Функция hebrevc()

Функция hebrevc() объявлена устаревшей. Её можно заменить на выражение nl2br(hebrev($str)), либо лучше всего использовать поддержку Unicode RTL.

Функция convert_cyr_string()

Функция convert_cyr_string() объявлена устаревшей. Её можно заменить либо на mb_convert_string(), либо iconv() или на класс UConverter.

Функция money_format()

Функция money_format() объявлена устаревшей. Она может быть заменена функциональностью интернационализации - классом NumberFormatter.

Функция ezmlm_hash()

Функция ezmlm_hash() объявлена устаревшей.

Функция restore_include_path()

Функция restore_include_path() объявлена устаревшей. Её можно заменить на ini_restore('include_path').

Использование implode с нерекомендуемым порядком параметров

Передача параметров в implode() в обратном порядке объявлена устаревшей - используйте implode($glue, $parts) вместо implode($parts, $glue).

COM

Импорт библиотек типов с регистрацией констант без учёта регистра объявлен устаревшим.

Фильтрация

Фильтр FILTER_SANITIZE_MAGIC_QUOTES объявлен устаревшим, вместо него используйте FILTER_SANITIZE_ADD_SLASHES.

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

Передача нестрокового шаблона в mb_ereg_replace() объявлена устаревшей. В данный момент нестроковые значения интерпретируются как кодовые точки ASCII. В PHP 8 шаблон будет обрабатываться как строка.

Передача кодировки в качестве 3-го параметра в mb_strrpos() объявлена устаревшей. Вместо этого передавайте позицию как 0, а кодировку в 4-м параметре.

Облегчённый протокол доступа к каталогам (LDAP)

Функции ldap_control_paged_result_response() и ldap_control_paged_result() объявлены устаревшими. Для управления постраничным режимом используйте функцию ldap_search().

Reflection

Вызовы ReflectionType::__toString() теперь создают уведомление об устаревшей возможности. Этот метод объявлен устаревшим в пользу использования ReflectionNamedType::getName() в документации с PHP 7.1, но не выдавал соответствующего уведомления по техническим причинам.

Методы export() у всех классов Reflection объявлены устаревшими. Теперь создавайте объект Reflection и преобразуйте его в строку:

<?php
// Вместо ReflectionClass::export(Foo::class, false) используйте:
echo new ReflectionClass(Foo::class), "\n";

// Вместо $str = ReflectionClass::export(Foo::class, true) используйте:
$str = (string) new ReflectionClass(Foo::class);
?>

Сокеты

Флаги AI_IDN_ALLOW_UNASSIGNED и AI_IDN_USE_STD3_ASCII_RULES для функции socket_addrinfo_lookup() объявлены устаревшими из-за обновления glibc.

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

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

PHP Core

Nested ternary operators without explicit parentheses

Nested ternary operations must explicitly use parentheses to dictate the order of the operations. Previously, when used without parentheses, the left-associativity would not result in the expected behaviour in most cases.

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

Parentheses are not required when nesting into the middle operand, as this is always unambiguous and not affected by associativity:

1 ? 2 ? 3 : 4 : 5 // ok

Array and string offset access using curly braces

The array and string offset access syntax using curly braces is deprecated. Use $var[$idx] instead of $var{$idx}.

(real) cast and is_real() function

The (real) cast is deprecated, use (float) instead.

The is_real() function is also deprecated, use is_float() instead.

Unbinding $this when $this is used

Unbinding $this of a non-static closure that uses $this is deprecated.

parent keyword without parent class

Using parent inside a class without a parent is deprecated, and will throw a compile-time error in the future. Currently an error will only be generated if/when the parent is accessed at run-time.

allow_url_include INI option

The allow_url_include ini directive is deprecated. Enabling it will generate a deprecation notice at startup.

Invalid characters in base conversion functions

Passing invalid characters to base_convert(), bindec(), octdec() and hexdec() will now generate a deprecation notice. The result will still be computed as if the invalid characters did not exist. Leading and trailing whitespace, as well as prefixes of type 0x (depending on base) continue to be allowed.

Using array_key_exists() on objects

Using array_key_exists() on objects is deprecated. Instead either isset() or property_exists() should be used.

Magic quotes functions

The get_magic_quotes_gpc() and get_magic_quotes_runtime() functions are deprecated. They always return false.

hebrevc() function

The hebrevc() function is deprecated. It can be replaced with nl2br(hebrev($str)) or, preferably, the use of Unicode RTL support.

convert_cyr_string() function

The convert_cyr_string() function is deprecated. It can be replaced by one of mb_convert_string(), iconv() or UConverter.

money_format() function

The money_format() function is deprecated. It can be replaced by the intl NumberFormatter functionality.

ezmlm_hash() function

The ezmlm_hash() function is deprecated.

restore_include_path() function

The restore_include_path() function is deprecated. It can be replaced by ini_restore('include_path').

Implode with historical parameter order

Passing parameters to implode() in reverse order is deprecated, use implode($glue, $parts) instead of implode($parts, $glue).

COM

Importing type libraries with case-insensitive constant registering has been deprecated.

Multibyte String

Passing a non-string pattern to mb_ereg_replace() is deprecated. Currently, non-string patterns are interpreted as ASCII codepoints. In PHP 8, the pattern will be interpreted as a string instead.

Passing the encoding as 3rd parameter to mb_strrpos() is deprecated. Instead pass a 0 offset, and encoding as 4th parameter.

Lightweight Directory Access Protocol

ldap_control_paged_result_response() and ldap_control_paged_result() are deprecated. Pagination controls can be sent along with ldap_search() instead.

Reflection

Calls to ReflectionType::__toString() now generate a deprecation notice. This method has been deprecated in favor of ReflectionNamedType::getName() in the documentation since PHP 7.1, but did not throw a deprecation notice for technical reasons.

The export() methods on all Reflection classes are deprecated. Construct a Reflection object and convert it to string instead:

<?php
// ReflectionClass::export(Foo::class, false) is:
echo new ReflectionClass(Foo::class), "\n";

// $str = ReflectionClass::export(Foo::class, true) is:
$str = (string) new ReflectionClass(Foo::class);
?>

Socket

The AI_IDN_ALLOW_UNASSIGNED and AI_IDN_USE_STD3_ASCII_RULES flags for socket_addrinfo_lookup() are deprecated, due to an upstream deprecation in glibc.

PHP 7.3 → 7.4: Удалённые расширения

Удаление расширения — зависимость уровня архитектуры. Нужно найти все вызовы, формат сохранённых данных и операционные процедуры, выбрать замену и провести миграцию до смены runtime.

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

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

Следующие модули перемещены в репозиторий PECL и больше не будут поставляться с дистрибутивом PHP. Версии этих модулей в виде пакетов PECL будут создаваться в соответствии с потребностями пользователей.

  • Firebird/Interbase - доступ к базам данных на InterBase и/или Firebird по-прежнему возможен через драйвер PDO Firebird.

  • Recode

  • WDDX

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

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

These extensions have been moved to PECL and are no longer part of the PHP distribution. The PECL package versions of these extensions will be created according to user demand.

PHP 7.3 → 7.4: Другие изменения

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

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

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

Улучшения производительности

Ядро PHP

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

Регулярные выражения (совместимые с Perl)

Когда функция preg_match() в режиме UTF-8 (модификатор "u") неоднократно вызывается для одной и той же строки (возможно, на различных позициях), проверка правильности UTF-8 будет выполнена только один раз.

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

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

opcache.preload_user - новая INI-директива для установки пользователя, из-под которого должен выполняться код предварительной загрузки, иначе это будет root (не допускается по соображениям безопасности).

Миграция на pkg-config

Множество модулей теперь используют исключительно pkg-config, чтобы определять зависимости библиотек. Как правило, это означает, что вместо --with-foo-dir=DIR используется только --with-foo. Пользовательские пути к библиотекам могут быть указаны либо путём добавления дополнительных каталогов в PKG_CONFIG_PATH, либо путём явного указания параметров компиляции через FOO_CFLAGS и FOO_LIBS.

Следующие модули и SAPI были затронуты этим изменением:

  • CURL:

    • Опция --with-curl больше не принимает каталог.

  • Enchant:

    • Опция --with-enchant больше не принимает каталог.

  • FPM:

    • Опция --with-fpm-systemd теперь использует только pkg-config для проверок libsystem. Минимальная обязательная версия libsystemd - 209.

  • GD:

    • Опция --with-gd переименована в --enable-gd (должен быть включён модуль или нет), а опция --with-external-gd использует внешнюю библиотеку libgd, вместо той, которая идёт в комплекте.

    • Опция --with-png-dir удалена. Наличие libpng теперь обязательно.

    • Опция --with-zlib-dir удалена. Наличие zlib теперь обязательно.

    • Опция --with-freetype-dir переименована в --with-freetype

    • Опция --with-jpeg-dir переименована в --with-jpeg

    • Опция --with-webp-dir переименована в --with-webp

    • Опция --with-xpm-dir переименована в --with-xpm

  • IMAP:

    • Опция --with-kerberos-systemd больше не принимает каталог.

  • Intl:

    • Опция --with-icu-dir удалена. Если передан --enable-intl, тогда всегда требуется наличие libicu.

  • LDAP:

    • Опция --with-ldap-sasl больше не принимает каталог.

  • Libxml:

    • Опция --with-libxml-dir удалена.

    • Опция --enable-libxml переименована в --with-libxml.

    • Опция --with-libexpat-dir переименована в --with-expat и больше не принимает каталог.

  • LiteSpeed:

    • Опция --with-litespeed переименована в --enable-litespeed.

  • Mbstring:

    • Опция --with-onig удалена. Если --disable-mbregex не указан, требуется libonig.

  • ODBC:

    • Опция --with-iodbc больше не принимает каталог.

    • Опция --with-unixODBC без каталога теперь использует pkg-config (предпочтительно). Каталог по-прежнему можно указать для старых версий без libodbc.pc.

  • OpenSSL:

    • Опция --with-openssl больше не принимает каталог.

  • PCRE:

    • Опция --with-pcre-regex удалена. Вместо этого --with-external-pcre позволяет использовать внешнюю PCRE-библиотеку вместо встроенной.

  • PDO_SQLite:

    • Опция --with-pdo-sqlite больше не принимает каталог.

  • Readline:

    • Опция --with-libedit больше не принимает каталог.

  • Sodium:

    • Опция --with-sodium больше не принимает каталог.

  • SQLite3:

    • Опция --with-sqlite3 больше не принимает каталог.

  • XSL:

    • Опция --with-xsl больше не принимает каталог.

  • Zip:

    • Опция --with-libzip удалена.

    • Опция --enable-zip переименована в --with-zip.

Экранирование CSV

fputcsv(), fgetcsv(), SplFileObject::fputcsv(), SplFileObject::fgetcsv() и SplFileObject::setCsvControl() теперь принимаем пустую строку в аргументе $escape. Это отключит проприетарный механизм экранирования PHP.

Поведение функции str_getcsv() было соответствующим образом скорректировано (ранее пустая строка была идентична использованию значения по умолчанию).

Метод SplFileObject::getCsvControl() теперь также может возвращать пустую строку для третьего элемента массива, соответственно.

Фильтрация данных

Модуль filter больше не поддерживает ---with-pcre-dir для Unix-сборок и поэтому может быть спокойно собран для общего пользования с помощью ./configure.

GD

Поведение функции imagecropauto() в встроенной библиотеке libgd было синхронизировано с системной библиотекой libgd:

  • IMG_CROP_DEFAULT в случае неудачного выполнения не заменяется на IMG_CROP_SIDES

  • Пороговое значение кадрирования теперь рассчитывается из алгоритма в системной библиотеке libgd

Значение по умолчанию $modeimagecropauto() было изменено на IMG_CROP_DEFAULT; передача -1 теперь объявлена устаревшей.

imagescale() теперь поддерживает масштабирование с сохранением соотношения сторон до фиксированной высоты при передаче -1 в параметр $new_width.

Фреймворк хеш-кодов HASH

Модуль hash больше нельзя отключить, теперь он является неотъемлемой частью любой PHP-сборки, подобно модулю date.

Intl

Модуль intl теперь требует как минимум ICU 50.1.

Класс ResourceBundle теперь реализует Countable.

Облегчённый протокол доступа к каталогам (LDAP)

Поддержка nsldap и umich_ldap была удалена.

Libxml

Все модули на основе libxml теперь требуют libxml версии 2.7.6 или новее.

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

Библиотека oniguruma больше не идёт в комплекте с PHP, вместо неё в системе должна быть libonig. В качестве альтернативы можно указать ---disable-mbregex, чтобы отключить компонент mbregex.

OPcache

Конфигурационные опции --disable-opcache-file и --enable-opcache-file удалены в пользу использования INI-директивы opcache.file_cache

Хеширование паролей

Функции password_hash() и password_needs_rehash() теперь принимают обнуляемую строку (string) и целое число (int) в аргументе $algo.

PEAR

Установка PEAR (вместе с PECL) больше не включена по умолчанию. Её можно явно включить, используя --with-pear. Эта опция объявлена устаревшей и может быть удалена в будущем.

Reflection

Изменены числовые значения констант-модификаторов (IS_ABSTRACT, IS_DEPRECATED, IS_EXPLICIT_ABSTRACT, IS_FINAL, IS_IMPLICIT_ABSTRACT, IS_PRIVATE, IS_PROTECTED, IS_PUBLIC и IS_STATIC) в классах ReflectionClass, ReflectionFunction, ReflectionMethod, ReflectionObject и ReflectionProperty.

SimpleXML

Класс SimpleXMLElement теперь реализует Countable.

SQLite3

Встроенная в сборке библиотека libsqlite удалена. Для сборки модуля SQLite3 теперь требуется libsqlite3 ≥ 3.7.4. Чтобы собрать модуль PDO_SQLite обязательно требуется libsqlite3 ≥ 3.5.0.

Сериализация и десериализация SQLite3, SQLite3Stmt и SQLite3Result теперь явно запрещены. Раньше сериализация экземпляров этих классов была возможна, но десериализация делала объекты неиспользуемыми для дальнейшей работы.

Нотацию @param теперь также можно использовать для обозначения параметров SQL-запроса.

Zip

Встроенная библиотека libzip удалена. Теперь обязательно наличие в системе библиотеки libzip >= 0.11, чтобы собрать модуль zip.

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

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

Performance Improvements

PHP Core

A specialized VM opcode for the array_key_exists() function has been added, which improves performance of this function if it can be statically resolved. In namespaced code, this may require writing \array_key_exists() or explicitly importing the function.

Regular Expressions (Perl-Compatible)

When preg_match() in UTF-8 mode ("u" modifier) is repeatedly called on the same string (but possibly different offsets), it will only be checked for UTF-8 validity once.

Changes to INI File Handling

zend.exception_ignore_args is a new INI directive for including or excluding arguments from stack traces generated from exceptions.

opcache.preload_user is a new INI directive for specifying the user account under which preloading code is executed if it would otherwise be run as root (which is not allowed for security reasons).

Migration to pkg-config

A number of extensions have been migrated to exclusively use pkg-config for the detection of library dependencies. Generally, this means that instead of using --with-foo-dir=DIR or similar only --with-foo is used. Custom library paths can be specified either by adding additional directories to PKG_CONFIG_PATH or by explicitly specifying compilation options through FOO_CFLAGS and FOO_LIBS.

The following extensions and SAPIs are affected:

  • CURL:

    • --with-curl no longer accepts a directory.

  • Enchant:

    • --with-enchant no longer accepts a directory.

  • FPM:

    • --with-fpm-systemd now uses only pkg-config for libsystem checks. The libsystemd minimum required version is 209.

  • GD:

    • --with-gd becomes --enable-gd (whether to enable the extension at all) and --with-external-gd (to opt into using an external libgd, rather than the bundled one).

    • --with-png-dir has been removed. libpng is required.

    • --with-zlib-dir has been removed. zlib is required.

    • --with-freetype-dir becomes --with-freetype

    • --with-jpeg-dir becomes --with-jpeg

    • --with-webp-dir becomes --with-webp

    • --with-xpm-dir becomes --with-xpm

  • IMAP:

    • --with-kerberos-systemd no longer accepts a directory.

  • Intl:

    • --with-icu-dir has been removed. If --enable-intl is passed, then libicu is always required.

  • LDAP:

    • --with-ldap-sasl no longer accepts a directory.

  • Libxml:

    • --with-libxml-dir has been removed.

    • --enable-libxml becomes --with-libxml.

    • --with-libexpat-dir has been renamed to --with-expat and no longer accepts a directory.

  • LiteSpeed:

    • --with-litespeed becomes --enable-litespeed.

  • Mbstring:

    • --with-onig has been removed. Unless --disable-mbregex has been passed, libonig is required.

  • ODBC:

    • --with-iodbc no longer accepts a directory.

    • --with-unixODBC without a directory now uses pkg-config (preferred). Directory is still accepted for old versions without libodbc.pc.

  • OpenSSL:

    • --with-openssl no longer accepts a directory.

  • PCRE:

    • --with-pcre-regex has been removed. Instead --with-external-pcre is provided to opt into using an external PCRE library, rather than the bundled one.

  • PDO_SQLite:

    • --with-pdo-sqlite no longer accepts a directory.

  • Readline:

    • --with-libedit no longer accepts a directory.

  • Sodium:

    • --with-sodium no longer accepts a directory.

  • SQLite3:

    • --with-sqlite3 no longer accepts a directory.

  • XSL:

    • --with-xsl no longer accepts a directory.

  • Zip:

    • --with-libzip has been removed.

    • --enable-zip becomes --with-zip.

CSV escaping

fputcsv(), fgetcsv(), SplFileObject::fputcsv(), SplFileObject::fgetcsv(), and SplFileObject::setCsvControl() now accept an empty string as $escape argument, which disables the proprietary PHP escaping mechanism.

The behavior of str_getcsv() has been adjusted accordingly (formerly, an empty string was identical to using the default).

SplFileObject::getCsvControl() now may also return an empty string for the third array element, accordingly.

Data Filtering

The filter extension no longer exposes --with-pcre-dir for Unix builds and can now reliably be built as shared when using ./configure

GD

The behavior of imagecropauto() in the bundled libgd has been synced with that of system libgd:

The default $mode parameter of imagecropauto() has been changed to IMG_CROP_DEFAULT; passing -1 is now deprecated.

imagescale() now supports aspect ratio preserving scaling to a fixed height by passing -1 as $new_width.

HASH Message Digest Framework

The hash extension cannot be disabled anymore and is always an integral part of any PHP build, similar to the date extension.

Intl

The intl extension now requires at least ICU 50.1.

ResourceBundle now implements Countable.

Lightweight Directory Access Protocol

Support for nsldap and umich_ldap has been removed.

Libxml

All libxml-based extensions now require libxml 2.7.6 or newer.

Multibyte String

The oniguruma library is no longer bundled with PHP, instead libonig needs to be available on the system. Alternatively --disable-mbregex can be used to disable the mbregex component.

OPcache

The --disable-opcache-file and --enable-opcache-file configure options have been removed in favor of the opcache.file_cache INI directive.

Password Hashing

The password_hash() and password_needs_rehash() functions now accept nullable string and int for $algo argument.

PEAR

Installation of PEAR (including PECL) is no longer enabled by default. It can be explicitly enabled using --with-pear. This option is deprecated and may be removed in the future.

Reflection

The numeric values of the modifier constants (IS_ABSTRACT, IS_DEPRECATED, IS_EXPLICIT_ABSTRACT, IS_FINAL, IS_IMPLICIT_ABSTRACT, IS_PRIVATE, IS_PROTECTED, IS_PUBLIC, and IS_STATIC) on the ReflectionClass, ReflectionFunction, ReflectionMethod, ReflectionObject, and ReflectionProperty classes have changed.

SimpleXML

SimpleXMLElement now implements Countable.

SQLite3

The bundled libsqlite has been removed. To build the SQLite3 extension a system libsqlite3 ≥ 3.7.4 is now required. To build the PDO_SQLite extension a system libsqlite3 ≥ 3.5.0 is now required.

Serialization and unserialization of SQLite3, SQLite3Stmt and SQLite3Result is now explicitly forbidden. Formerly, serialization of instances of these classes was possible, but unserialization yielded unusable objects.

The @param notation can now also be used to denote SQL query parameters.

Zip

The bundled libzip library has been removed. A system libzip >= 0.11 is now necessary to build the zip extension.

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

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

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

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

Флаги команды configure

Команда configure теперь учитывает дополнительные переменные окружения CFLAGS и LDFLAGS.

Обработка CTRL

Комбинации клавиш CTRL +C и CTRL +BREAK в командной строке перехватывают путём установки функцией sapi_windows_set_ctrl_handler() функции-обработчика.

Функция proc_open() в ОС Windows принимает опцию "create_process_group". Это требуется, когда дочернему процессу необходимо обрабатывать события нажатия клавиши CTRL.

OPcache

Модуль OPcache теперь поддерживает произвольное количество отдельных кешей на каждого пользователя через INI-директиву opcache.cache_id. Процессы с одинаковым идентификатором кеша и пользователем используют один и тот же экземпляр OPcache.

stat

Улучшена реализация stat.

  • Передаётся номер индексного дескриптора (inode), который опирается на индекс файла в NTFS.

  • Номер устройства теперь исходит из серийного номера тома.

Обратите внимание, что на 64-битных системах оба значения извлекаются из системы в исходном виде. В 32-разрядных системах эти значения фиктивные, потому что могут превышать максимальное 32-разрядное целое число, разрешённое в PHP.

libsqlite3

libsqlite3 больше не компилируется статически в php_sqlite3.dll и php_pdo_sqlite.dll, но доступен как libsqlite3.dll. Обратитесь к инструкции по установке для SQLite3 и PDO_SQLITE соответственно.

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

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

configure flags

configure now regards additional CFLAGS and LDFLAGS set as environment variables.

CTRL handling

CTRL +C and CTRL +BREAK on console can be caught by setting a handler function with sapi_windows_set_ctrl_handler().

proc_open() on Windows can be passed a "create_process_group" option. It is required if the child process is supposed to handle CTRL events.

OPcache

OPcache now supports an arbitrary number of separate caches per user via the INI directive opcache.cache_id. All processes with the same cache ID and user share an OPcache instance.

stat

The stat implementation has been refactored.

  • An inode number is delivered and is based on the NTFS file index.

  • The device number is now based on the volume serial number.

Note that both values are derived from the system and provided as-is on 64-bit systems. On 32-bit systems, these values might overflow the 32-bit integer in PHP, so they're fake.

libsqlite3

libsqlite3 is no longer compiled statically into php_sqlite3.dll and php_pdo_sqlite.dll, but rather available as libsqlite3.dll. Refer to the installation instructions for SQLite3 and PDO_SQLITE, respectively.

PHP 7.4 → 8.0

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

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

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

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

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

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

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

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

Migrating from PHP 7.4.x to PHP 8.0.x

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

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

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

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

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

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

Ядро PHP

Именованные аргументы

Добавлена поддержка именованных аргументов.

Атрибуты

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

Объявление свойств в конструкторе

Добавлена поддержка определения свойств в конструкторе (объявление свойств в сигнатуре конструктора).

Объединение типов

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

Выражение Match

Добавлена поддержка выражения match.

Оператор Nullsafe

Добавлена поддержка оператора Nullsafe (?->).

Другие новые функции

  • Добавлен класс WeakMap.

  • Добавлен класс ValueError.

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

    <?php
    class A {
         public function method(int $many, string $parameters, $here) {}
    }
    class B extends A {
         public function method(...$everything) {}
    }
    ?>
  • static (как в "позднем статическом связывании") теперь можно использовать как возвращаемый тип:

    <?php
    class Test {
         public function create(): static {
              return new static();
         }
    }
    ?>
  • Теперь можно получить имя класса объекта с помощью $object::class. Результат такой же, что и get_class($object).

  • new и instanceof теперь можно использовать с произвольными выражениями, используя new (expression)(...$args) и $obj instanceof (expression).

  • Были внесены некоторые исправления согласованности в синтаксис переменных, например, теперь разрешена запись Foo::BAR::$baz.

  • Добавлен интерфейс Stringable, который автоматически реализуется, если в классе определён метод __toString().

  • Теперь трейты могут определять абстрактные закрытые методы. Такие методы должны быть реализованы классом с помощью трейта.

  • throw теперь можно использовать как выражение. Это означает, что теперь возможно следующее:

    <?php
    $fn = fn() => throw new Exception('Исключение в стрелочной функции');
    $user = $session->user ?? throw new Exception('Должен быть пользователь');
  • В списках параметров теперь разрешена необязательная завершающая запятая.

    <?php
    function functionWithLongSignature(
        Type1 $parameter1,
        Type2 $parameter2, // <-- Эта запятая теперь разрешена.
    ) {
    }
  • Теперь можно написать catch (Exception) для перехвата исключения, не сохраняя его в переменной.

  • Добавлена поддержка типа mixed.

  • Закрытые методы, объявленные в родительском классе, больше не применяют какие-либо правила наследования для методов дочернего класса (за исключением окончательных закрытых конструкторов). В следующем примере показано, какие ограничения были сняты:

    <?php
    class ParentClass {
        private function method1() {}
        private function method2() {}
        private static function method3() {}
        // Выдаёт предупреждение, так как "final" больше не имеет значения:
        private final function method4() {}
    }
    class ChildClass extends ParentClass {
        // Теперь все следующее разрешено, хотя модификаторы не такие же,
        // как для закрытых методов в родительском классе.
        public abstract function method1() {}
        public static function method2() {}
        public function method3() {}
        public function method4() {}
    }
    ?>
  • Добавлена функция get_resource_id(), которая возвращает то же значение, что и (int) $resource. Принцип работы такой же, но с более понятным API.

  • Добавлен класс InternalIterator.

Дата и время

DOM

Добавлены DOMParentNode и DOMChildNode с новыми API-интерфейсами обхода и управления.

Фильтрация данных

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

FPM

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

Hash

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

Функции интернационализации

Добавлены константы IntlDateFormatter::RELATIVE_FULL, IntlDateFormatter::RELATIVE_LONG, IntlDateFormatter::RELATIVE_MEDIUM и IntlDateFormatter::RELATIVE_SHORT.

LDAP

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

OPcache

Если ini-параметр opcache.record_warnings включён, OPcache будет записывать предупреждения во время компиляции и воспроизводить их при следующем включении, даже если они обслуживаются из кеша.

OpenSSL

Добавлена поддержка синтаксиса криптографических сообщений (CMS) (» RFC 5652), состоящего из функций для шифрования, дешифрования, подписи, проверки и чтения. API похож на API для функций PKCS #7 с добавлением новых констант кодирования: OPENSSL_ENCODING_DER, OPENSSL_ENCODING_SMIME и OPENSSL_ENCODING_PEM:

  • openssl_cms_encrypt() шифрует сообщение в файле с сертификатами и выводит результат в предоставленный файл.
  • openssl_cms_decrypt() расшифровывает сообщение S/MIME в файле и выводит результаты в предоставленный файл.
  • openssl_cms_read() экспортирует файл CMS в массив сертификатов PEM.
  • openssl_cms_sign() подписывает сообщение MIME в файле сертификатом и ключом и выводит результат в предоставленный файл.
  • openssl_cms_verify() проверяет, что блок данных не повреждён, подписывающая сторона является тем, кем она являются и возвращает сертификаты подписывающих сторон.

Регулярные выражения (совместимые с Perl)

Добавлена функция preg_last_error_msg(), которая возвращает человекочитаемое сообщение о последней ошибке PCRE. Она дополняет preg_last_error(), которая возвращает целочисленное значение перечисления.

Reflection

SQLite3

SQLite3::setAuthorizer() и соответствующие константы классов были добавлены, с помощью которых можно задать собственную callback-функцию для авторизации или запрета действия в базе данных.

Библиотека стандартных функций

  • Добавлены функции str_contains(), str_starts_with() и str_ends_with(), которые проверяют, содержит ли haystack, начинается или заканчивается needle соответственно.

  • Добавлена функция fdiv(), которая выполняет деление с плавающей точкой в соответствии с IEEE 754. Деление на ноль строго определено и возвращает одно из значений: Inf, -Inf или NaN.

  • Добавлена функция get_debug_type(), которая возвращает тип, который может использоваться для генераций сообщений об ошибках. В отличие от gettype(), она использует канонические имена типов, возвращает имена классов объектов и сообщает о типе ресурсов.

  • printf() и её производные теперь поддерживают спецификаторы формата %h и %H. Они работают как %g и %G, но всегда используют "." в качестве десятичного разделителя, а не определяют его с помощью локали LC_NUMERIC.

  • printf() и её производные теперь поддерживают использование "*" в качестве ширины или точности, и в этом случае ширина/точность передаётся в качестве аргумента printf. Это также позволяет использовать точность -1 с %g, %G, %h и %H. Например, следующий код можно использовать для воспроизведения форматирования с плавающей точкой по умолчанию PHP:

    <?php
    printf("%.*H", (int) ini_get("precision"), $float);
    printf("%.*H", (int) ini_get("serialize_precision"), $float);
    ?>
  • proc_open() теперь поддерживает дескрипторы псевдотерминала (PTY). Следующий код присоединяет stdin, stdout и stderr к одному и тому же PTY:

    <?php
    $proc = proc_open($command, [['pty'], ['pty'], ['pty']], $pipes);
    ?>
  • proc_open() теперь поддерживает дескрипторы пары сокетов. Следующий код присоединяет отдельную пару сокетов к stdin, stdout и stderr:

    <?php
    $proc = proc_open($command, [['socket'], ['socket'], ['socket']], $pipes);
    ?>

    В отличие от каналов, у сокетов нет проблем с блокировкой ввода-вывода в Windows. Однако не все программы могут корректно работать с сокетами stdio.

  • Функции сортировки теперь используют устойчивую сортировку, это означает, что сравниваемые элементы сохранят исходный порядок.

  • array_diff(), array_intersect() и их производные теперь могут использоваться с одним массивом в качестве аргумента. Это означает, что теперь возможно следующее:

    <?php
    // Работает, даже если $excludes пуст:
    array_diff($array, ...$excludes);
    // Работает, даже если $array содержит только один массив:
    array_intersect(...$arrays);
    ?>
  • Параметр flag в функции ob_implicit_flush() был изменён, и теперь принимает логическое значение (bool), а не целое число (int).

Лексер (Tokenizer)

PhpToken добавляет объектно-ориентированный интерфейс к PHP-лексеру (tokenizer). Он обеспечивает более единообразное и эргономичное представление, в то же время эффективнее и быстрее.

Zip

  • Модуль Zip обновлён до версии 1.19.1.

  • Новые методы ZipArchive::setMtimeName() и ZipArchive::setMtimeIndex() для установки времени изменения записи.

  • Новый метод ZipArchive::registerProgressCallback() для предоставления обновлений во время закрытия архива.

  • Новый метод ZipArchive::registerCancelCallback(), чтобы разрешить отмену во время закрытия архива.

  • Новый метод ZipArchive::replaceFile() для замены содержимого записи.

  • Новый метод ZipArchive::isCompressionMethodSupported(), чтобы проверить дополнительные возможности сжатия.

  • Новый метод ZipArchive::isEncryptionMethodSupported(), чтобы проверить дополнительные функции шифрования.

  • Добавлено свойство ZipArchive::lastId для получения значения индекса последней добавленной записи.

  • Теперь ошибки можно проверить после закрытия и с помощью свойств ZipArchive::status и ZipArchive::statusSys или метода ZipArchive::getStatusString().

  • Параметр 'remove_path' в ZipArchive::addGlob() и ZipArchive::addPattern() теперь обрабатывается как произвольный строковый префикс (для согласованности с 'add_path'), тогда как раньше он интерпретировался как имя каталога.

  • Дополнительные функции сжатия/шифрования теперь перечислены в phpinfo.

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

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

PHP Core

Named Arguments

Support for Named Arguments has been added.

Attributes

Support for Attributes has been added.

Constructor Property Promotion

Support for constructor property promotion (declaring properties in the constructor signature) has been added.

Union Types

Support for union types has been added.

Match Expression

Support for match expressions has been added.

Nullsafe Operator

Support for the nullsafe operator (?->) has been added.

Other new Features

  • The WeakMap class has been added.

  • The ValueError class has been added.

  • Any number of function parameters may now be replaced by a variadic argument, as long as the types are compatible. For example, the following code is now allowed:

    <?php
    class A {
         public function method(int $many, string $parameters, $here) {}
    }
    class B extends A {
         public function method(...$everything) {}
    }
    ?>
  • static (as in "late static binding") can now be used as a return type:

    <?php
    class Test {
         public function create(): static {
              return new static();
         }
    }
    ?>
  • It is now possible to fetch the class name of an object using $object::class. The result is the same as get_class($object).

  • new and instanceof can now be used with arbitrary expressions, using new (expression)(...$args) and $obj instanceof (expression).

  • Some consistency fixes to variable syntax have been applied, for example writing Foo::BAR::$baz is now allowed.

  • Added Stringable interface, which is automatically implemented if a class defines a __toString() method.

  • Traits can now define abstract private methods. Such methods must be implemented by the class using the trait.

  • throw can now be used as an expression. That allows usages like:

    <?php
    $fn = fn() => throw new Exception('Exception in arrow function');
    $user = $session->user ?? throw new Exception('Must have user');
  • An optional trailing comma is now allowed in parameter lists.

    <?php
    function functionWithLongSignature(
        Type1 $parameter1,
        Type2 $parameter2, // <-- This comma is now allowed.
    ) {
    }
  • It is now possible to write catch (Exception) to catch an exception without storing it in a variable.

  • Support for mixed type has been added.

  • Private methods declared on a parent class no longer enforce any inheritance rules on the methods of a child class (with the exception of final private constructors). The following example illustrates which restrictions have been removed:

    <?php
    class ParentClass {
        private function method1() {}
        private function method2() {}
        private static function method3() {}
        // Throws a warning, as "final" no longer has an effect:
        private final function method4() {}
    }
    class ChildClass extends ParentClass {
        // All of the following are now allowed, even though the modifiers aren't
        // the same as for the private methods in the parent class.
        public abstract function method1() {}
        public static function method2() {}
        public function method3() {}
        public function method4() {}
    }
    ?>
  • get_resource_id() has been added, which returns the same value as (int) $resource. It provides the same functionality under a clearer API.

  • The InternalIterator has been added.

Date and Time

DOM

DOMParentNode and DOMChildNode with new traversal and manipulation APIs have been added.

Filter

FILTER_VALIDATE_BOOL has been added as an alias for FILTER_VALIDATE_BOOLEAN. The new name is preferred, as it uses the canonical type name.

FPM

Added a new option pm.status_listen that allows getting the status from different endpoint (e.g. port or UDS file) which is useful for getting the status when all children are busy with serving long running requests.

Hash

HashContext objects can now be serialized.

LDAP

ldap_count_references() has been added, which returns the number of reference messages in a search result.

OPcache

If the opcache.record_warnings ini setting is enabled, OPcache will record compile-time warnings and replay them on the next include, even if it is served from cache.

OpenSSL

Added Cryptographic Message Syntax (CMS) (» RFC 5652) support composed of functions for encryption, decryption, signing, verifying and reading. The API is similar to the API for PKCS #7 functions with an addition of new encoding constants: OPENSSL_ENCODING_DER, OPENSSL_ENCODING_SMIME and OPENSSL_ENCODING_PEM:

  • openssl_cms_encrypt() encrypts the message in the file with the certificates and outputs the result to the supplied file.
  • openssl_cms_decrypt() that decrypts the S/MIME message in the file and outputs the results to the supplied file.
  • openssl_cms_read() that exports the CMS file to an array of PEM certificates.
  • openssl_cms_sign() that signs the MIME message in the file with a cert and key and output the result to the supplied file.
  • openssl_cms_verify() that verifies that the data block is intact, the signer is who they say they are, and returns the certs of the signers.

Regular Expressions (Perl-Compatible)

preg_last_error_msg() has been added, which returns a human-readable message for the last PCRE error. It complements preg_last_error(), which returns an integer enum value instead.

SQLite3

SQLite3::setAuthorizer() and respective class constants have been added to set a userland callback that will be used to authorize or not an action on the database.

Standard Library

  • str_contains(), str_starts_with() and str_ends_with() have been added, which check whether haystack contains, starts with or ends with needle, respectively.

  • fdiv() has been added, which performs a floating-point division under IEEE 754 semantics. Division by zero is considered well-defined and will return one of Inf, -Inf or NaN.

  • get_debug_type() has been added, which returns a type useful for error messages. Unlike gettype(), it uses canonical type names, returns class names for objects, and indicates the resource type for resources.

  • printf() and friends now support the %h and %H format specifiers. These are the same as %g and %G, but always use "." as the decimal separator, rather than determining it through the LC_NUMERIC locale.

  • printf() and friends now support using "*" as width or precision, in which case the width/precision is passed as an argument to printf. This also allows using precision -1 with %g, %G, %h and %H. For example, the following code can be used to reproduce PHP's default floating point formatting:

    <?php
    printf("%.*H", (int) ini_get("precision"), $float);
    printf("%.*H", (int) ini_get("serialize_precision"), $float);
    ?>
  • proc_open() now supports pseudo-terminal (PTY) descriptors. The following attaches stdin, stdout and stderr to the same PTY:

    <?php
    $proc = proc_open($command, [['pty'], ['pty'], ['pty']], $pipes);
    ?>
  • proc_open() now supports socket pair descriptors. The following attaches a distinct socket pair to stdin, stdout and stderr:

    <?php
    $proc = proc_open($command, [['socket'], ['socket'], ['socket']], $pipes);
    ?>

    Unlike pipes, sockets do not suffer from blocking I/O issues on Windows. However, not all programs may work correctly with stdio sockets.

  • Sorting functions are now stable, which means that equal-comparing elements will retain their original order.

  • array_diff(), array_intersect() and their variations can now be used with a single array as argument. This means that usages like the following are now possible:

    <?php
    // OK even if $excludes is empty:
    array_diff($array, ...$excludes);
    // OK even if $arrays only contains a single array:
    array_intersect(...$arrays);
    ?>
  • The flag parameter of ob_implicit_flush() was changed to accept a bool rather than an int.

Tokenizer

PhpToken adds an object-based interface to the tokenizer. It provides a more uniform and ergonomic representation, while being more memory efficient and faster.

Zip

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

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

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

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

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

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

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

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

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

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

Ядро PHP

Сравнение строк с числами

Нестрогие сравнения чисел и нечисловых строк теперь работают как преобразование числа в строку с последующим сравнением строк. Сравнение чисел и числовых строк работает по прежним правилам. Поэтому сравнение наподобие 0 == "not-a-number" теперь выдаст false.

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

Другие изменения, которые ломают обратную совместимость

  • Слово match стало зарезервированным ключевым словом.

  • Слово mixed стало зарезервированным, поэтому его нельзя указывать как название класса, интерфейса или трейта, и в пространствах имён.

  • Ошибки утверждений теперь выбрасываются по умолчанию. Старое поведение устанавливается в INI-настройке assert.exception=0.

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

  • Нестатические методы теперь нельзя вызывать статически, поэтому функция is_callable() завершится ошибкой при проверке нестатического метода с названием класса, доступность вызова необходимо проверять с экземпляром объекта.

  • Приведения типов (real) и (unset) удалили.

  • INI-директиву track_errors удалили. Это означает, что php_errormsg больше не актуален. Вместо него пользуются функцией error_get_last().

  • Больше нельзя определять константы без учёта регистра. Больше нельзя устанавливать для третьего параметра функции define() значение true.

  • Больше нельзя указывать автозагрузчик через функцию __autoload(). Вместо этого рекомендуют пользоваться функцией spl_autoload_register().

  • Аргумент errcontext больше не передаётся в пользовательские обработчики ошибок, которые задали функцией set_error_handler().

  • Функцию create_function() удалили. Вместо неё пользуются анонимными функцииями.

  • Функцию each() удалили. Вместо неё пользуются конструкцией foreach или классом ArrayIterator.

  • Больше нельзя отвязать переменную this от замыканий, которые создали из методов Closure::fromCallable() или ReflectionMethod::getClosure().

  • Больше нельзя отвязать переменную this от правильных замыканий, которые содержат this.

  • Функцию array_key_exists() больше нельзя вызывать с объектами. Вместо этого можно использовать isset() или property_exists().

  • Работа параметра key в функции array_key_exists() теперь приведена в соответствии с isset() и обычным доступом к массиву. Все типы ключей теперь используют обычное приведение типов, массив/объект к ключе приведёт к выбрасыванию TypeError.

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

  • Уровень error_reporting по умолчанию теперь E_ALL. Ранее он исключал E_NOTICE и E_DEPRECATED.

  • display_startup_errors теперь включён по умолчанию.

  • Использование parent внутри класса, у которого нет родителя, теперь приведёт к фатальной ошибке во время компиляции.

  • Оператор @ больше не подавляет фатальные ошибки (E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR, E_RECOVERABLE_ERROR, E_PARSE). Обработчики ошибок, которые ожидают, что error_reporting будет иметь значение 0 при использовании оператора @, должны делать такие проверки через битовую маску:

    <?php
    // Замените это
    function my_error_handler($err_no, $err_msg, $filename, $linenum) {
        if (error_reporting() == 0) {
            return false;
        }
        // ...
    }
    
    // На это
    function my_error_handler($err_no, $err_msg, $filename, $linenum) {
        if (!(error_reporting() & $err_no)) {
            return false;
        }
        // ...
    }
    ?>

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

  • #[ больше не интерпретируется как начало комментария, так как этот синтаксис теперь используется для атрибутов.

  • Ошибки наследования из-за несовместимых сигнатур методов (нарушения LSP) теперь всегда вызывают фатальную ошибку. Ранее в некоторых случаях выдавалось предупреждение.

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

    <?php
    echo "Сумма: " . $a + $b;
    // ранее интерпретировалось как:
    echo ("Сумма: " . $a) + $b;
    // сейчас интерпретируется как:
    echo "Сумма:" . ($a + $b);
    ?>
  • Аргументы со значением по умолчанию, которое разрешается в null во время выполнения, больше не будут неявно помечать тип аргумента как nullable. Вместо этого нужно указывать либо явный тип, разрешающий значение null, либо явное значение null по умолчанию.

    <?php
    // Замените этот код:
    function test(int $arg = CONST_RESOLVING_TO_NULL) {}
    // На этот:
    function test(?int $arg = CONST_RESOLVING_TO_NULL) {}
    // На этот (альтернативный вариант):
    function test(int $arg = null) {}
    ?>
  • Ряд предупреждений преобразован в исключения Error:

    • Попытка записи в свойство несуществующего объекта. Ранее это неявно создавало объект stdClass в случае null, false и пустых строк.
    • Попытка добавить элемент в массив, для которого уже используется ключ PHP_INT_MAX.
    • Попытка использовать недопустимый тип (массив или объект) в качестве ключа массива или смещения строки.
    • Попытка записать в индекс массива скалярное значение.
    • Попытка распаковать значение, не являющее массивом/Traversable.
    • Попытка получить доступ к неквалифицированным константам, которые не определены. Ранее неквалифицированный доступ к константам приводил к предупреждению и интерпретировался как строка.
    • Передача неверного количества аргументов в невариативную встроенную функцию приведёт к исключению ArgumentCountError.
    • Передача недопустимых исчисляемых типов в функцию count() выбросит исключение TypeError.

    Ряд уведомлений преобразован в предупреждения:

    • Попытка прочитать неопределённую переменную.
    • Попытка прочитать неопределённое свойство.
    • Попытка прочитать неопределённый ключ массива.
    • Попытка прочитать свойство не-объекта.
    • Попытка получить доступ к индексу массива не-массива.
    • Попытка преобразовать массив в строку.
    • Попытка использовать ресурс в качестве ключа массива.
    • Попытка использовать null, логическое значение или число с плавающей точкой в качестве строкового смещения.
    • Попытка прочитать смещение строки за пределами допустимой границы.
    • Попытка присвоить смещению строки пустую строку.
  • При попытке назначить несколько байтов смещению строки теперь будет выдано предупреждение.

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

  • Неперехваченные исключения теперь проходят процедуру "чистого завершения", это означает, что после неперехваченного исключения будут вызываться деструкторы.

  • Фатальная ошибка времени компиляции "Only variables can be passed by reference" была отложена до времени выполнения и преобразована в исключение Error "Argument cannot be passed by reference".

  • Некоторые уведомления "Only variables can be passed by reference" были преобразованы в исключение "Argument cannot be passed by reference".

  • Сгенерированное имя для анонимных классов изменилось. Теперь он будет включать имя первого родителя или интерфейса:

    <?php
    new class extends ParentClass {};
    // -> ParentClass@anonymous
    new class implements FirstInterface, SecondInterface {};
    // -> FirstInterface@anonymous
    new class {};
    // -> class@anonymous
    ?>

    За новыми именами по-прежнему будет следовать NUL-байт и уникальный суффикс.

  • Ссылки на неабсолютные трейты методов в адаптациях псевдонимов трейтов теперь должны быть однозначными:

    <?php
    class X {
        use T1, T2 {
            func as otherFunc;
        }
        function func() {}
    }
    ?>

    Если существуют и T1::func(), и T2::func(), этот код ранее принимался без уведомления, и предполагалось, что func ссылается на T1::func. Теперь вместо этого будет выброшена фатальная ошибка: необходимо явно указать T1::func или T2::func.

  • Сигнатура абстрактных методов, определённых в трейтах, теперь проверяется по методу реализующего класса:

    <?php
    trait MyTrait {
        abstract private function neededByTrait(): string;
    }
    
    class MyClass {
        use MyTrait;
    
        // Ошибка из-за несоответствия типа возвращаемого значения.
        private function neededByTrait(): int { return 42; }
    }
    ?>
  • Отключённые функции теперь обрабатываются точно так же, как несуществующие функции. Вызов отключённой функции сообщит, что нет такой функции, это даёт возможность переопределить отключённую функцию.

  • Оболочки потока data:// больше не доступны для записи, что соответствует документированному поведению.

  • Арифметические и побитовые операторы +, -, *, /, **, %, <<, >>, &, |, ^, ~, ++, -- теперь будут последовательно выдавать TypeError, когда одним из операндов является массив (array), ресурс (resource) или не перегруженный объект (object). Единственным исключением из этого правила является операция слияния массивов +, которая по-прежнему поддерживается.

  • Приведение с плавающей точкой в строку теперь всегда будет вести себя независимо от локали.

    <?php
    setlocale(LC_ALL, "de_DE");
    // Ранее:  3,14
    // Теперь: 3.14
    ?>

    Смотрите printf(), number_format() и NumberFormatter() для получения информации о способах настройки форматирования чисел.

  • Удалена поддержка устаревших фигурных скобок для доступа к смещению.

    <?php
    // Вместо:
    $array{0};
    $array{"key"};
    // Используйте:
    $array[0];
    $array["key"];
    ?>
  • Применение модификатора final к закрытому методу теперь приведёт к предупреждению, если этот метод не является конструктором.

  • Если в конструкторе объекта используется exit(), то деструктор объекта больше не будет вызываться. Это соответствует поведению, когда конструктор выбрасывает исключение.

  • Именам в пространстве имён больше нельзя содержать пробелы: имя Foo\Bar будет распознаваться как имя в пространстве имён, Foo \ Bar — нет. И наоборот, зарезервированные ключевые слова теперь разрешены в качестве сегментов пространства имён, что также может изменить интерпретацию кода: new\x теперь совпадает с constant('new\x'), но не с new \x().

  • Для вложенных тернарных операторов теперь требуется явное указание скобок.

  • debug_backtrace() и Exception::getTrace() больше не будут предоставлять ссылки на аргументы. Невозможно изменить аргументы функции через трассировку.

  • Обработка числовых строк была изменена, чтобы сделать её более понятной и менее подверженной ошибкам. Завершающие пробелы теперь разрешены в числовых строках для согласованности с тем, как обрабатываются начальные пробелы. В основном это влияет на:

    • Функцию is_numeric()
    • Сравнение строк со строками
    • Объявления типов
    • Операции увеличения и уменьшения

    Понятие "ведущая числовая строка" в основном было отброшено; случаи, когда это осталось, существуют для облегчения миграции. Строки, которые выдавали E_NOTICE "A non well-formed numeric value encountered", теперь будут выдавать E_WARNING "A non-numeric value encountered", а все строки, которые выдавали E_WARNING "A non-numeric value encountered" теперь будет выдавать TypeError. В основном это влияет на:

    • Арифметические операции
    • Побитовые операции

    Это изменение E_WARNING на TypeError также влияет на E_WARNING "Illegal string offset 'string'" для недопустимых смещений строки. Поведение явных приведений к int/float из строк не изменилось.

  • Теперь у магических методов будут проверяться аргументы и возвращаемые типы, если они объявлены. Сигнатура должна соответствовать следующему списку:

    • __call(string $name, array $arguments): mixed
    • __callStatic(string $name, array $arguments): mixed
    • __clone(): void
    • __debugInfo(): ?array
    • __get(string $name): mixed
    • __invoke(mixed $arguments): mixed
    • __isset(string $name): bool
    • __serialize(): array
    • __set(string $name, mixed $value): void
    • __set_state(array $properties): object
    • __sleep(): array
    • __unserialize(array $data): void
    • __unset(string $name): void
    • __wakeup(): void
  • Ключи массива call_user_func_array() теперь будут интерпретироваться как имена параметров, а не игнорироваться.

  • Объявление функции с именем assert() внутри пространства имён больше не допускается и вызывает E_COMPILE_ERROR. Функция assert() подвергается специальной обработке со стороны движка, что может привести к несогласованному поведению при определении одноимённой функции в пространстве имён.

Преобразование ресурсов в объекты

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

COM и .Net (Windows)

Возможность импорта констант без учёта регистра из библиотек типов была удалена. Второй аргумент com_load_typelib() больше не может быть false; com.autoregister_casesensitive больше нельзя отключить; Маркеры без учёта регистра в com.typelib_file игнорируются.

CURL

CURLOPT_POSTFIELDS больше не принимает объекты как массивы. Чтобы интерпретировать объект как массив, выполните явное приведение (array). То же самое относится и к другим параметрам, принимающим массивы.

Дата и время

Для работы функций mktime() и gmmktime() теперь требуется хотя бы один аргумент. time() может использоваться для получения текущей отметки времени.

DOM

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

  • DOMNameList
  • DomImplementationList
  • DOMConfiguration
  • DomError
  • DomErrorHandler
  • DOMImplementationSource
  • DOMLocator
  • DOMUserDataHandler
  • DOMTypeInfo
  • DOMStringExtend

Удалены нереализованные методы модуля DOM, у которых не было реализации:

  • DOMNamedNodeMap::setNamedItem()
  • DOMNamedNodeMap::removeNamedItem()
  • DOMNamedNodeMap::setNamedItemNS()
  • DOMNamedNodeMap::removeNamedItemNS()
  • DOMText::replaceWholeText()
  • DOMNode::compareDocumentPosition()
  • DOMNode::isEqualNode()
  • DOMNode::getFeature()
  • DOMNode::setUserData()
  • DOMNode::getUserData()
  • DOMDocument::renameNode()

Enchant

Exif

read_exif_data() была удалена; Вместо неё следует использовать exif_read_data().

Фильтрация данных

GD

  • Устаревшие функции image2wbmp() были удалены.

  • Устаревшие функции png2wbmp() и jpeg2wbmp() были удалены.

  • Параметр mode по умолчанию для функции imagecropauto() больше не принимает значение -1. Вместо этого следует использовать IMG_CROP_DEFAULT.

  • В Windows, php_gd2.dll переименован в php_gd.dll.

GMP

gmp_random() была удалена. Вместо неё следует использовать gmp_random_range() или gmp_random_bits().

Iconv

Реализации iconv, которые неправильно устанавливают errno в случае возникновения ошибок, больше не поддерживаются.

IMAP

  • Неиспользуемый аргумент default_host функции imap_headerinfo() был удалён.

  • Функция imap_header(), которая является псевдонимом imap_headerinfo(), была удалена.

Функции интернационализации

  • Устаревшая константа INTL_IDNA_VARIANT_2003 удалена.

  • Устаревшая константа Normalizer::NONE удалена.

LDAP

MBString

  • Директива mbstring.func_overload была удалена. Связанные константы MB_OVERLOAD_MAIL, MB_OVERLOAD_STRING и MB_OVERLOAD_REGEX также были удалены. Наконец, записи "func_overload" и "func_overload_list" в mb_get_info() были удалены.

  • mb_parse_str() больше нельзя использовать без передачи массива результатов.

  • Удалён ряд устаревших псевдонимов mbregex. В следующем списке указано, какие функции следует использовать вместо них:

  • Модификатор e для mb_ereg_replace() был удалён. Вместо него следует использоватьmb_ereg_replace_callback().

  • Аргумент нестрокового шаблона для mb_ereg_replace() теперь будет интерпретироваться как строка вместо кодовой точки ASCII. Предыдущее поведение можно восстановить явным вызовом chr().

  • Аргумент needle для функций mb_strpos(), mb_strrpos(), mb_stripos(), mb_strripos(), mb_strstr(), mb_stristr(), mb_strrchr() и mb_strrichr() теперь может быть пустым.

  • Параметр is_hex, который не использовался для внутренних целей, был удалён из mb_decode_numericentity().

  • Устаревшее поведение передачи кодировки в качестве третьего аргумента вместо смещения для функции mb_strrpos() было удалено; вместо этого в качестве четвёртого аргумента следует указать явное смещение 0 с кодировкой.

  • Псевдонимы кодировки символов ISO_8859-* были заменены на псевдонимы ISO8859-* для лучшей совместимости с модулем iconv. Псевдонимы mbregex ISO 8859 с подчёркиванием (ISO_8859_* и ISO8859_*) также были удалены.

  • mb_ereg() и mb_eregi() теперь будут возвращать логическое значение true, в случае найденного совпадения. Ранее они возвращали целое число 1, если аргумент matches не был передан, или max(1, strlen($matches[0])), если matches был не пустой.

OCI8

  • Класс OCI-Lob переименован в OCILob, а класс OCI-Collection — в OCICollection для имени совместимость обеспечивается средствами аннотации типа arginfo PHP 8.

  • Некоторые функции псевдонимов объявлены устаревшим.

  • oci_internal_debug() и её псевдоним ociinternaldebug() были удалены.

ODBC

  • odbc_connect() больше не использует соединения повторно.

  • Неиспользуемый параметр flags функции odbc_exec() был удалён.

OpenSSL

  • openssl_seal() и openssl_open() теперь требуют передачи method, так как предыдущее значение по умолчанию "RC4" считается небезопасным.

Регулярные выражения (совместимые с Perl)

При передаче недопустимых управляющих последовательностей они больше не интерпретируются как литералы. Такое поведение ранее требовало модификатора X, который теперь игнорируется.

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

  • Режим обработки ошибок по умолчанию был изменён с "тихого" (silent) на "исключения" (exceptions). Подробнее смотрите Ошибки и обработка ошибок.

  • Изменились сигнатуры некоторых методов PDO:

PDO ODBC

Директива php.inipdo_odbc.db2_instance_name была удалена.

PDO MySQL

PDO::inTransaction() теперь сообщает о фактическом состоянии транзакции подключения, а не о приблизительном от PDO. Если запрос, при условии "неявной фиксации", выполняется, то PDO::inTransaction() впоследствии вернёт false, так как транзакция будет неактивной.

PostgreSQL

  • Устаревший синтаксис pg_connect() с использованием нескольких параметров вместо строки подключения больше не поддерживается.

  • Устаревшие сигнатуры pg_lo_import() и pg_lo_export(), передающие соединение в качестве последнего аргумента, больше не поддерживаются. Вместо этого соединение должно быть передано первым аргументом.

  • pg_fetch_all() теперь будет возвращать пустой массив вместо false для наборов результатов с отсутствующими строками.

Phar

Метаданные, связанные с phar, больше не будут автоматически десериализоваться, чтобы исправить потенциальные уязвимости безопасности из-за создания экземпляров объекта, автозагрузки и т. д.

Reflection

  • Сигнатуры методов

    были изменены на:

    • ReflectionClass::newInstance(...$args)
    • ReflectionFunction::invoke(...$args)
    • ReflectionMethod::invoke($object, ...$args)

    Код, который должен быть совместим как с PHP 7, так и с PHP 8, может использовать следующие сигнатуры:

    • ReflectionClass::newInstance($arg = null, ...$args)
    • ReflectionFunction::invoke($arg = null, ...$args)
    • ReflectionMethod::invoke($object, $arg = null, ...$args)
  • Метод ReflectionType::__toString() теперь будет возвращать полное отладочное представление типа и больше не является устаревшим. В частности, результат будет включать индикатор допустимости значений NULL для типов, допускающих значение NULL. Формат возвращаемого значения нестабилен и может меняться в зависимости от версии PHP.

  • Методы Reflection export() были удалены. Вместо этого объекты reflection могут быть преобразованы в строку.

  • ReflectionMethod::isConstructor() и ReflectionMethod::isDestructor() теперь также возвращают true для методов интерфейсов __construct() и __destruct(). Раньше это было верно только для методов классов и трейтов.

  • Метод ReflectionType::isBuiltin() перемещён в ReflectionNamedType. У ReflectionUnionType этого метода нет.

Сокеты

  • Устаревшие flagsAI_IDN_ALLOW_UNASSIGNED и AI_IDN_USE_STD3_ASCII_RULES для socket_addrinfo_lookup() были удалены.

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

Библиотека стандартных функций

  • assert() больше не будет выполнять строковые аргументы, вместо этого они будут обрабатываться как любые обычные аргументы. Таким образом, вместо assert('$a == $b') следует использовать assert($a == $b). INI-директива assert.quiet_eval и константа ASSERT_QUIET_EVAL были удалены, так как они больше не имеют смысла.

  • parse_str() больше нельзя использовать без указания массива результатов.

  • Фильтр string.strip_tags удалён.

  • Аргумент needle функций strpos(), strrpos(), stripos(), strripos(), strstr(), strchr(), strrchr() и stristr() теперь всегда будет интерпретироваться как строка. Раньше нестрочные needles интерпретировались как кодовая точка ASCII. Явный вызов chr() может использоваться для восстановления предыдущего поведения.

  • Аргумент needle функций strpos(), strrpos(), stripos(), strripos(), strstr(), stristr() и strrchr() теперь может быть пустым.

  • Аргумент length функций substr(), substr_count(), substr_compare() и iconv_substr() теперь может быть null. Значения null означает отсутствие аргумента длины, и поэтому функции вернут остаток строки вместо пустой строки.

  • Аргумент length функции array_splice() теперь может быть null. Передача значения null означает отсутствие аргумента, поэтому функция удалить все, начиная от offset до конца массива.

  • Аргумент args функций vsprintf(), vfprintf() и vprintf() теперь должен быть массивом. Раньше принимался любой тип.

  • Параметр 'salt' функции password_hash() больше не поддерживается. Если используется опция 'salt', генерируется предупреждение, переданная соль игнорируется, а вместо неё используется сгенерированная соль.

  • Функция quotemeta() теперь будет возвращать пустую строку, если была передана пустая строка. Ранее возвращалось false.

  • Удалены следующие функции:

  • FILTER_SANITIZE_MAGIC_QUOTES удалена.

  • Вызов implode() с параметрами в обратном порядке ($pieces, $glue) больше не поддерживается.

  • parse_url() теперь будет различать отсутствующие и пустые запросы и фрагменты:

    • http://example.com/foo → query = null, fragment = null
    • http://example.com/foo? → query = "", fragment = null
    • http://example.com/foo# → query = null, fragment = ""
    • http://example.com/foo?# → query = "", fragment = ""
    Ранее во всех случаях query и fragment были null.
  • var_dump() и debug_zval_dump() теперь будут печатать числа с плавающей точкой, используя serialize_precision, а не precision. В конфигурации по умолчанию это означает, что числа с плавающей точкой теперь печатаются с полной точностью этими функциями отладки.

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

  • Локаль по умолчанию при запуске теперь всегда будет определена как "C". По умолчанию локали не наследуются из окружения. Ранее для LC_ALL было задано значение "C", в то время как LC_CTYPE наследовался от окружения. Однако некоторые функции не учитывали унаследованную локаль без явного вызова setlocale(). Явный вызов setlocale() теперь требуется всегда, если компонент локали должен быть изменён с значения по умолчанию.

  • Устаревший резервный вариант DES в crypt() был удалён. Если в crypt() передаётся неизвестный формат соли, функция завершится ошибкой с *0 вместо возврата к слабому хешу DES.

  • При указании значений вне допустимого диапазона для SHA256/SHA512 crypt() теперь будет выдана ошибка *0 вместо ограничения до ближайшего предела. Это соответствует поведению glibc.

  • Результат функций сортировки мог измениться, если в массиве есть одинаковые элементы.

  • Любые функции, принимающие callback-функции, которые явно не указаны для приёма параметров по ссылке, теперь будут предупреждать, если используется callback-функция со ссылочными параметрами. Например, array_filter() и array_reduce(). Ранее так было у большинства функций, но не у всех.

  • Обёртка HTTP-потока, используемая такими функциями, как file_get_contents(), теперь по умолчанию объявляет HTTP/1.1, а не HTTP/1.0. Это не меняет поведения клиента, но может заставить серверы реагировать по-другому. Чтобы сохранить старое поведение, установите параметр контекста потока 'protocol_version', например:

    <?php
    $ctx = stream_context_create(['http' => ['protocol_version' => '1.0']]);
    echo file_get_contents('http://example.org', false, $ctx);
    ?>
  • Вызов crypt() без явной передачи соли больше не поддерживается. Если вы хотите создать надёжный хеш с автоматически сгенерированной солью, используйте вместо этого password_hash().

  • substr(), mb_substr(), iconv_substr() и grapheme_substr() теперь последовательно фиксируют смещения за пределы границы строки. Ранее, в некоторых случаях, вместо пустой строки возвращался false.

  • В Windows функции выполнения программ (proc_open(), exec(), popen() и т. д.) с использованием оболочки теперь последовательно выполняют %comspec% /s /c "$commandline", которая делает то же самое, что и выполнение $commandline (без дополнительных кавычек).

Sysvsem

  • Параметр auto_release в sem_get() был изменён, чтобы принимать логические значения (bool), а не целые числа (int).

Tidy

PHP-лексер (Tokenizer)

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

  • Имена пространств имён теперь представлены через лексемы T_NAME_QUALIFIED (Foo\Bar), T_NAME_FULLY_QUALIFIED (\Foo\Bar) и T_NAME_RELATIVE (namespace\Foo\Bar). PHP-лексер использует лексему T_NS_SEPARATOR только для автономных разделителей пространства имён и лексема синтаксически действительна только в сочетании с объявлениями группового использования.

XMLReader

Методы XMLReader::open() и XMLReader::XML() стали статическими. Методы по-прежнему разрешается вызывать как методы экземпляра, но в классах-наследниках потребуется объявить методы статическими, если в дочернем классе они переопределяют методы родительского класса.

XML-RPC

Модуль XML-RPC был перемещён в PECL и больше не является частью дистрибутива PHP.

Zip

ZipArchive::OPSYS_Z_CPM была удалена (в этом имени была опечатка). Используйте вместо неё ZipArchive::OPSYS_CPM.

Zlib

Пакеты тестов PHP для Windows

Скрипт выполнения тестов был переименован из run-test.php в run-tests.php, чтобы соответствовать его имени в php-src.

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

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

PHP Core

String to Number Comparison

Non-strict comparisons between numbers and non-numeric strings now work by casting the number to string and comparing the strings. Comparisons between numbers and numeric strings continue to work as before. Notably, this means that 0 == "not-a-number" is considered false now.

ComparisonBeforeAfter
0 == "0"truetrue
0 == "0.0"truetrue
0 == "foo"truefalse
0 == ""truefalse
42 == " 42"truetrue
42 == "42foo"truefalse

Other incompatible Changes

  • match is now a reserved keyword.

  • mixed 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.

  • Assertion failures now throw by default. If the old behavior is desired, assert.exception=0 can be set in the INI settings.

  • Methods with the same name as the class are no longer interpreted as constructors. The __construct() method should be used instead.

  • The ability to call non-static methods statically has been removed. Thus is_callable() will fail when checking for a non-static method with a classname (must check with an object instance).

  • The (real) and (unset) casts have been removed.

  • The track_errors ini directive has been removed. This means that php_errormsg is no longer available. The error_get_last() function may be used instead.

  • The ability to define case-insensitive constants has been removed. The third argument to define() may no longer be true.

  • The ability to specify an autoloader using an __autoload() function has been removed. spl_autoload_register() should be used instead.

  • The errcontext argument will no longer be passed to custom error handlers set with set_error_handler().

  • create_function() has been removed. Anonymous functions may be used instead.

  • each() has been removed. foreach or ArrayIterator should be used instead.

  • The ability to unbind this from closures that were created from a method, using Closure::fromCallable() or ReflectionMethod::getClosure(), has been removed.

  • The ability to unbind this from proper closures that contain uses of this has also been removed.

  • The ability to use array_key_exists() with objects has been removed. isset() or property_exists() may be used instead.

  • The behavior of array_key_exists() regarding the type of the key parameter has been made consistent with isset() and normal array access. All key types now use the usual coercions and array/object keys throw a TypeError.

  • Any array that has a number n as its first numeric key will use n+1 for its next implicit key, even if n is negative.

  • The default error_reporting level is now E_ALL. Previously it excluded E_NOTICE and E_DEPRECATED.

  • display_startup_errors is now enabled by default.

  • Using parent inside a class that has no parent will now result in a fatal compile-time error.

  • The @ operator will no longer silence fatal errors (E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR, E_RECOVERABLE_ERROR, E_PARSE). Error handlers that expect error_reporting to be 0 when @ is used, should be adjusted to use a mask check instead:

    <?php
    // Replace
    function my_error_handler($err_no, $err_msg, $filename, $linenum) {
        if (error_reporting() == 0) {
            return false;
        }
        // ...
    }
    
    // With
    function my_error_handler($err_no, $err_msg, $filename, $linenum) {
        if (!(error_reporting() & $err_no)) {
            return false;
        }
        // ...
    }
    ?>

    Additionally, care should be taken that error messages are not displayed in production environments, which can result in information leaks. Please ensure that display_errors=Off is used in conjunction with error logging.

  • #[ is no longer interpreted as the start of a comment, as this syntax is now used for attributes.

  • Inheritance errors due to incompatible method signatures (LSP violations) will now always generate a fatal error. Previously a warning was generated in some cases.

  • The precedence of the concatenation operator has changed relative to bitshifts and addition as well as subtraction.

    <?php
    echo "Sum: " . $a + $b;
    // was previously interpreted as:
    echo ("Sum: " . $a) + $b;
    // is now interpreted as:
    echo "Sum:" . ($a + $b);
    ?>
  • Arguments with a default value that resolves to null at runtime will no longer implicitly mark the argument type as nullable. Either an explicit nullable type, or an explicit null default value has to be used instead.

    <?php
    // Replace
    function test(int $arg = CONST_RESOLVING_TO_NULL) {}
    // With
    function test(?int $arg = CONST_RESOLVING_TO_NULL) {}
    // Or
    function test(int $arg = null) {}
    ?>
  • A number of warnings have been converted into Error exceptions:

    • Attempting to write to a property of a non-object. Previously this implicitly created an stdClass object for null, false and empty strings.
    • Attempting to append an element to an array for which the PHP_INT_MAX key is already used.
    • Attempting to use an invalid type (array or object) as an array key or string offset.
    • Attempting to write to an array index of a scalar value.
    • Attempting to unpack a non-array/Traversable.
    • Attempting to access unqualified constants which are undefined. Previously, unqualified constant accesses resulted in a warning and were interpreted as strings.
    • Passing the wrong number of arguments to a non-variadic built-in function will throw an ArgumentCountError.
    • Passing invalid countable types to count() will throw a TypeError.

    A number of notices have been converted into warnings:

    • Attempting to read an undefined variable.
    • Attempting to read an undefined property.
    • Attempting to read an undefined array key.
    • Attempting to read a property of a non-object.
    • Attempting to access an array index of a non-array.
    • Attempting to convert an array to string.
    • Attempting to use a resource as an array key.
    • Attempting to use null, a boolean, or a float as a string offset.
    • Attempting to read an out-of-bounds string offset.
    • Attempting to assign an empty string to a string offset.
  • Attempting to assign multiple bytes to a string offset will now emit a warning.

  • Unexpected characters in source files (such as NUL bytes outside of strings) will now result in a ParseError exception instead of a compile warning.

  • Uncaught exceptions now go through "clean shutdown", which means that destructors will be called after an uncaught exception.

  • The compile time fatal error "Only variables can be passed by reference" has been delayed until runtime, and converted into an "Argument cannot be passed by reference" Error exception.

  • Some "Only variables should be passed by reference" notices have been converted to "Argument cannot be passed by reference" exception.

  • The generated name for anonymous classes has changed. It will now include the name of the first parent or interface:

    <?php
    new class extends ParentClass {};
    // -> ParentClass@anonymous
    new class implements FirstInterface, SecondInterface {};
    // -> FirstInterface@anonymous
    new class {};
    // -> class@anonymous
    ?>

    The name shown above is still followed by a NUL byte and a unique suffix.

  • Non-absolute trait method references in trait alias adaptations are now required to be unambiguous:

    <?php
    class X {
        use T1, T2 {
            func as otherFunc;
        }
        function func() {}
    }
    ?>

    If both T1::func() and T2::func() exist, this code was previously silently accepted, and func was assumed to refer to T1::func. Now it will generate a fatal error instead, and either T1::func or T2::func needs to be written explicitly.

  • The signature of abstract methods defined in traits is now checked against the implementing class method:

    <?php
    trait MyTrait {
        abstract private function neededByTrait(): string;
    }
    
    class MyClass {
        use MyTrait;
    
        // Error, because of return type mismatch.
        private function neededByTrait(): int { return 42; }
    }
    ?>
  • Disabled functions are now treated exactly like non-existent functions. Calling a disabled function will report it as unknown, and redefining a disabled function is now possible.

  • data:// stream wrappers are no longer writable, which matches the documented behavior.

  • The arithmetic and bitwise operators +, -, *, /, **, %, <<, >>, &, |, ^, ~, ++, -- will now consistently throw a TypeError when one of the operands is an array, resource or non-overloaded object. The only exception to this is the array + array merge operation, which remains supported.

  • Float to string casting will now always behave locale-independently.

    <?php
    setlocale(LC_ALL, "de_DE");
    $f = 3.14;
    echo $f, "\n";
    // Previously: 3,14
    // Now:        3.14
    ?>

    See printf(), number_format() and NumberFormatter() for ways to customize number formatting.

  • Support for deprecated curly braces for offset access has been removed.

    <?php
    // Instead of:
    $array{0};
    $array{"key"};
    // Write:
    $array[0];
    $array["key"];
    ?>
  • Applying the final modifier on a private method will now produce a warning unless that method is the constructor.

  • If an object constructor exit()s, the object destructor will no longer be called. This matches the behavior when the constructor throws.

  • Namespaced names can no longer contain whitespace: While Foo\Bar will be recognized as a namespaced name, Foo \ Bar will not. Conversely, reserved keywords are now permitted as namespace segments, which may also change the interpretation of code: new\x is now the same as constant('new\x'), not new \x().

  • Nested ternaries now require explicit parentheses.

  • debug_backtrace() and Exception::getTrace() will no longer provide references to arguments. It will not be possible to change function arguments through the backtrace.

  • Numeric string handling has been altered to be more intuitive and less error-prone. Trailing whitespace is now allowed in numeric strings for consistency with how leading whitespace is treated. This mostly affects:

    • The is_numeric() function
    • String-to-string comparisons
    • Type declarations
    • Increment and decrement operations

    The concept of a "leading-numeric string" has been mostly dropped; the cases where this remains exist in order to ease migration. Strings which emitted an E_NOTICE "A non well-formed numeric value encountered" will now emit an E_WARNING "A non-numeric value encountered" and all strings which emitted an E_WARNING "A non-numeric value encountered" will now throw a TypeError. This mostly affects:

    • Arithmetic operations
    • Bitwise operations

    This E_WARNING to TypeError change also affects the E_WARNING "Illegal string offset 'string'" for illegal string offsets. The behavior of explicit casts to int/float from strings has not been changed.

  • Magic Methods will now have their arguments and return types checked if they have them declared. The signatures should match the following list:

    • __call(string $name, array $arguments): mixed
    • __callStatic(string $name, array $arguments): mixed
    • __clone(): void
    • __debugInfo(): ?array
    • __get(string $name): mixed
    • __invoke(mixed $arguments): mixed
    • __isset(string $name): bool
    • __serialize(): array
    • __set(string $name, mixed $value): void
    • __set_state(array $properties): object
    • __sleep(): array
    • __unserialize(array $data): void
    • __unset(string $name): void
    • __wakeup(): void
  • call_user_func_array() array keys will now be interpreted as parameter names, instead of being silently ignored.

  • Declaring a function called assert() inside a namespace is no longer allowed, and issues E_COMPILE_ERROR. The assert() function is subject to special handling by the engine, which may lead to inconsistent behavior when defining a namespaced function with the same name.

Resource to Object Migration

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

COM and .Net (Windows)

The ability to import case-insensitive constants from type libraries has been removed. The second argument to com_load_typelib() may no longer be false; com.autoregister_casesensitive may no longer be disabled; case-insensitive markers in com.typelib_file are ignored.

CURL

CURLOPT_POSTFIELDS no longer accepts objects as arrays. To interpret an object as an array, perform an explicit (array) cast. The same applies to other options accepting arrays as well.

Date and Time

mktime() and gmmktime() now require at least one argument. time() can be used to get the current timestamp.

DOM

Unimplemented classes from the DOM extension that had no behavior and contained test data have been removed. These classes have also been removed in the latest version of the DOM standard:

  • DOMNameList
  • DomImplementationList
  • DOMConfiguration
  • DomError
  • DomErrorHandler
  • DOMImplementationSource
  • DOMLocator
  • DOMUserDataHandler
  • DOMTypeInfo
  • DOMStringExtend

Unimplemented methods from the DOM extension that had no behavior have been removed:

  • DOMNamedNodeMap::setNamedItem()
  • DOMNamedNodeMap::removeNamedItem()
  • DOMNamedNodeMap::setNamedItemNS()
  • DOMNamedNodeMap::removeNamedItemNS()
  • DOMText::replaceWholeText()
  • DOMNode::compareDocumentPosition()
  • DOMNode::isEqualNode()
  • DOMNode::getFeature()
  • DOMNode::setUserData()
  • DOMNode::getUserData()
  • DOMDocument::renameNode()

Enchant

Exif

read_exif_data() has been removed; exif_read_data() should be used instead.

Filter

GD

GMP

gmp_random() has been removed. One of gmp_random_range() or gmp_random_bits() should be used instead.

Iconv

iconv implementations which do not properly set errno in case of errors are no longer supported.

IMAP

Internationalization Functions

  • The deprecated constant INTL_IDNA_VARIANT_2003 has been removed.

  • The deprecated Normalizer::NONE constant has been removed.

LDAP

MBString

OCI8

  • The OCI-Lob class is now called OCILob, and the OCI-Collection class is now called OCICollection for name compliance enforced by PHP 8 arginfo type annotation tooling.

  • Several alias functions have been marked as deprecated.

  • oci_internal_debug() and its alias ociinternaldebug() have been removed.

ODBC

OpenSSL

Regular Expressions (Perl-Compatible)

When passing invalid escape sequences they are no longer interpreted as literals. This behavior previously required the X modifier – which is now ignored.

PHP Data Objects

  • The default error handling mode has been changed from "silent" to "exceptions". See Errors and error handling for details.

  • The signatures of some PDO methods have changed:

    • PDO::query(string $query, ?int $fetchMode = null, mixed ...$fetchModeArgs)
    • PDOStatement::setFetchMode(int $mode, mixed ...$args)

PDO ODBC

The php.ini directive pdo_odbc.db2_instance_name has been removed.

PDO MySQL

PDO::inTransaction() now reports the actual transaction state of the connection, rather than an approximation maintained by PDO. If a query that is subject to "implicit commit" is executed, PDO::inTransaction() will subsequently return false, as a transaction is no longer active.

PostgreSQL

  • The deprecated pg_connect() syntax using multiple parameters instead of a connection string is no longer supported.

  • The deprecated pg_lo_import() and pg_lo_export() signature that passes the connection as the last argument is no longer supported. The connection should be passed as first argument instead.

  • pg_fetch_all() will now return an empty array instead of false for result sets with zero rows.

Phar

Metadata associated with a phar will no longer be automatically unserialized, to fix potential security vulnerabilities due to object instantiation, autoloading, etc.

Reflection

  • The method signatures

    • ReflectionClass::newInstance($args)
    • ReflectionFunction::invoke($args)
    • ReflectionMethod::invoke($object, $args)

    have been changed to:

    • ReflectionClass::newInstance(...$args)
    • ReflectionFunction::invoke(...$args)
    • ReflectionMethod::invoke($object, ...$args)

    Code that must be compatible with both PHP 7 and PHP 8 can use the following signatures to be compatible with both versions:

    • ReflectionClass::newInstance($arg = null, ...$args)
    • ReflectionFunction::invoke($arg = null, ...$args)
    • ReflectionMethod::invoke($object, $arg = null, ...$args)
  • The ReflectionType::__toString() method will now return a complete debug representation of the type, and is no longer deprecated. In particular the result will include a nullability indicator for nullable types. The format of the return value is not stable and may change between PHP versions.

  • Reflection export() methods have been removed. Instead reflection objects can be cast to string.

  • ReflectionMethod::isConstructor() and ReflectionMethod::isDestructor() now also return true for __construct() and __destruct() methods of interfaces. Previously, this would only be true for methods of classes and traits.

  • ReflectionType::isBuiltin() method has been moved to ReflectionNamedType. ReflectionUnionType does not have it.

Sockets

  • The deprecated AI_IDN_ALLOW_UNASSIGNED and AI_IDN_USE_STD3_ASCII_RULESflags for socket_addrinfo_lookup() have been removed.

Standard PHP Library (SPL)

Standard Library

  • assert() will no longer evaluate string arguments, instead they will be treated like any other argument. assert($a == $b) should be used instead of assert('$a == $b'). The assert.quiet_eval ini directive and the ASSERT_QUIET_EVAL constant have also been removed, as they would no longer have any effect.

  • parse_str() can no longer be used without specifying a result array.

  • The string.strip_tags filter has been removed.

  • The needle argument of strpos(), strrpos(), stripos(), strripos(), strstr(), strchr(), strrchr(), and stristr() will now always be interpreted as a string. Previously non-string needles were interpreted as an ASCII code point. An explicit call to chr() can be used to restore the previous behavior.

  • The needle argument for strpos(), strrpos(), stripos(), strripos(), strstr(), stristr() and strrchr() can now be empty.

  • The length argument for substr(), substr_count(), substr_compare(), and iconv_substr() can now be null. null values will behave as if no length argument was provided and will therefore return the remainder of the string instead of an empty string.

  • The length argument for array_splice() can now be null. null values will behave identically to omitting the argument, thus removing everything from the offset to the end of the array.

  • The args argument of vsprintf(), vfprintf(), and vprintf() must now be an array. Previously any type was accepted.

  • The 'salt' option of password_hash() is no longer supported. If the 'salt' option is used a warning is generated, the provided salt is ignored, and a generated salt is used instead.

  • The quotemeta() function will now return an empty string if an empty string was passed. Previously false was returned.

  • The following functions have been removed:

  • FILTER_SANITIZE_MAGIC_QUOTES has been removed.

  • Calling implode() with parameters in a reverse order ($pieces, $glue) is no longer supported.

  • parse_url() will now distinguish absent and empty queries and fragments:

    • http://example.com/foo → query = null, fragment = null
    • http://example.com/foo? → query = "", fragment = null
    • http://example.com/foo# → query = null, fragment = ""
    • http://example.com/foo?# → query = "", fragment = ""
    Previously all cases resulted in query and fragment being null.
  • var_dump() and debug_zval_dump() will now print floating-point numbers using serialize_precision rather than precision. In a default configuration, this means that floating-point numbers are now printed with full accuracy by these debugging functions.

  • If the array returned by __sleep() contains non-existing properties, these are now silently ignored. Previously, such properties would have been serialized as if they had the value null.

  • The default locale on startup is now always "C". No locales are inherited from the environment by default. Previously, LC_ALL was set to "C", while LC_CTYPE was inherited from the environment. However, some functions did not respect the inherited locale without an explicit setlocale() call. An explicit setlocale() call is now always required if a locale component should be changed from the default.

  • The deprecated DES fallback in crypt() has been removed. If an unknown salt format is passed to crypt(), the function will fail with *0 instead of falling back to a weak DES hash now.

  • Specifying out of range rounds for SHA256/SHA512 crypt() will now fail with *0 instead of clamping to the closest limit. This matches glibc behavior.

  • The result of sorting functions may have changed, if the array contains elements that compare as equal.

  • Any functions accepting callbacks that are not explicitly specified to accept parameters by reference will now warn if a callback with reference parameters is used. Examples include array_filter() and array_reduce(). This was already the case for most, but not all, functions previously.

  • The HTTP stream wrapper as used by functions like file_get_contents() now advertises HTTP/1.1 rather than HTTP/1.0 by default. This does not change the behavior of the client, but may cause servers to respond differently. To retain the old behavior, set the 'protocol_version' stream context option, e.g.

    <?php
    $ctx = stream_context_create(['http' => ['protocol_version' => '1.0']]);
    echo file_get_contents('http://example.org', false, $ctx);
    ?>
  • Calling crypt() without an explicit salt is no longer supported. If you would like to produce a strong hash with an auto-generated salt, use password_hash() instead.

  • substr(), mb_substr(), iconv_substr() and grapheme_substr() now consistently clamp out-of-bounds offsets to the string boundary. Previously, false was returned instead of the empty string in some cases.

  • On Windows, the program execution functions (proc_open(), exec(), popen() etc.) using the shell, now consistently execute %comspec% /s /c "$commandline", which has the same effect as executing $commandline (without additional quotes).

Sysvsem

  • The auto_release parameter of sem_get() was changed to accept bool values rather than int.

Tidy

Tokenizer

  • T_COMMENT tokens will no longer include a trailing newline. The newline will instead be part of a following T_WHITESPACE token. It should be noted that T_COMMENT is not always followed by whitespace, it may also be followed by T_CLOSE_TAG or end-of-file.

  • Namespaced names are now represented using the T_NAME_QUALIFIED (Foo\Bar), T_NAME_FULLY_QUALIFIED (\Foo\Bar) and T_NAME_RELATIVE (namespace\Foo\Bar) tokens. T_NS_SEPARATOR is only used for standalone namespace separators, and only syntactially valid in conjunction with group use declarations.

XMLReader

XMLReader::open() and XMLReader::XML() are now static methods. They can still be called as instance methods, but inheriting classes need to declare them as static if they override these methods.

XML-RPC

The XML-RPC extension has been moved to PECL and is no longer part of the PHP distribution.

Zip

ZipArchive::OPSYS_Z_CPM has been removed (this name was a typo). Use ZipArchive::OPSYS_CPM instead.

Zlib

Windows PHP Test Packs

The test runner has been renamed from run-test.php to run-tests.php, to match its name in php-src.

PHP 8.0+: неверный тип стал исключением TypeErrorСамостоятельный пример
<?php
try {
    count(null);
} catch (TypeError $error) {
    echo $error::class, "\n";
}
Ожидаемый результат
TypeError

До PHP 8 count() принимал неподсчитываемые значения с предупреждением и возвращал 1 или 0; PHP 8 выбрасывает TypeError. Миграционный тест должен проверять реальные nullable-входы до обновления production.

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

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

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

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

Ядро PHP

  • Если за параметром со значением по умолчанию следует обязательный параметр, то значение по умолчанию не имеет смысла. С PHP 8.0.0 подобный порядок параметров объявлен устаревшим и может быть исправлен путём удаления значения по умолчанию:

    <?php
    function test($a = [], $b) {} // До
    function test($a, $b) {}      // После
    ?>

    Одним из исключений из этого правила являются параметры вида Type $param = null, где значение по умолчанию null делает тип неявно обнуляемым. Это пока что ещё разрешено, но вместо этого лучше рекомендуется использовать явный тип nullable:

    <?php
    function test(A $a = null, $b) {} // По-прежнему разрешено
    function test(?A $a, $b) {}       // Рекомендуется
    ?>
  • Вызов get_defined_functions() с явно заданным значением false в exclude_disabled устарел и больше не имеет смысла. get_defined_functions() никогда не будет возвращать отключённые функции.

Enchant

LibXML

libxml_disable_entity_loader() объявлена устаревшей. Поскольку теперь используется libxml 2.9.0, в котором загрузка внешних объектов по умолчанию отключена, поэтому использование этой функции больше не требуется для защиты от XXE-атак, если не используется (все ещё уязвимая) LIBXML_NOENT. В этом случае рекомендуется провести рефакторинг кода с помощью libxml_set_external_entity_loader(), чтобы подавить загрузку внешних сущностей.

PGSQL / PDO PGSQL

Библиотека стандартных функций

  • Функции сравнения сортировки, возвращающие true или false теперь сгенерирует предупреждение об устаревшей возможности, поэтому их следует переписать, чтобы они возвращали целое число меньше, равное или больше нуля.

    <?php
    // Заменить подобный код:
    usort($array, fn($a, $b) => $a > $b);
    // На этот:
    usort($array, fn($a, $b) => $a <=> $b);
    ?>

Zip

  • Использование пустого файла в ZipArchive объявлено устаревшим. Libzip 1.6.0 больше не работает с пустыми zip-архивами. Существующее обходное решение будет удалено в следующей версии.

  • Процедурный API Zip объявлен устаревшим. Вместо него используйте ZipArchive. Итерацию по всем записям можно выполнить с помощью ZipArchive::statIndex() и цикла for:

    <?php
    // итерация с использованием процедурного API
    assert(is_resource($zip));
    while ($entry = zip_read($zip)) {
        echo zip_entry_name($entry);
    }
    
    // итерация с использованием объектно-ориентированного API
    assert($zip instanceof ZipArchive);
    for ($i = 0; $entry = $zip->statIndex($i); $i++) {
        echo $entry['name'];
    }
    ?>

Reflection

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

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

PHP Core

  • If a parameter with a default value is followed by a required parameter, the default value has no effect. This is deprecated as of PHP 8.0.0 and can generally be resolved by dropping the default value, without a change in functionality:

    <?php
    function test($a = [], $b) {} // Before
    function test($a, $b) {}      // After
    ?>

    One exception to this rule are parameters of the form Type $param = null, where the null default makes the type implicitly nullable. This usage remains allowed, but it is recommended to use an explicit nullable type instead:

    <?php
    function test(A $a = null, $b) {} // Still allowed
    function test(?A $a, $b) {}       // Recommended
    ?>
  • Calling get_defined_functions() with exclude_disabled explicitly set to false is deprecated and no longer has an effect. get_defined_functions() will never include disabled functions.

Enchant

LibXML

libxml_disable_entity_loader() has been deprecated. As libxml 2.9.0 is now required, external entity loading is guaranteed to be disabled by default, and this function is no longer needed to protect against XXE attacks, unless the (still vulnerable) LIBXML_NOENT is used. In that case, it is recommended to refactor the code using libxml_set_external_entity_loader() to suppress loading of external entities.

PGSQL / PDO PGSQL

Standard Library

  • Sort comparison functions that return true or false will now throw a deprecation warning, and should be replaced with an implementation that returns an integer less than, equal to, or greater than zero.

    <?php
    // Replace
    usort($array, fn($a, $b) => $a > $b);
    // With
    usort($array, fn($a, $b) => $a <=> $b);
    ?>

Zip

  • Using an empty file as ZipArchive is deprecated. Libzip 1.6.0 does not accept empty files as valid zip archives any longer. The existing workaround will be removed in the next version.

  • The procedural API of Zip is deprecated. Use ZipArchive instead. Iteration over all entries can be accomplished using ZipArchive::statIndex() and a for loop:

    <?php
    // iterate using the procedural API
    assert(is_resource($zip));
    while ($entry = zip_read($zip)) {
        echo zip_entry_name($entry);
    }
    
    // iterate using the object-oriented API
    assert($zip instanceof ZipArchive);
    for ($i = 0; $entry = $zip->statIndex($i); $i++) {
        echo $entry['name'];
    }
    ?>

Reflection

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

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

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

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

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

Apache2Handler

Модуль PHP был переименован из php7_module в php_module.

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

Reflection

Результаты ReflectionClass::getConstants() и ReflectionClass::getReflectionConstants() теперь можно фильтровать с помощью нового параметра filter. Добавлены три новые константы для работы с ним:

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

Математические функции abs(), ceil(), floor() и round() теперь правильно учитывают объявление strict_type. Ранее они приводили первый аргумент к числовому значению даже в режиме строгой типизации.

Zip

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

CURL

  • Для работы модуля CURL теперь требуется как минимум libcurl 7.29.0.

  • Устаревший параметр version функции curl_version() был удалён.

Дата и время

DatePeriod теперь реализует IteratorAggregate (вместо Traversable).

DOM

DOMNamedNodeMap и DOMNodeList теперь реализуют IteratorAggregate (вместо Traversable).

Intl

IntlBreakIterator и ResourceBundle теперь реализуют IteratorAggregate (вместо Traversable).

Enchant

Модуль enchant теперь использует libenchant-2 по умолчанию, если возможно. libenchant версии 1 все ещё поддерживается, но устарел и может быть удалён в будущем.

GD

  • Параметр num_points для imagepolygon(), imageopenpolygon() и imagefilledpolygon() теперь является необязательным, то есть эти функции могут быть вызваны с помощью трёх или четырёх параметров. Если параметр опущен, он рассчитывается как count($points)/2.

  • Добавлена функция imagegetinterpolation() для получения текущего метода интерполяции.

JSON

Модуль JSON больше нельзя отключить, теперь он является неотъемлемой частью любой сборки PHP, как и модуль date.

MBString

Таблицы данных Unicode обновлены до версии 13.0.0.

PDO

PDOStatement теперь реализует IteratorAggregate (вместо Traversable).

LibXML

Минимальная необходимая версия libxml - 2.9.0. Это означает, что загрузка внешних объектов по умолчанию теперь отключена и поэтому не требуется дополнительных шагов для защиты от XXE-атак.

MySQLi / PDO MySQL

  • Если mysqlnd не используется (это вариант по умолчанию и рекомендуется), минимальная поддерживаемая версия libmysqlclient теперь 5.5.

  • mysqli_result теперь реализует IteratorAggregate (вместо Traversable).

PGSQL / PDO PGSQL

Для модулей PGSQL и PDO PGSQL теперь требуется как минимум libpq 9.1.

Readline

Вызов readline_completion_function() перед запуском интерактивной подсказки (например, в auto_prepend_file) теперь отменяет функцию завершения интерактивной подсказки по умолчанию. Ранее readline_completion_function() работала только при вызове после запуска интерактивной подсказки.

SimpleXML

SimpleXMLElement теперь реализует RecursiveIterator и включает в себя функционал SimpleXMLIterator. SimpleXMLIterator является пустым расширением SimpleXMLElement.

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

  • com.dotnet_version - это новая INI-директива для выбора версии платформы .NET, которая будет использоваться для объектов dotnet.

  • zend.exception_string_param_max_len - это новая INI-директива для установки максимальной длины строки в аргументе строковой трассировки стека.

EBCDIC

Цели EBCDIC больше не поддерживаются, хотя маловероятно, что они до сих пор работали.

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

  • Компилятор Just-In-Time (JIT) был добавлен в модуль opcache.

  • array_slice() в массиве без расстояний между элементами больше не будет сканировать весь массив, чтобы найти начальное смещение. Это может значительно сократить время выполнения функции с большими смещениями и малой длиной.

  • strtolower() теперь использует реализацию SIMD в локали "C"LC_CTYPE (которая используется по умолчанию).

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

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

Changes in SAPI Modules

Apache2Handler

The PHP module has been renamed from php7_module to php_module.

Changed Functions

Reflection

ReflectionClass::getConstants() and ReflectionClass::getReflectionConstants() results can be now filtered via a new parameter filter. Three new constants were added to be used with it:

Standard

The math functions abs(), ceil(), floor() and round() now properly heed the strict_types directive. Previously, they coerced the first argument even in strict type mode.

Zip

Other Changes to Extensions

CURL

  • The CURL extension now requires at least libcurl 7.29.0.

  • The deprecated parameter version of curl_version() has been removed.

Date and Time

DatePeriod now implements IteratorAggregate (instead of Traversable).

DOM

DOMNamedNodeMap and DOMNodeList now implement IteratorAggregate (instead of Traversable).

Intl

IntlBreakIterator and ResourceBundle now implement IteratorAggregate (instead of Traversable).

Enchant

The enchant extension now uses libenchant-2 by default when available. libenchant version 1 is still supported but is deprecated and could be removed in the future.

GD

JSON

The JSON extension cannot be disabled anymore and is always an integral part of any PHP build, similar to the date extension.

MBString

The Unicode data tables have been updated to version 13.0.0.

PDO

PDOStatement now implements IteratorAggregate (instead of Traversable).

LibXML

The minimum required libxml version is now 2.9.0. This means that external entity loading is now guaranteed to be disabled by default, and no extra steps need to be taken to protect against XXE attacks.

MySQLi / PDO MySQL

PGSQL / PDO PGSQL

The PGSQL and PDO PGSQL extensions now require at least libpq 9.1.

Readline

Calling readline_completion_function() before the interactive prompt starts (e.g. in auto_prepend_file) will now override the default interactive prompt completion function. Previously, readline_completion_function() only worked when called after starting the interactive prompt.

SimpleXML

SimpleXMLElement now implements RecursiveIterator and absorbed the functionality of SimpleXMLIterator. SimpleXMLIterator is an empty extension of SimpleXMLElement.

Changes to INI File Handling

  • com.dotnet_version is a new INI directive to choose the version of the .NET framework to use for dotnet objects.

  • zend.exception_string_param_max_len is a new INI directive to set the maximum string length in an argument of a stringified stack strace.

EBCDIC

EBCDIC targets are no longer supported, though it's unlikely that they were still working in the first place.

Performance

  • A Just-In-Time (JIT) compiler has been added to the opcache extension.

  • array_slice() on an array without gaps will no longer scan the whole array to find the start offset. This may significantly reduce the runtime of the function with large offsets and small lengths.

  • strtolower() now uses a SIMD implementation when using the "C"LC_CTYPE locale (which is the default).

Контроль перед переключением production

Все относящиеся к проекту несовместимости должны иметь воспроизводимый тест. Deprecation не подавляют: его устраняют или записывают владельца и срок. Новые функции применяют только после повышения минимальной версии. Затем повторяют smoke-тест в том же SAPI и на том же типе данных, что используется в production.

Источники и обсуждения

Код и руководство с собой

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

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

Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.