## Другие изменения

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

#### Замыкания

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

#### Файберы

Переключение файберов теперь разрешили при запуске деструктора. Раньше переключение файберов блокировали из-за конфликтов со сборщиком мусора.

Деструкторы теперь разрешается выполнять в отдельном файбере:

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

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

Флаги статуса обработчика вывода, которые передали в параметр `flags` функции ob_start(), теперь очищаются.

Функция output_add_rewrite_var() для выбора хостов, которые перезапишутся, теперь руководствуется значением директивы `url_rewriter.hosts` вместо директивы `session.trans_sid_hosts`.

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

#### apache2handler

Из-за окончания жизненного цикла удалили поддержку веб-серверов Apache 2.0 и 2.2. Теперь требуется версия Apache не ниже 2.4.

#### Модуль CLI

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

#### Модуль FPM

Теперь сброс, или отправка, заголовков без тела выполнится успешно.

На странице статуса появилось новое поле, которое показывает пиковое значение объёма выделяемой памяти.

Настройку `events.mechanism` в файле /dev/poll для ОС Solaris/Illumos удалили.

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

#### Ядро

Функции trigger_error() и user_error() теперь возвращают конкретное логическое значение true вместо общего bool.

#### Модуль DOM

В Методе DOMDocument::registerNodeClass() предварительный тип возврата определили как true вместо прежнего bool, поскольку на практике метод возвращал только `true`.

#### Модуль Hash

В функции hash_update() предварительный тип возврата теперь true вместо прежнего bool, поскольку на практике метод возвращал только `true`.

#### Модуль Intl

Константы `NumberFormatter::ROUND_TOWARD_ZERO` и `NumberFormatter::ROUND_AWAY_FROM_ZERO` добавили как синонимы констант `NumberFormatter::ROUND_DOWN` и `NumberFormatter::ROUND_UP` для согласованности с семейством режимов `PHP_ROUND_*`.

Метод ResourceBundle::get() получил предварительный тип возврата `ResourceBundle|array|string|int|null`.

Функции idn_to_ascii() и idn_to_utf8() теперь выбрасывают ошибки ValueError при каждом вызове, если имя в параметре `domain` оказалось пустым или слишком длинным.

Функции idn_to_ascii() и idn_to_utf8() теперь выбрасывают ошибку ValueError при каждом вызове, если значение аргумента `variant` не равно `INTL_IDNA_VARIANT_UTS46`.

#### Модуль LibXML

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

#### Модуль MBString

Поведение функции mb_strcut() теперь лучше согласуется с недопустимыми для кодировок UTF-8 и UTF-16 строками. Для допустимых для кодировок UTF-8 и UTF-16 строк поведение не изменилось.

#### Модуль ODBC

Разработчики изменили значение по умолчанию для параметра `row` в функциях odbc_fetch_object(), odbc_fetch_array() и odbc_fetch_into(), теперь значение равно `null`, что согласуется в функцией odbc_fetch_row(). Предыдущие значения по умолчанию равнялись `-1`, `-1` и `0` соответственно.

#### Модуль OpenSSL

Параметр `extra_attributes` в функции openssl_csr_new() вместо DN-имени (англ. сокр.: Distinguished Name — уникальное имя) субъекта устанавливает атрибут CSR; раньше функция делала это неправильно.

Параметр `dn` в функции openssl_csr_new() разрешает устанавливать массив (array) значений для одной записи.

В функцию openssl_csr_sign() добавили новый параметр `serial_hex`, который разрешает устанавливать серийные номера в шестнадцатеричном формате.

Разбор значений даты и времени в формате UTCTime языка ASN.1 функцией openssl_x509_parse() завершится ошибкой, если секунды опустили для версии модуля OpenSSL ниже 3.2 (для таких полей возвращает значение `-1`). Версия OpenSSL выше 3.3 уже не загружала такие сертификаты.

#### Модуль PDO

Получить значение атрибута `PDO::ATTR_STRINGIFY_FETCHES` теперь возможно методом PDO::getAttribute().

Добавили новую константу `PDO::PGSQL_ATTR_RESULT_MEMORY_SIZE`, чтобы получать данные о потреблении памяти результатами запросов методом PDO::getAttribute() для драйверов, которые поддерживают метод.

#### Драйвер PDO_FIREBIRD

Значения атрибутов `FB_ATTR_DATE_FORMAT`, `FB_ATTR_TIME_FORMAT` и `FB_ATTR_TIMESTAMP_FORMAT` теперь возможно получать методом PDO::getAttribute().

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

