PHP 8.4.1 Released!

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

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

Ядро PHP

Изменение поведения языковой конструкции exit()

Поведение языковой конструкции exit() и её псевдонима die() теперь больше похоже на функции: их разрешили передавать как значения с типом callable, на поведение функций теперь влияет директива strict_types управляющей конструкции declare и теперь они выполняют стандартные преобразования типов вместо приведения нецелочисленных значений к строке.

Поэтому передача недопустимых типов в функции exit() и die() теперь выбрасывает ошибку TypeError.

Рекурсия при сравнении

Появление рекурсии при сравнении теперь выбрасывает ошибку Error вместо ошибки уровня E_ERROR.

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

Непрямую модификацию доступных только для чтения свойств внутри магического метода __clone() запретили, например, присваивание по ссылке $ref = &$this->readonly вызовет фатальную ошибку. Инициализацию доступных только для чтения свойств запретили раньше и упустили в реализации «повторной инициализации доступных только для чтения свойств при клонировании».

Изменение типа констант

Константы PHP_DEBUG и PHP_ZTS теперь принадлежат логическому типу bool. Раньше константы принадлежали целочисленному типу int.

Длина имени временного файла

Длину имён загруженных файлов и файлов, которые создали функцией tempnam(), увеличили на 13 байтов. Общая длина по-прежнему зависит от платформы.

Удаление уровня ошибки E_STRICT

Уровень ошибки E_STRICT удалили, поскольку движок PHP больше не использует его. Константа E_STRICT устарела.

Типизация констант в классах модулей

Следующие модули теперь объявляют тип для констант своих классах:

Миграция ресурсов в объекты

Ряд ресурсов (resource) перенесли в объекты (object). Значения, которые возвращали функции-создатели ресурсов и которые проверяли функцией is_resource(), потребуется заменить проверками значений возврата таких функций на принадлежность типу false, если только в описании функции не указали иное.

Модуль DBA

Функции модуля DBA теперь принимают и возвращают объекты Dba\Connection вместо ресурсов (resource) dba_connection.

Драйвер ODBC

Функции драйвера ODBC теперь принимают и возвращают объекты Odbc\Result вместо ресурсов (resource) odbc_result.

Функции драйвера ODBC теперь принимают и возвращают объекты Odbc\Connection вместо ресурсов (resource) odbc_connection.

SOAP

Разработчики представили свойство SoapClient::$httpurl объектом Soap\Url, а не ресурсом (resource) soap_url. Проверки функцией is_resource() наподобие is_resource($client->httpurl)) потребуется заменить проверками на null вроде $client->httpurl !== null.

Разработчики представили свойство SoapClient::$sdl объектом Soap\Sdl, а не ресурсом (resource) soap_sdl. Проверки функции is_resource() наподобие is_resource($client->sdl) потребуется заменить проверками на null вроде $client->sdl !== null.

Новые предупреждения и исключения

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

Модуль Curl

Функция curl_multi_select() теперь выбрасывает ошибку ValueError, если аргумент timeout меньше 0 или больше значения константы PHP_INT_MAX.

Модуль Gd

Функции imagejpeg(), imagewebp(), imagepng(), imageavif() теперь выбрасывают ошибку ValueError, если в параметр quality передали недопустимое значение.

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

Функция imagescale() теперь выбрасывает ошибку ValueError, если ширина width или высота height выходит за пределы допустимых значений: недополнено или переполнено.

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

Функция imagefilter() с фильтром IMG_FILTER_SCATTER теперь выбрасывают ошибку ValueError, если значение вычитания sub или добавления plus эффекта выходит за пределы допустимых значений: недополнено или переполнено.

Модуль Gettext

Функции bind_textdomain_codeset(), textdomain(), d()*gettext() теперь выбрасывают ошибку ValueError, если в аргументе domain передали пустую строку.

Модуль Intl

Функции resourcebundle_get(), ResourceBundle::get() и обращение к смещениям объекта ResourceBundle теперь выбрасывают исключение:

  • TypeError при недопустимых типах смещения
  • ValueError при передаче пустой строки (string)
  • ValueError, если целочисленный индекс не помещается в 32-битное целое число со знаком

