Каждая новая функция, класс, интерфейс, перечисление или константа станет причиной ошибки Error о повторном объявлении, которую выбросит PHP, если встретит в коде объявление с тем же названием, хотя раздел не указывает это в явной форме.
    Поведение языковой конструкции exit() и её псевдонима die()
    теперь больше похоже на функции:
    их разрешили передавать как значения с типом callable,
    на поведение функций теперь влияет директива strict_types
    управляющей конструкции declare и теперь они выполняют стандартные преобразования типов
    вместо приведения нецелочисленных значений к строке.
   
Поэтому передача недопустимых типов в функции exit() и die() теперь выбрасывает ошибку TypeError.
    Появление рекурсии при сравнении теперь выбрасывает
    ошибку Error вместо
    ошибки уровня E_ERROR.
   
    Непрямую модификацию доступных только для чтения свойств внутри магического метода
    __clone() запретили, например, присваивание по ссылке $ref = &$this->readonly
    вызовет фатальную ошибку. Инициализацию доступных только для чтения свойств запретили раньше
    и упустили в реализации «повторной инициализации доступных только для чтения свойств
    при клонировании».
   
    Константы PHP_DEBUG и PHP_ZTS
    теперь принадлежат логическому типу bool.
    Раньше константы принадлежали целочисленному типу int.
   
Длину имён файлов, которые загрузили, и файлов, которые создали функцией tempnam(), увеличили на 13 байтов. Общая длина по-прежнему зависит от платформы.
Следующие модули теперь объявляют тип для констант своих классах:
   Ряд ресурсов (resource) перенесли в объекты (object).
   Значения, которые возвращали функции-создатели ресурсов и которые
   проверяли функцией is_resource(), потребуется заменить
   проверками значений возврата таких функций на принадлежность типу false,
   если только в описании функции не указали иное.
  
    Функции модуля DBA теперь принимают и возвращают объекты
    Dba\Connection вместо ресурсов (resource) dba_connection.
   
    Функции драйвера ODBC теперь принимают и возвращают объекты
    Odbc\Result вместо ресурсов (resource) odbc_result.
   
    Функции драйвера ODBC теперь принимают и возвращают объекты
    Odbc\Connection вместо ресурсов (resource) odbc_connection.
   
    Разработчики представили свойство 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_multi_select() теперь выбрасывает
    ошибку ValueError,
    если аргумент timeout меньше 0
    или больше значения константы PHP_INT_MAX.
   
    Функции
    imagejpeg(), imagewebp(), imagepng(), imageavif()
    теперь выбрасывают ошибку ValueError,
    если в параметр quality передали недопустимое значение.
   
    Функция imageavif()
    теперь выбрасывает ошибку ValueError,
    если в параметр speed передали недопустимое значение.
   
    Функция imagescale()
    теперь выбрасывает ошибку ValueError,
    если ширина width или высота height
    выходит за пределы допустимых значений: недополнено или переполнено.
   
    Функция imagescale()
    теперь выбрасывают ошибку ValueError,
    если передали недопустимое значение в параметр mode.
   
    Функция imagefilter() с фильтром IMG_FILTER_SCATTER
    теперь выбрасывают ошибку ValueError,
    если значение вычитания sub или добавления plus
    эффекта выходит за пределы допустимых значений: недополнено или переполнено.
   
    Функции
    bind_textdomain_codeset(), textdomain(), d()*gettext()
    теперь выбрасывают ошибку ValueError,
    если в аргументе domain передали пустую строку.
   
