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

### Ядро PHP

#### Псевдонимы `"array"` и `"callable"`

Слова `"array"` и `"callable"` больше нельзя указывать как псевдонимы классов при вызове функции class_alias().

#### Нестрогое сравнение несравнимых объектов

Нестрогое сравнение несравнимых объектов — перечислений, объектов CurlHandle и других внутренних классов — с логическими значениями прежде оставалось непоследовательным. При сравнении с логическим литералом в выражениях наподобие `$object == true` объект неявно приводился к логическому значению, как если бы сравнение выполняли с явным приведением типа: `(bool) $object`. При сравнении со значением, которое невозможно вычислить в статическом контексте, — в выражениях наподобие `$object == $true`, возвращалось значение `false`. Поведение унифицировали: объекты без внутренней логики сравнения теперь сравниваются только после неявного приведения `(bool) $object`.

#### Значение возврата функции gc_collect_cycles

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

#### Замена ключевого слова static в окончательном подклассе

В окончательных подклассах ключевое слово static разрешили заменять на self или название конкретного класса.

#### Обработчики тиков

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

#### Связывание трейтов

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

#### Ошибки при компиляции и связывании классов

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

#### Исключения, выбрасываемые пользовательским обработчиком ошибок

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

#### Ошибка применения атрибута во время компиляции

Применение `#[\Attribute]` к абстрактному классу, перечислению, интерфейсу или трейту вызывает ошибку во время компиляции. Ранее атрибут можно было добавить, но при вызове метода ReflectionAttribute::newInstance() выдавалась ошибка. Ошибку можно отложить с момента компиляции до момента выполнения с помощью нового атрибута `#[\DelayedTargetValidation]`.

#### Директива disable_classes

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

#### Деструктуризация значений кроме массивов

Деструктуризация значений, кроме массивов и `null`, конструкцией `[]` или функцией list() теперь выдаёт предупреждение.

#### Предупреждения, связанные с приведением типов

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

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

### Модуль Bzip2

Функция bzcompress() теперь выбрасывает ошибку ValueError, если значение параметра `$block_size` выходит за пределы диапазона от 1 до 9.

Функция bzcompress() теперь выбрасывает ошибку ValueError, если значение параметра `$work_factor` выходит за пределы диапазона от 0 до 250.

### Модуль DOM

Клонирование объектов DOMNamedNodeMap, DOMNodeList, Dom\NamedNodeMap, Dom\NodeList, Dom\HTMLCollection и Dom\DtdNamedNodeMap теперь выбрасывает ошибку. Такое поведение никогда не создавало рабочие объекты, поэтому изменение не повлияет на код, который написали на предыдущих версиях языка.

### Модуль FileInfo

Функция finfo_file() и метод finfo::file() теперь выбрасывают ошибку ValueError вместо TypeError, если значение параметра `$filename` содержит нулевые байты. Теперь тип выбрасываемой ошибки соответствует остальной частью языка.

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

Для работы модуля теперь требуется как минимум ICU 57.1.

Метод IntlDateFormatter::setTimeZone() и функция datefmt_set_timezone() теперь выбрасывают исключение IntlException при неинициализированных классах или ошибках клонирования.

Все методы класса Locale теперь выбрасывают исключение ValueError, если значение параметра locale содержит нулевые байты.

Поведение константы `Collator::SORT_REGULAR` при обработке числовых строк теперь соответствует поведению `SORT_REGULAR` в модуле ext/standard.

### Модуль LDAP

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

### Модуль MBString

Таблицы данных Unicode были обновлены до версии Unicode 17.0.

### Модуль MySQLi

Вызов конструктора на объекте mysqli теперь невозможен и выбрасывает ошибку Error.

### Модуль ODBC

ODBC теперь предполагает, что доступна как минимум функциональность ODBC 3.5. Определение ODBCVER и флаги системы сборки, управляющие им, были удалены.

ODBC больше не включает флаги сборки для сборки с конкретными драйверами (за исключением DB2) и удаляет особые случаи для этих драйверов. Настоятельно рекомендуется использовать диспетчер драйверов наподобие iODBC или unixODBC на операционных системах кроме Windows.

### Модуль Opcache

Модуль Opcache встроили в бинарный файл PHP, поэтому модуль не требует отдельной установки и загружается автоматически. INI-директивы opcache.enable и opcache.enable_cli по-прежнему работают.

Флаги конфигурации --enable-opcache/--disable-opcache были удалены и сборка больше не создаёт объекты opcache.so или php_opcache.dll.

INI-директивы `zend_extension=opcache.so` и `zend_extension=php_opcache.dll` теперь выдают предупреждение.

### Модуль PCNTL

Функция pcntl_exec() теперь выбрасывает ошибку ValueError, если элементы параметра `$args` содержат нулевые байты..

Функция pcntl_exec() теперь выбрасывает ошибку ValueError, если записи или ключи параметра `$env_vars` содержат нулевые байты.

### Модуль PCRE

Модуль скомпилирован без полуустаревшего параметра компиляции PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK.

### Модуль PDO

Аргументы, которые передаются в конструктор класса при установке режима `PDO::FETCH_CLASS`, теперь обрабатываются по правилам стандартной семантики функции call_user_func_array(), поэтому строковые ключи интерпретируются как именованные аргументы. При передаче в параметр, который ожидает аргумент по ссылке, значения, а не переменной, аргумент автоматически оборачивался во временную переменную. Это поведение тоже удалили и теперь выдаётся стандартное предупреждение `E_WARNING`. Для передачи в аргументе конструктора переменной по ссылке в массиве переменной по ссылке значение массива присваивают по ссылке: `$ctor_args = [&$valByRef]`.