Метод IntlDateFormatter::__construct() теперь выбрасывает ошибку ValueError, если в параметр locale передали недопустимое значение.

Метод NumberFormatter::__construct() теперь выбрасывает ошибку ValueError, если в параметр locale передали недопустимое значение.

Модуль MBString

Теперь функции mb_encode_numericentity() и mb_decode_numericentity() проверяют, что значение параметра map состоит только из целых числел (int), иначе выбрасывают ошибку ValueError.

Теперь функция mb_http_input() выбрасывает ошибку ValueError при каждом вызове, если в параметр type передали недопустимое значение.

Теперь функция mb_http_output() проверяет, что значение параметра encoding не содержит нулевых байтов, иначе выбрасывает ошибку ValueError.

ODBC

Функция odbc_fetch_row() раньше возвращала значение false, если значение аргумента row оказывалось меньше или равно 0. Теперь функция выдаёт предупреждение.

Модуль PCNTL

Функции pcntl_sigprocmask(), pcntl_sigwaitinfo() и pcntl_sigtimedwait() теперь выбрасывают исключение:

  • ValueError, если массив signals оказался пустым (за исключением функции pcntl_sigprocmask(), если для параметра mode установили режим SIG_SETMASK)
  • TypeError, если массив signals содержит значение, которое не принадлежит типу int
  • ValueError, если массив signals содержит значение, которое оказалось недопустимым номером сигнала

Функция pcntl_sigprocmask() теперь выбрасывает ошибку ValueError, если в аргументе mode передали значение, которое не входит в список: SIG_BLOCK, SIG_UNBLOCK или SIG_SETMASK.

Функция pcntl_sigtimedwait() теперь выбрасывает ошибку:

  • ValueError, если значение аргумента seconds меньше 0
  • ValueError, если значение аргумента nanoseconds меньше 0 или больше 1e9
  • ValueError, если значения аргументов seconds и nanoseconds равны 0

Модуль SimpleXML

Вызов функции simplexml_import_dom() не с XML-объектом теперь вместо исключения ValueError выбрасывает ошибку TypeError.

Новые исключения и ошибки в стандартных функциях

Функция round() теперь проверяет значение параметра mode и выбрасывает ошибку ValueError для недопустимых режимов. Раньше функция интерпретировала недопустимые режимы округления как режим PHP_ROUND_HALF_UP.

Функция str_getcsv() теперь выбрасывает ошибку ValueError, когда длина разделителя separator и ограничителя полей enclosure не равна одному байту, или если в аргументе символа экранирования escape не передали однобайтовый символ или пустую строку. Это выравнивает поведение функции, чтобы оно было идентично поведению функций fputcsv() и fgetcsv().

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

Опция "allowed_classes" функции unserialize() теперь выбрасывает исключения TypeError и ValueError, если в аргументе передали не массив (array) имён классов.

Класс XMLReader

Передача недопустимой кодировки символов в метод XMLReader::open() или XMLReader::XML() теперь выбрасывает ошибку ValueError.

Передача строки (string), которая содержит нулевые байты, раньше выдавала предупреждение, а теперь выбрасывает ошибку ValueError.

Класс XMLWriter

Передача строки (string), которая содержит нулевые байты, раньше выдавала предупреждение, а теперь выбрасывает ошибку ValueError.

Модуль XSL

Метод XSLTProcessor::setParameter() теперь выбрасывает ошибку ValueError, если значения аргументов содержат нулевые байты. Метод никогда не работал корректно, поэтому теперь такое поведение приводит к исключению.

Вызов метода XSLTProcessor::importStyleSheet() не с XML-объектом теперь вместо исключения ValueError выбрасывает ошибку TypeError.

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

Модуль DOM