- `Pdo\Firebird::TRANSACTION_ISOLATION_LEVEL`
- `Pdo\Firebird::READ_COMMITTED`
- `Pdo\Firebird::REPEATABLE_READ`
- `Pdo\Firebird::SERIALIZABLE`
- `Pdo\Firebird::WRITABLE_TRANSACTION`

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

Содержимое, которое создаёт драйвер, меняется в зависимости от значения флага `FB_API_VER` в файле ibase.h. Эту информацию получают методом Pdo\Firebird::getApiVersion(). Эта информация теперь также упоминается в выводе функции phpinfo().

Теперь доступны пять новых типов данных: `INT128`, `DEC16`, `DEC34`, `TIMESTAMP_TZ`, `TIME_TZ` . Типы доступны начиная с Firebird 4.0.

#### Драйвер PDO_MYSQL

Значение атрибута `PDO::ATTR_FETCH_TABLE_NAMES` теперь возможно получать методом PDO::getAttribute().

#### Драйвер PDO_PGSQL

Добавили поддержку получения информации о потреблении памяти запросами для флага `PDO::PGSQL_ATTR_RESULT_MEMORY_SIZE`.

Значение тперь возвращается как число с плавающей точкой float, а не как строка (string), если столбец принадлежит типу `FLOAT4OID` или `FLOAT8OID`.

#### Модуль PGSQL

Параметр `conditions` функции pg_select() теперь необязателен и принимает пустой массив.

#### Модуль Phar

В методах Phar::setAlias(), Phar::setDefaultStub() предварительный тип возврата bool изменили на true.

#### Модуль POSIX

Функция posix_isatty() теперь устанавливает номер ошибки, если аргумент дескриптора файла или потока недопустим.

#### Модуль Reflection

Метод ReflectionGenerator::getFunction() теперь разрешили вызывать, когда завершится выполнение генератора.

#### Модуль Sockets

Значение по умолчанию для параметра `backlog` функции socket_create_listen() изменили на `SOMAXCONN`. Раньше значение по умолчанию равнялось `128`.

#### Модуль Sodium

Функции семейства sodium_crypto_aead_aes256gcm_* теперь доступны для центральных процессоров, которые построили по архитектуре aarch64, с криптографическими модулями ARM.

#### Стандартная PHP-библиотека SPL

Предварительный тип возврата в методах SplPriorityQueue::insert(), SplPriorityQueue::recoverFromCorruption(), SplHeap::insert(), SplHeap::recoverFromCorruption() изменили с bool на true.

Класс SplObjectStorage теперь реализует итератор SeekableIterator.

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

Значение по умолчанию стоимости `'cost'` для алгоритма хеширования `PASSWORD_BCRYPT` в функции password_hash() увеличили с `10` до `12`.

Функция debug_zval_dump() теперь указывает, упакован ли массив.

Тип возврата в функции long2ip() изменили со `string|false` на string.

Тип возврата в функции highlight_string() изменили со `string|bool` на string|true.

Тип возврата в функции print_r() изменили со `string|bool` на string|true.

##### Округление чисел функцией round()

Тип параметра `mode` функции round() расширили до типа `RoundingMode|int`, который теперь принимает новое перечисление RoundingMode.

В функцию round() добавили четыре новых режима: RoundingMode::PositiveInfinity, RoundingMode::NegativeInfinity, RoundingMode::TowardsZero, RoundingMode::AwayFromZero

Внутреннюю реализацию округления до целых чисел переписали, чтобы реализацию было легче проверять на корректность и поддерживать. По ходу переписывания исправили ряд ошибок округления. Например, раньше округление числа `0.49999999999999994` до ближайшего целого вернуло бы значение `1.0` вместо правильного результата — `0.0`. Округление также затронет часть дополнительных входных данных и выдаст другой по сравнению с предыдущими версиями PHP результат.

Исправили ошибку, которую вызывало «предварительное округление» в функции round(). Раньше для обработки как десятичного числа, значения наподобие `0.285`, которое PHP внутренне представляет как `0.28499999999999998`, функция вначале «предварительно округляла» число, а затем округляла результат до `0.29`. Однако «предварительное округление» неправильно округляет отдельные числа, поэтому это исправление удаляет «предварительное округление» и изменяет способ сравнения чисел, чтобы значения правильно округлялись как десятичные числа, а не как числа с плавающей точкой по стандарту IEEE754.

Максимальную точность, с которой функция round() умеет обрабатывать числа, увеличили на один знак. Например, вызов `round(4503599627370495.5)` возвращал число `4503599627370495.5`, а теперь возвращает `4503599627370496`.

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