Функции resourcebundle_get(), ResourceBundle::get() и обращение к смещениям объекта ResourceBundle теперь выбрасывают исключение:
    Метод IntlDateFormatter::__construct()
    теперь выбрасывает ошибку ValueError,
    если в параметр locale передали недопустимое значение.
   
    Метод NumberFormatter::__construct()
    теперь выбрасывает ошибку ValueError,
    если в параметр locale передали недопустимое значение.
   
    Теперь функции mb_encode_numericentity()
    и mb_decode_numericentity() проверяют,
    что значение параметра map состоит только из целых числел (int),
    иначе выбрасывают ошибку ValueError.
   
    Теперь функция mb_http_input()
    выбрасывает ошибку ValueError при каждом вызове,
    если в параметр type передали недопустимое значение.
   
    Теперь функция mb_http_output() проверяет,
    что значение параметра encoding не содержит нулевых байтов,
    иначе выбрасывает ошибку ValueError.
   
    Функция odbc_fetch_row() раньше возвращала значение false,
    если значение аргумента row оказывалось меньше или равно 0.
    Теперь функция выдаёт предупреждение.
   
Функции pcntl_sigprocmask(), pcntl_sigwaitinfo() и pcntl_sigtimedwait() теперь выбрасывают исключение:
signals оказался пустым
      (за исключением функции pcntl_sigprocmask(),
      если для параметра mode установили режим SIG_SETMASK)
     signals содержит значение, которое не принадлежит типу int
     signals содержит значение, которое оказалось недопустимым номером сигнала
     
    Функция pcntl_sigprocmask() теперь выбрасывает
    ошибку ValueError, если в аргументе mode
    передали значение, которое не входит в список: SIG_BLOCK, SIG_UNBLOCK
    или SIG_SETMASK.
   
Функция pcntl_sigtimedwait() теперь выбрасывает ошибку:
seconds меньше 0
     nanoseconds меньше 0
      или больше 1e9
     seconds и nanoseconds
      равны 0
     Установка неположительного значения в директиве session.gc_divisor или отрицательного значения в директиве session.gc_probability теперь выдаёт предупреждение.
Вызов функции 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::open() или XMLReader::XML() теперь выбрасывает ошибку ValueError.
Передача строки (string), которая содержит нулевые байты, раньше выдавала предупреждение, а теперь выбрасывает ошибку ValueError.
Передача строки (string), которая содержит нулевые байты, раньше выдавала предупреждение, а теперь выбрасывает ошибку ValueError.
Метод XSLTProcessor::setParameter() теперь выбрасывает ошибку ValueError, если значения аргументов содержат нулевые байты. Метод никогда не работал корректно, поэтому теперь такое поведение приводит к исключению.
Вызов метода XSLTProcessor::importStyleSheet() не с XML-объектом теперь вместо исключения ValueError выбрасывает ошибку TypeError.
Невозможность вызвать callback-функцию во время оценки теперь выбрасывает исключение, а не выдаёт предупреждение.
   Синтаксис относительных форматов снова принимает
   в символах number множественные знаки числа: +-2.
  
   Отдельные методы модуля DOM раньше возвращали значение false
   или выбрасывали исключение DOMException с кодом
   DOM_PHP_ERR, если не получалось выделить новый узел.
   Теперь методы постоянно выбрасывают исключение DOMException
   с кодом DOM_INVALID_STATE_ERR.
   Такая ситуация в крайней степени маловероятна и вряд ли затронет прежний код.
   В итоге вместо типа DOMDocument|false методу
   DOMImplementation::createDocument() назначили предварительный
   тип возврата DOMDocument.
  