Отдельные методы модуля DOM раньше возвращали значение false или выбрасывали исключение DOMException с кодом DOM_PHP_ERR, если не получалось выделить новый узел. Теперь методы постоянно выбрасывают исключение DOMException с кодом DOM_INVALID_STATE_ERR. Такая ситуация в крайней степени маловероятна и вряд ли затронет прежний код. В итоге вместо типа DOMDocument|false методу DOMImplementation::createDocument() назначили предварительный тип возврата DOMDocument.

Раньше объекты DOMXPath разрешали клонировать, но в итоге получался непригодный объект. Клонирование объекта DOMXPath больше невозможно и теперь выбрасывает ошибку Error.

Метод DOMImplementation::getFeature() удалили.

Класс GMP

Класс GMP сделали окончательным и поэтому расширение класса теперь невозможно.

Модуль MBString

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

Для строк в кодировке SJIS-Mac, или её псевдониме MacJapanese, индексы символов, которые передают в функцию mb_substr(), теперь ссылаются на индексы кодовых точек кодировки Unicode, которые получаются при преобразовании строки в Unicode. Это важно, поскольку около 40 символов кодировки SJIS-Mac преобразовываются в последовательность из нескольких кодовых точек Unicode.

Модуль MySQLi

Невостребованную и незадокументированную константу MYSQLI_SET_CHARSET_DIR удалили.

Константу MYSQLI_STMT_ATTR_PREFETCH_ROWS удалили. Функция недоступна в драйвере mysqlnd.

Константы MYSQLI_CURSOR_TYPE_FOR_UPDATE и MYSQLI_CURSOR_TYPE_SCROLLABLE удалили. Этот функционал никогда не реализовывали ни в драйвере mysqlnd, ни в библиотеке libmysql.

Невостребованную константу MYSQLI_TYPE_INTERVAL — заглушку и псевдоним константы MYSQLI_TYPE_ENUM — удалили.

Драйвер MySQLnd

Код ошибки, которым сообщают о превышении времени ожидания сервера MySQL, изменили с 2006 на 4031 для серверов MySQL версии 8.0.24 и выше.

Модуль Opcache

Максимальное значение директивы opcache.interned_strings_buffer в 64-разрядных архитектурах теперь составляет 32767 МБ. Раньше значение составляло 4095 мегабайтов.

Компилятор JIT

Значения конфигурации по умолчанию для JIT-компилятора изменились с opcache.jit=tracing на opcache.jit=disable и с opcache.jit_buffer_size=0 на opcache.jit_buffer_size=64M.

Это не влияет на поведение наблюдаемых объектов по умолчанию, поскольку JIT по-прежнему отключён по умолчанию. Однако теперь JIT-компиляция отключается параметром opcache.jit, а не opcache.jit_buffer_size. Изменение затронет пользователей, которые раньше включали JIT только директивой opcache.jit_buffer_size, но не указывали режим JIT-компиляции в директиве opcache.jit. Поэтому чтобы включить JIT-компиляцию потребуется указать значение конфигурации для директивы opcache.jit.

Теперь при включённой JIT-компиляции PHP будет завершаться с критической ошибкой при запуске, если инициализация JIT-компилятора по какой-либо причине не удалась.

Модуль PCNTL

Функции pcntl_sigprocmask(), pcntl_sigwaitinfo() и pcntl_sigtimedwait() теперь при каждом вызове возвращают значение false, если возникла ошибка. Раньше в отдельных случаях функции иногда возвращали значение -1.

Модуль PCRE

Библиотеку pcre2lib, которая идёт в комплекте поставки, обновили до версии 10.44. Поэтому запись {,3} теперь распознается как квантификатор, а не как текст. Кроме того, изменилось значение отдельных классов символов в режиме UCP. Полный перечень изменений приводит » список изменений PCRE2.

Драйвер PDO_DBLIB

Атрибуты Pdo\Dblib::ATTR_STRINGIFY_UNIQUEIDENTIFIER и Pdo\Dblib::ATTR_DATETIME_CONVERT теперь действуют как логические атрибуты вместо целочисленных. Поэтому установка атрибута методом PDO::setAttribute() и получение атрибута методом PDO::getAttribute() ожидает и возвращает логическое значение (bool).