При попытке вызова метода PDOStatement::setFetchMode() в контексте работы методов PDOStatement::fetch(), PDOStatement::fetchObject() или PDOStatement::fetchAll() — например, при передаче объекта запроса в конструктор в режиме извлечения данных в объект — теперь выбрасывается ошибка Error.

Изменились значения констант `PDO::FETCH_GROUP`, `PDO::FETCH_UNIQUE`, `PDO::FETCH_CLASSTYPE`, `PDO::FETCH_PROPS_LATE` и `PDO::FETCH_SERIALIZE`.

При попытке указать опцию `PDO::FETCH_PROPS_LATE` с несовместимыми режимами извлечения теперь выбрасывается ошибка ValueError, как и при других несовместимых комбинациях флагов. Опция совместима только с режимом `PDO::FETCH_CLASS`.

При попытке выбрать строки методом PDOStatement::fetchAll() в режиме `PDO::FETCH_INTO` теперь выбрасывается ошибка ValueError — как и в режиме выборки `PDO::FETCH_LAZY`.

### Драйвер PDO_FIREBIRD

При попытке установить слишком длинное имя курсора в классе PDOStatement, полученном от драйвера Firebird, теперь выбрасывается ошибка ValueError.

### Драйвер PDO_SQLITE

SQLite PDO::quote() теперь выбрасывает исключение или выдаёт предупреждение, в зависимости от режима ошибок, если строка содержит нулевой байт.

Метод PDO::sqliteCreateCollation() теперь выбрасывает исключение, если у callback-функции неправильный тип возвращаемого значения, что повышает совместимость с поведением метода Pdo\Sqlite::createCollation().

### Модуль POSIX

Функция posix_kill() теперь выбрасывает исключение ValueError, если аргумент process_id меньше или больше, чем поддерживает платформа (целое число со знаком или большой диапазон), функция posix_setpgid() теперь выбрасывает исключение ValueError, если process_id или process_group_id меньше нуля или больше, чем поддерживает платформа.

Функция posix_setrlimit() теперь выбрасывает исключение ValueError, если аргументы hard_limit или soft_limit меньше -1 или если soft_limit больше hard_limit.

### Модуль интроспекции кода Reflection

Метод ReflectionAttribute::newInstance() теперь выбросит ошибку для внутренних атрибутов, если атрибут применили к недопустимой цели, а выдачу ошибки отложили с компиляции на момент выполнения атрибута #[\DelayedTargetValidation].

### Модуль Session

Попытка записать данные сессии, где ключ массива $_SESSION содержит символ вертикальной черты (`|`), теперь выдаёт предупреждение вместо молчаливой ошибки.

Функция session_start() строже относится к аргументу options. Функция теперь выбрасывает ошибку ValueError, если массив не является хеш-картой, или ошибку TypeError, если значение read_and_close не является допустимым типом, совместимым с int.

Передача целочисленного значения `0` в аргументе `locales` функции setlocale() больше не поддерживается и теперь выбрасывает ошибку TypeError.

### Модуль SimpleXML

Передача выражения XPath, которое возвращает что-либо, кроме набора узлов, в методе SimpleXMLElement::xpath() теперь выдаёт предупреждение и возвращает значение `false`, вместо того, чтобы молчаливо завершаться с ошибкой и возвращать пустой массив.

### Модуль SNMP

Функции snmpget(), snmpset(), snmp2_get(), snmp2_set(), snmp3_get(), snmp3_set() и SNMP::__construct() теперь выбрасывают ошибку ValueError, если имя хоста слишком большое, содержит нулевые байты или если порт указан с отрицательным значением или больше 65535, а значения времени ожидания и повторных попыток меньше -1 или слишком большое.

### Модуль SOAP

Метод SoapClient::__doRequest() теперь принимает новый необязательный параметр `$uriParserClass`, который принимает строковые аргументы или `null`. Значение `null` представляет исходный метод — parse_url(), а новые обработчики устанавливаются при передаче либо объекта Uri\Rfc3986\Uri, либо объекта Uri\WhatWg\Url.

### Модуль Sockets

Функции socket_create_listen(), socket_bind() и socket_sendto() теперь выбрасывают ошибку ValueError, если порт меньше 0 или больше 65535, а также если хотя бы один элемент массива `$hints` содержит числовой индекс.

Функция socket_addrinfo_lookup() теперь выбрасывает ошибку TypeError, если какое-то значение параметра `$hints` невозможно преобразовать в целое число, и ошибку ValueError при переполнении значения параметра.

Функция socket_set_option() с опциями `MCAST_LEAVE_GROUP`/`MCAST_LEAVE_SOURCE_GROUP` теперь выбрасывает исключение, если значение не является корректным объектом или массивом.

Функция socket_set_option() с контекстом многоадресной рассылки теперь выбрасывает ошибку ValueError, если созданный сокет не принадлежит семейству `AF_INET`/`AF_INET6`.

### Модуль SPL

Класс ArrayObject больше не принимает перечисления, поскольку изменение свойства $name или $value нарушило бы требование о неизменности перечисления и сделало бы обработку изменённого перечисления движком непредсказуемой или даже невозможной.

Параметр `$length` метода SplFileObject::fwrite() теперь принимает значение `null`. Значение по умолчанию изменилось с `0` на `null`.

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

Функции семейства printf теперь обрабатывают пропуск спецификатора точности в строке формата как точность со значением 0; раньше при пропуске спецификатора точность ошибочно сбрасывалась.

### Модуль Tidy

Методы tidy::__construct(), tidy::parseFile(), tidy::parseString() теперь выбрасывают ошибку ValueError, если конфигурация содержит некорректное значение или пытается установить внутреннюю запись, доступную только для чтения, и ошибку TypeError, если ключ конфигурации не является строкой.

`↑` and `↓` to navigate • `Enter` to select • `Esc` to close • `/` to open