Раньше объекты DOMXPath разрешали клонировать, но в итоге получался непригодный объект. Клонирование объекта DOMXPath больше невозможно и теперь выбрасывает ошибку Error.
Метод DOMImplementation::getFeature() удалили.
Класс GMP сделали окончательным и поэтому расширение класса теперь невозможно.
В недопустимых строках с ошибками кодировки функция mb_substr() теперь интерпретирует индексы символов аналогично большей части других функций для работы с многобайтовыми строками. Поэтому символьные индексы, которые возвращает функция mb_strpos(), разрешили передавать в функцию mb_substr().
Для строк в кодировке SJIS-Mac, или её псевдониме MacJapanese, индексы символов, которые передают в функцию mb_substr(), теперь ссылаются на индексы кодовых точек кодировки Unicode, которые получаются при преобразовании строки в Unicode. Это важно, поскольку около 40 символов кодировки SJIS-Mac преобразовываются в последовательность из нескольких кодовых точек Unicode.
   Невостребованную и незадокументированную константу
   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 —
   удалили.
  
   Код ошибки, которым сообщают о превышении времени ожидания сервера MySQL,
   изменили с 2006 на 4031
   для серверов MySQL версии 8.0.24 и выше.
  
   Максимальное значение директивы
   opcache.interned_strings_buffer
   в 64-разрядных архитектурах теперь составляет 32767 МБ.
   Раньше значение составляло 4095 мегабайтов.
  
    Значения конфигурации по умолчанию для 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_sigprocmask(),
   pcntl_sigwaitinfo()
   и pcntl_sigtimedwait() теперь при каждом вызове
   возвращают значение false, если возникла ошибка.
   Раньше в отдельных случаях функции иногда возвращали значение -1.
  
   Библиотеку pcre2lib, которая идёт в комплекте поставки, обновили до версии 10.44.
   Поэтому запись {,3} теперь распознается как квантификатор, а не как текст.
   Кроме того, изменилось значение отдельных классов символов в режиме UCP.
   Полный перечень изменений приводит
   » список изменений PCRE2.
  
   Атрибуты Pdo\Dblib::ATTR_STRINGIFY_UNIQUEIDENTIFIER
   и Pdo\Dblib::ATTR_DATETIME_CONVERT теперь действуют как логические атрибуты
   вместо целочисленных.
   Поэтому установка атрибута методом PDO::setAttribute()
   и получение атрибута методом PDO::getAttribute() ожидает
   и возвращает логическое значение (bool).
  
   Атрибут PDO::ATTR_AUTOCOMMIT теперь действует как логический атрибут
   вместо целочисленного.
   Поэтому установка атрибута методом PDO::setAttribute()
   и получение атрибута методом PDO::getAttribute() ожидает
   и возвращает логическое значение (bool).
  
Модуль теперь раскрывает отдельные API-интерфейсы СУБД Firebird на языке C++, поэтому для сборки модуля теперь требуется компилятор C++. Более того, теперь модуль потребуется скомпилировать с библиотекой fbclient 3.0 или выше.
   Атрибуты PDO::ATTR_AUTOCOMMIT, PDO::ATTR_EMULATE_PREPARES
   и PDO::MYSQL_ATTR_DIRECT_QUERY теперь действуют как логические
   атрибуты вместо целочисленных.
   Поэтому установка атрибута методом PDO::setAttribute()
   и получение атрибута методом PDO::getAttribute()
   ожидает и возвращает логическое значение (bool).
  
Приоритет учётных данных, которые указали в DSN-строке подключения конструктора класса PDO, выше, чем приоритет учётных данных, которые указали во втором и третьем аргументах конструктора, поскольку учётные данные в DSN-строке подключения ближе к положениям документации.
Объект класса 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
   Разработчики представили свойство 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.
Теперь вместо предупреждений и повреждения объекта сбои в конструкторе выбрасывают исключение.
   Функции семейства xml_set_()*_handler()
   теперь объявляют и проверяют сигнатуру
   callable|string|null
   параметров handler.
   Больше того, значения с типом string, которые соответствуют названиям методов,
   которые задали функцией xml_set_object(),
   теперь проверяются на существование метода в классе объекта, который передали прежде.
   Поэтому теперь перед установкой названий методов, которые устанавливаются как callable-обработчики,
   требуется каждый раз вызывать функцию xml_set_object().
   Передача пустой строки для отключения обработчика по-прежнему разрешается, но устарела.
  
Однако, поскольку функция xml_set_object() и передача строк, которые не принадлежат типу callable, устарели, рекомендуют заменить такие экземпляры callable-обработчиками, которые ссылаются непосредственно на метод.