Драйвер PDO_FIREBIRD

Атрибут PDO::ATTR_AUTOCOMMIT теперь действует как логический атрибут вместо целочисленного. Поэтому установка атрибута методом PDO::setAttribute() и получение атрибута методом PDO::getAttribute() ожидает и возвращает логическое значение (bool).

Модуль теперь раскрывает отдельные API-интерфейсы СУБД Firebird на языке C++, поэтому для сборки модуля теперь требуется компилятор C++. Более того, теперь модуль потребуется скомпилировать с библиотекой fbclient 3.0 или выше.

Драйвер PDO_MYSQL

Атрибуты PDO::ATTR_AUTOCOMMIT, PDO::ATTR_EMULATE_PREPARES и PDO::MYSQL_ATTR_DIRECT_QUERY теперь действуют как логические атрибуты вместо целочисленных. Поэтому установка атрибута методом PDO::setAttribute() и получение атрибута методом PDO::getAttribute() ожидает и возвращает логическое значение (bool).

Драйвер PDO_PGSQL

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

Модуль SimpleXML

Объект класса SimpleXMLElement — представляет не только элемент в XML-документе, но и интерфейс RecursiveIterator. До PHP 8.4.0 отдельные методы класса наподобие SimpleXMLElement::asXML() или SimpleXMLElement::getName() и приведение таких экземпляров к строке (string) неявно сбрасывали итератор.

Такое поведение иногда делало циклы бесконечными, поскольку итератор отматывался к первому элементу. Приведём пример. Следующий код:

<?php

$xmlString
= "<root><a><b>1</b><b>2</b><b>3</b></a></root>";
$xml = simplexml_load_string($xmlString);

$nodes = $xml->a->b;
foreach (
$nodes as $nodeData) {
echo
"Данные узла: " . $nodeData . "\n";

$xml = $nodes->asXml();
}

…вызовет бесконечный цикл.

Данные узла: 1
Данные узла: 2
Данные узла: 2
Данные узла: 2
Данные узла: 2
Данные узла: 2
Данные узла: 2
// ...

Это поведение исправили, и элемент SimpleXMLElement больше не будет неявно сбрасывать данные итератора, если только итератор не отмотают вручную. Поэтому приведённый пример теперь будет выводить следующие данные:

Данные узла: 1
Данные узла: 2
Данные узла: 3

Модуль SOAP

Разработчики представили свойство SoapClient::$typemap массивом (array), а не ресурсом (resource). Проверки функцией is_resource() наподобие is_resource($client->typemap) потребуется заменить проверкой на null вроде $client->typemap !== null.

Модуль SOAP получил необязательную зависимость от модуля session. Теперь при запуске будут возникать ошибки, если включить модуль SOAP, а PHP собрать без модуля session, но с флагом конфигурации --enable-rtld-now. Проблему решают двумя способами: либо не включают режим rtld-now, либо загружают модуль сессий.

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

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

Функция http_build_query() теперь корректно обрабатывает типизированные перечисления.

Функции stream_bucket_make_writeable() и stream_bucket_new() теперь возвращают экземпляр класса StreamBucket, а не класса stdClass.

Модуль Tidy

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

Парсер XML

Функции семейства xml_set_()*_handler() теперь объявляют и проверяют сигнатуру callable|string|null параметров handler. Больше того, значения с типом string, которые соответствуют названиям методов, которые задали функцией xml_set_object(), теперь проверяются на существование метода в классе объекта, который передали прежде. Поэтому теперь перед установкой названий методов, которые устанавливаются как callable-обработчики, требуется каждый раз вызывать функцию xml_set_object(). Передача пустой строки для отключения обработчика по-прежнему разрешается, но устарела.

Однако, поскольку функция xml_set_object() и передача строк, которые не принадлежат типу callable, устарели, рекомендуют заменить такие экземпляры callable-обработчиками, которые ссылаются непосредственно на метод.

Добавить

Примечания пользователей

Пользователи ещё не добавляли примечания для страницы
To Top