#### Модуль cURL

Минимальная версия библиотеки libcurl, которая требуется для работы модуля, теперь 7.61.0.

Опция `CURLOPT_DNS_USE_GLOBAL_CACHE` больше ни на что не влияет, и без предупреждения игнорируется. Опция устарела на нижележащем уровне — в библиотеке libcurl 7.11.1, а в libcurl 7.62.0 опцию удалили.

#### Модуль GMP

GMP-объекты разрешили приводить к логическому типу bool, раньше выдавалась ошибка уровня `E_RECOVERABLE_ERROR`. Поведение приведения перегружается так, чтобы GMP-объект, который представляет значение `0`, приводился к логическому значению `false`.

#### Модуль LibXML

Минимальная версия библиотеки libxml2, которая требуется для работы модуля, теперь 2.9.4.

#### Модуль Intl

Поведение класса Intl нормализовали так, чтобы при попытке использовать неинициализированный объект или при ошибках клонирования класс выбрасывал ошибку Error.

#### Модуль MBString

Таблицы данных Юникода обновили до Unicode 16.0.

#### Драйвер MySQLnd

Добавили поддержку нового типа данных БД MySQL 9 — VECTOR.

#### Модуль OpenSSL

Минимальная версия библиотеки OpenSSL, которая требуется для работы модуля, теперь 1.1.1.

#### Драйвер PDO_PGSQL

Минимальная версия библиотеки libpq, которая требуется для работы драйвера, теперь 10.0.

#### Модуль PGSQL

Минимальная версия библиотеки libpq, которая требуется для работы модуля, теперь 10.0.

#### Стандартная PHP-библиотека SPL

Доступ за пределы массива в SplFixedArray теперь вместо RuntimeException выбрасывает исключение OutOfBoundsException. Поскольку OutOfBoundsException — дочерний класс RuntimeException, поведение при попытке перехватить эти исключения не меняется.

#### Модуль XSL

Объявили типизированные свойства XSLTProcessor::$cloneDocument и XSLTProcessor::$doXInclude.

#### Модуль Zlib

Минимальная версия библиотеки zlib, которая требуется для работы модуля, теперь 1.2.11.

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

#### Ядро

Улучшили производительность разбора и форматирования чисел с плавающей точкой в ZTS-сборках при высокой параллельной нагрузке. Это влияет на семейство функций printf(), и на функции сериализации наподобие json_encode() или serialize().

Вызов функции sprintf() только со спецификаторами `%s` и `%d` скомпилирует эквивалентную интерполяцию строки без накладных расходов на вызов функции и без повторного анализа строки формата.

#### Модуль BCMath

Улучили производительность числовых преобразований и операций.

#### Модуль DOM

Производительность метода DOMNode::C14N() значительно улучшили при вызове без xpath-выражения. Изменение иногда сокращает время запроса на два порядка при обработке документов с десятками тысяч узлов.

Улучшили производительность и снизили потребление памяти при XML-сериализации.

Снизили потребление памяти классами узлов.

#### Модуль FTP

Улучшили производительность загрузки больших файлов по протоколу FTP до 10 раз.

#### Модуль Hash

Добавили реализацию алгоритма SHA-256 инструкциями SSE2 и SHA-NI. Изменение повышает производительность поддерживаемых процессоров примерно в 1,3 раза для SSE2-инструкций и до 3-5 раз для инструкций SHA-NI. Благодарим Колина Персиваля (англ. Colin Percival), разработчика сервиса резервного копирования Tarsnap, за эту оптимизацию.

#### Модуль MBString

Функция mb_strcut() теперь быстрее обрабатывает строки в кодировках UTF-8 и UTF-16.

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

Значительно улучшили производительность преобразования строк в кодировке SJIS-win в кодировку Unicode.

#### Драйвер MySQLnd

Улучшили производительность при обработке драйвером MySQLnd значений в кавычках в MySQL-запросах.

#### Модуль PCRE

Улучшили производительность именованных групп захвата.

#### Модуль Random

Улучшили производительность класса Random\Randomizer, повышенное внимание уделили методам Random\Randomizer::getBytes() и Random\Randomizer::getBytesFromString().

#### Модуль SimpleXML

Улучшили производительность и снизили потребление памяти при XML-сериализации.

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

Значительно улучшили производительность функций strspn() и strcspn(). Теперь функции работают за линейное время, а не ограничиваются квадратичным временем.

Улучшили производительность функции strpbrk().

Функция get_browser() теперь работает до 1,5-2,5 раза быстрее в отдельных тестах.

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