<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/migration84.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'ru',
  ),
  'this' => 
  array (
    0 => 'migration84.incompatible.php',
    1 => 'Изменения, которые ломают обратную совместимость',
    2 => 'Изменения, которые ломают обратную совместимость',
  ),
  'up' => 
  array (
    0 => 'migration84.php',
    1 => 'Миграция с PHP 8.3.x на PHP 8.4.x',
  ),
  'prev' => 
  array (
    0 => 'migration84.constants.php',
    1 => 'Новые глобальные константы',
  ),
  'next' => 
  array (
    0 => 'migration84.deprecated.php',
    1 => 'Устаревшая функциональность',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'ru',
    'path' => 'appendices/migration84/incompatible.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="migration84.incompatible" class="sect1">
 <h2 class="title">Изменения, которые ломают обратную совместимость</h2>

 <p class="simpara">
  Каждая новая <a href="migration84.new-functions.php" class="link">функция</a>,
  <a href="migration84.new-classes.php" class="link">класс, интерфейс, перечисление</a>
  или <a href="migration84.constants.php" class="link">константа</a>
  станет причиной ошибки <span class="exceptionname"><a href="class.error.php" class="exceptionname">Error</a></span> о повторном объявлении,
  которую выбросит PHP, если встретит в коде объявление с тем же названием,
  хотя раздел не указывает это в явной форме.
 </p>

 <div class="sect2" id="migration84.incompatible.core">
  <h3 class="title">Ядро PHP</h3>

  <div class="sect3" id="migration84.incompatible.core.exit">
   <h4 class="title">Изменение поведения языковой конструкции <span class="function"><a href="function.exit.php" class="function">exit()</a></span></h4>

   <p class="simpara">
    Поведение языковой конструкции <span class="function"><a href="function.exit.php" class="function">exit()</a></span> и её псевдонима <span class="function"><a href="function.die.php" class="function">die()</a></span>
    теперь больше похоже на функции:
    их разрешили передавать как значения с типом <span class="type"><a href="language.types.callable.php" class="type callable">callable</a></span>,
    на поведение функций теперь влияет директива <code class="literal">strict_types</code>
    управляющей конструкции <a href="control-structures.declare.php" class="link"><code class="literal">declare</code></a> и теперь они выполняют стандартные преобразования типов
    вместо приведения нецелочисленных значений к строке.
   </p>

   <p class="simpara">
    Поэтому передача недопустимых типов в функции <span class="function"><a href="function.exit.php" class="function">exit()</a></span>
    и <span class="function"><a href="function.die.php" class="function">die()</a></span> теперь выбрасывает ошибку
    <span class="exceptionname"><a href="class.typeerror.php" class="exceptionname">TypeError</a></span>.
   </p>
  </div>

  <div class="sect3" id="migration84.incompatible.core.recursion-comparison">
   <h4 class="title">Рекурсия при сравнении</h4>

   <p class="simpara">
    Появление рекурсии при сравнении теперь выбрасывает
    ошибку <span class="exceptionname"><a href="class.error.php" class="exceptionname">Error</a></span> вместо
    ошибки уровня <strong><code><a href="errorfunc.constants.php#constant.e-error">E_ERROR</a></code></strong>.
   </p>
  </div>

  <div class="sect3" id="migration84.incompatible.core.readonly-indirect-modification">
   <h4 class="title">Непрямая модификация доступных только для чтения свойств</h4>

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

  <div class="sect3" id="migration84.incompatible.core.constant-type-change">
   <h4 class="title">Изменение типа констант</h4>

   <p class="simpara">
    Константы <strong><code><a href="reserved.constants.php#constant.php-debug">PHP_DEBUG</a></code></strong> и <strong><code><a href="reserved.constants.php#constant.php-zts">PHP_ZTS</a></code></strong>
    теперь принадлежат логическому типу <span class="type"><a href="language.types.boolean.php" class="type bool">bool</a></span>.
    Раньше константы принадлежали целочисленному типу <span class="type"><a href="language.types.integer.php" class="type int">int</a></span>.
   </p>
  </div>

  <div class="sect3" id="migration84.incompatible.core.tempnam-length">
   <h4 class="title">Длина имени временного файла</h4>

   <p class="simpara">
    Длину имён файлов, которые загрузили, и файлов, которые создали функцией
    <span class="function"><a href="function.tempnam.php" class="function">tempnam()</a></span>, увеличили на 13 байтов.
    Общая длина по-прежнему зависит от платформы.
   </p>
  </div>

  <div class="sect3" id="migration84.incompatible.core.e-strict">
   <h4 class="title">Удаление уровня ошибки <strong><code><a href="errorfunc.constants.php#constant.e-strict">E_STRICT</a></code></strong></h4>

   <p class="simpara">
    Уровень ошибки <strong><code><a href="errorfunc.constants.php#constant.e-strict">E_STRICT</a></code></strong> удалили,
    поскольку движок PHP больше с ним не работает.
    Константа <strong><code><a href="errorfunc.constants.php#constant.e-strict">E_STRICT</a></code></strong> устарела.
   </p>
  </div>
 </div>

 <div class="sect2" id="migration84.incompatible.typed-constants">
  <h3 class="title">Типизация констант в классах модулей</h3>

  <p class="para">
   Следующие модули теперь объявляют тип для констант своих классах:
   <ul class="simplelist">
    <li><a href="book.datetime.php" class="link">Date</a></li>
    <li><a href="book.intl.php" class="link">Intl</a></li>
    <li><a href="book.pdo.php" class="link">PDO</a></li>
    <li><a href="book.reflection.php" class="link">Reflection</a></li>
    <li><a href="book.spl.php" class="link">SPL</a></li>
    <li><a href="book.sqlite3.php" class="link">Sqlite</a></li>
    <li><a href="book.xmlreader.php" class="link">XMLReader</a></li>
   </ul>
  </p>
 </div>

 <div class="sect2" id="migration84.incompatible.resource2object">
  <h3 class="title">Миграция ресурсов в объекты</h3>

  <p class="simpara">
   Ряд ресурсов (<span class="type"><a href="language.types.resource.php" class="type resource">resource</a></span>) перенесли в объекты (<span class="type"><a href="language.types.object.php" class="type object">object</a></span>).
   Значения, которые возвращали функции-создатели ресурсов и которые
   проверяли функцией <span class="function"><a href="function.is-resource.php" class="function">is_resource()</a></span>, потребуется заменить
   проверками значений возврата таких функций на принадлежность типу <strong><code><a href="reserved.constants.php#constant.false">false</a></code></strong>,
   если только в описании функции не указали иное.
  </p>

  <div class="sect3" id="migration84.incompatible.resource2object.dba">
   <h4 class="title">Модуль DBA</h4>

   <p class="simpara">
    Функции модуля <a href="book.dba.php" class="link">DBA</a> теперь принимают и возвращают объекты
    <span class="classname"><a href="class.dba-connection.php" class="classname">Dba\Connection</a></span> вместо ресурсов (<span class="type"><a href="language.types.resource.php" class="type resource">resource</a></span>) <code class="literal">dba_connection</code>.
   </p>
  </div>

  <div class="sect3" id="migration84.incompatible.resource2object.odbc">
   <h4 class="title">Драйвер ODBC</h4>

   <p class="simpara">
    Функции драйвера <a href="book.uodbc.php" class="link">ODBC</a> теперь принимают и возвращают объекты
    <span class="classname"><strong class="classname">Odbc\Result</strong></span> вместо ресурсов (<span class="type"><a href="language.types.resource.php" class="type resource">resource</a></span>) <code class="literal">odbc_result</code>.
   </p>

   <p class="simpara">
    Функции драйвера <a href="book.uodbc.php" class="link">ODBC</a> теперь принимают и возвращают объекты
    <span class="classname"><strong class="classname">Odbc\Connection</strong></span> вместо ресурсов (<span class="type"><a href="language.types.resource.php" class="type resource">resource</a></span>) <code class="literal">odbc_connection</code>.
   </p>
  </div>

  <div class="sect3" id="migration84.incompatible.resource2object.soap">
   <h4 class="title">SOAP</h4>

   <p class="simpara">
    Разработчики представили свойство <span class="property"><a href="class.soapclient.php#soapclient.props.httpurl">SoapClient::$httpurl</a></span>
    объектом <span class="classname"><strong class="classname">Soap\Url</strong></span>, а не ресурсом (<span class="type"><a href="language.types.resource.php" class="type resource">resource</a></span>) <code class="literal">soap_url</code>.
    Проверки функцией <span class="function"><a href="function.is-resource.php" class="function">is_resource()</a></span> наподобие
    <code class="code">is_resource($client-&gt;httpurl)</code>) потребуется заменить проверками
    на <strong><code><a href="reserved.constants.php#constant.null">null</a></code></strong> вроде <code class="code">$client-&gt;httpurl !== null</code>.
   </p>
   <p class="simpara">
    Разработчики представили свойство <span class="property"><a href="class.soapclient.php#soapclient.props.sdl">SoapClient::$sdl</a></span>
    объектом <span class="classname"><strong class="classname">Soap\Sdl</strong></span>, а не ресурсом (<span class="type"><a href="language.types.resource.php" class="type resource">resource</a></span>) <code class="literal">soap_sdl</code>.
    Проверки функции <span class="function"><a href="function.is-resource.php" class="function">is_resource()</a></span> наподобие
    <code class="code">is_resource($client-&gt;sdl)</code> потребуется заменить проверками
    на <strong><code><a href="reserved.constants.php#constant.null">null</a></code></strong> вроде <code class="code">$client-&gt;sdl !== null</code>.
   </p>
  </div>
 </div>

 <div class="sect2" id="migration84.incompatible.new-warnings-exceptions">
  <h3 class="title">Новые предупреждения и исключения</h3>

  <p class="simpara">
   Разработчики добавили новые предупреждения и исключения, которые срабатывают
   при ошибках программирования, — когда в аргументах передают
   недопустимые значения.
  </p>

  <div class="sect3" id="migration84.incompatible.new-warnings-exceptions.curl">
   <h4 class="title">Модуль Curl</h4>

   <p class="simpara">
    Функция <span class="function"><a href="function.curl-multi-select.php" class="function">curl_multi_select()</a></span> теперь выбрасывает
    ошибку <span class="exceptionname"><a href="class.valueerror.php" class="exceptionname">ValueError</a></span>,
    если аргумент <code class="parameter">timeout</code> меньше <code class="literal">0</code>
    или больше значения константы <strong><code><a href="reserved.constants.php#constant.php-int-max">PHP_INT_MAX</a></code></strong>.
   </p>
  </div>

  <div class="sect3" id="migration84.incompatible.new-warnings-exceptions.gd">
   <h4 class="title">Модуль Gd</h4>

   <p class="para">
    Функции
    <span class="simplelist"><span class="function"><a href="function.imagejpeg.php" class="function">imagejpeg()</a></span>, <span class="function"><a href="function.imagewebp.php" class="function">imagewebp()</a></span>, <span class="function"><a href="function.imagepng.php" class="function">imagepng()</a></span>, <span class="function"><a href="function.imageavif.php" class="function">imageavif()</a></span></span>
    теперь выбрасывают ошибку <span class="exceptionname"><a href="class.valueerror.php" class="exceptionname">ValueError</a></span>,
    если в параметр <code class="parameter">quality</code> передали недопустимое значение.
   </p>

   <p class="simpara">
    Функция <span class="function"><a href="function.imageavif.php" class="function">imageavif()</a></span>
    теперь выбрасывает ошибку <span class="exceptionname"><a href="class.valueerror.php" class="exceptionname">ValueError</a></span>,
    если в параметр <code class="parameter">speed</code> передали недопустимое значение.
   </p>

   <p class="simpara">
    Функция <span class="function"><a href="function.imagescale.php" class="function">imagescale()</a></span>
    теперь выбрасывает ошибку <span class="exceptionname"><a href="class.valueerror.php" class="exceptionname">ValueError</a></span>,
    если ширина <code class="parameter">width</code> или высота <code class="parameter">height</code>
    выходит за пределы допустимых значений: недополнено или переполнено.
   </p>

   <p class="simpara">
    Функция <span class="function"><a href="function.imagescale.php" class="function">imagescale()</a></span>
    теперь выбрасывают ошибку <span class="exceptionname"><a href="class.valueerror.php" class="exceptionname">ValueError</a></span>,
    если передали недопустимое значение в параметр <code class="parameter">mode</code>.
   </p>

   <p class="simpara">
    Функция <span class="function"><a href="function.imagefilter.php" class="function">imagefilter()</a></span> с фильтром <strong><code><a href="image.constants.php#constant.img-filter-scatter">IMG_FILTER_SCATTER</a></code></strong>
    теперь выбрасывают ошибку <span class="exceptionname"><a href="class.valueerror.php" class="exceptionname">ValueError</a></span>,
    если значение вычитания <code class="parameter">sub</code> или добавления <code class="parameter">plus</code>
    эффекта выходит за пределы допустимых значений: недополнено или переполнено.
   </p>
  </div>

  <div class="sect3" id="migration84.incompatible.new-warnings-exceptions.gettext">
   <h4 class="title">Модуль Gettext</h4>

   <p class="para">
    Функции
    <span class="simplelist"><span class="function"><a href="function.bind-textdomain-codeset.php" class="function">bind_textdomain_codeset()</a></span>, <span class="function"><a href="function.textdomain.php" class="function">textdomain()</a></span>, <span class="function">d<span class="replaceable">*</span>gettext</span></span>
    теперь выбрасывают ошибку <span class="exceptionname"><a href="class.valueerror.php" class="exceptionname">ValueError</a></span>,
    если в аргументе <code class="parameter">domain</code> передали пустую строку.
   </p>
  </div>

  <div class="sect3" id="migration84.incompatible.new-warnings-exceptions.intl">
   <h4 class="title">Модуль Intl</h4>

   <p class="para">
    Функции <span class="function"><a href="resourcebundle.get.php" class="function">resourcebundle_get()</a></span>, <span class="methodname"><a href="resourcebundle.get.php" class="methodname">ResourceBundle::get()</a></span>
    и обращение к смещениям объекта <span class="classname"><a href="class.resourcebundle.php" class="classname">ResourceBundle</a></span> теперь выбрасывают исключение:
    <ul class="simplelist">
     <li>
      <span class="exceptionname"><a href="class.typeerror.php" class="exceptionname">TypeError</a></span> при недопустимых типах смещения
     </li>
     <li>
      <span class="exceptionname"><a href="class.valueerror.php" class="exceptionname">ValueError</a></span> при передаче пустой строки (<span class="type"><a href="language.types.string.php" class="type string">string</a></span>)
     </li>
     <li>
      <span class="exceptionname"><a href="class.valueerror.php" class="exceptionname">ValueError</a></span>, если целочисленный индекс
      не помещается в 32-битное целое число со знаком
     </li>
    </ul>
   </p>

   <p class="simpara">
    Метод <span class="methodname"><a href="intldateformatter.create.php" class="methodname">IntlDateFormatter::__construct()</a></span>
    теперь выбрасывает ошибку <span class="exceptionname"><a href="class.valueerror.php" class="exceptionname">ValueError</a></span>,
    если в параметр <code class="parameter">locale</code> передали недопустимое значение.
   </p>

   <p class="simpara">
    Метод <span class="methodname"><a href="numberformatter.create.php" class="methodname">NumberFormatter::__construct()</a></span>
    теперь выбрасывает ошибку <span class="exceptionname"><a href="class.valueerror.php" class="exceptionname">ValueError</a></span>,
    если в параметр <code class="parameter">locale</code> передали недопустимое значение.
   </p>
  </div>

  <div class="sect3" id="migration84.incompatible.new-warnings-exceptions.mbstring">
   <h4 class="title">Модуль MBString</h4>

   <p class="simpara">
    Теперь функции <span class="function"><a href="function.mb-encode-numericentity.php" class="function">mb_encode_numericentity()</a></span>
    и <span class="function"><a href="function.mb-decode-numericentity.php" class="function">mb_decode_numericentity()</a></span> проверяют,
    что значение параметра <code class="parameter">map</code> состоит только из целых числел (<span class="type"><a href="language.types.integer.php" class="type int">int</a></span>),
    иначе выбрасывают ошибку <span class="exceptionname"><a href="class.valueerror.php" class="exceptionname">ValueError</a></span>.
   </p>

   <p class="simpara">
    Теперь функция <span class="function"><a href="function.mb-http-input.php" class="function">mb_http_input()</a></span>
    выбрасывает ошибку <span class="exceptionname"><a href="class.valueerror.php" class="exceptionname">ValueError</a></span> при каждом вызове,
    если в параметр <code class="parameter">type</code> передали недопустимое значение.
   </p>

   <p class="simpara">
    Теперь функция <span class="function"><a href="function.mb-http-output.php" class="function">mb_http_output()</a></span> проверяет,
    что значение параметра <code class="parameter">encoding</code> не содержит нулевых байтов,
    иначе выбрасывает ошибку <span class="exceptionname"><a href="class.valueerror.php" class="exceptionname">ValueError</a></span>.
   </p>
  </div>

  <div class="sect3" id="migration84.incompatible.new-warnings-exceptions.odbc">
   <h4 class="title">ODBC</h4>

   <p class="simpara">
    Функция <span class="function"><a href="function.odbc-fetch-row.php" class="function">odbc_fetch_row()</a></span> раньше возвращала значение <strong><code><a href="reserved.constants.php#constant.false">false</a></code></strong>,
    если значение аргумента <code class="parameter">row</code> оказывалось меньше или равно <code class="literal">0</code>.
    Теперь функция выдаёт предупреждение.
   </p>
  </div>

  <div class="sect3" id="migration84.incompatible.new-warnings-exceptions.pcntl">
   <h4 class="title">Модуль PCNTL</h4>

   <p class="para">
    Функции <span class="function"><a href="function.pcntl-sigprocmask.php" class="function">pcntl_sigprocmask()</a></span>,
    <span class="function"><a href="function.pcntl-sigwaitinfo.php" class="function">pcntl_sigwaitinfo()</a></span>
    и <span class="function"><a href="function.pcntl-sigtimedwait.php" class="function">pcntl_sigtimedwait()</a></span> теперь выбрасывают исключение:
    <ul class="simplelist">
     <li>
      <span class="exceptionname"><a href="class.valueerror.php" class="exceptionname">ValueError</a></span>, если массив
      <code class="parameter">signals</code> оказался пустым
      (за исключением функции <span class="function"><a href="function.pcntl-sigprocmask.php" class="function">pcntl_sigprocmask()</a></span>,
      если для параметра <code class="parameter">mode</code> установили режим <strong><code><a href="pcntl.constants.php#constant.sig-setmask">SIG_SETMASK</a></code></strong>)
     </li>
     <li>
      <span class="exceptionname"><a href="class.typeerror.php" class="exceptionname">TypeError</a></span>, если массив
      <code class="parameter">signals</code> содержит значение, которое не принадлежит типу <span class="type"><a href="language.types.integer.php" class="type int">int</a></span>
     </li>
     <li>
      <span class="exceptionname"><a href="class.valueerror.php" class="exceptionname">ValueError</a></span>, если массив
      <code class="parameter">signals</code> содержит значение, которое оказалось недопустимым номером сигнала
     </li>
    </ul>
   </p>

   <p class="simpara">
    Функция <span class="function"><a href="function.pcntl-sigprocmask.php" class="function">pcntl_sigprocmask()</a></span> теперь выбрасывает
    ошибку <span class="exceptionname"><a href="class.valueerror.php" class="exceptionname">ValueError</a></span>, если в аргументе <code class="parameter">mode</code>
    передали значение, которое не входит в список: <strong><code><a href="pcntl.constants.php#constant.sig-block">SIG_BLOCK</a></code></strong>, <strong><code><a href="pcntl.constants.php#constant.sig-unblock">SIG_UNBLOCK</a></code></strong>
    или <strong><code><a href="pcntl.constants.php#constant.sig-setmask">SIG_SETMASK</a></code></strong>.
   </p>

   <p class="para">
    Функция <span class="function"><a href="function.pcntl-sigtimedwait.php" class="function">pcntl_sigtimedwait()</a></span> теперь выбрасывает ошибку:
    <ul class="simplelist">
     <li>
      <span class="exceptionname"><a href="class.valueerror.php" class="exceptionname">ValueError</a></span>, если значение аргумента
      <code class="parameter">seconds</code> меньше <code class="literal">0</code>
     </li>
     <li>
      <span class="exceptionname"><a href="class.valueerror.php" class="exceptionname">ValueError</a></span>, если значение аргумента
      <code class="parameter">nanoseconds</code> меньше <code class="literal">0</code>
      или больше <code class="literal">1e9</code>
     </li>
     <li>
      <span class="exceptionname"><a href="class.valueerror.php" class="exceptionname">ValueError</a></span>, если значения аргументов
      <code class="parameter">seconds</code> и <code class="parameter">nanoseconds</code>
      равны <code class="literal">0</code>
     </li>
    </ul>
   </p>
  </div>

  <div class="sect3" id="migration84.incompatible.new-warnings-exceptions.session">
   <h4 class="title">Модуль Session</h4>

   <p class="simpara">
    Установка неположительного значения в директиве <a href="session.configuration.php#ini.session.gc-divisor" class="link">session.gc_divisor</a>
    или отрицательного значения в директиве <a href="session.configuration.php#ini.session.gc-probability" class="link">session.gc_probability</a>
    теперь выдаёт предупреждение.
   </p>
  </div>

  <div class="sect3" id="migration84.incompatible.new-warnings-exceptions.simplexml">
   <h4 class="title">Модуль SimpleXML</h4>

   <p class="simpara">
    Вызов функции <span class="function"><a href="function.simplexml-import-dom.php" class="function">simplexml_import_dom()</a></span> не с XML-объектом теперь
    вместо исключения <span class="exceptionname"><a href="class.valueerror.php" class="exceptionname">ValueError</a></span>
    выбрасывает ошибку <span class="exceptionname"><a href="class.typeerror.php" class="exceptionname">TypeError</a></span>.
   </p>
  </div>

  <div class="sect3" id="migration84.incompatible.new-warnings-exceptions.standard">
   <h4 class="title">Новые исключения и ошибки в стандартных функциях</h4>

   <p class="simpara">
    Функция <span class="function"><a href="function.round.php" class="function">round()</a></span> теперь проверяет значение параметра <code class="parameter">mode</code>
    и выбрасывает ошибку <span class="exceptionname"><a href="class.valueerror.php" class="exceptionname">ValueError</a></span> для недопустимых режимов.
    Раньше функция интерпретировала недопустимые режимы округления как режим <strong><code><a href="math.constants.php#constant.php-round-half-up">PHP_ROUND_HALF_UP</a></code></strong>.
   </p>

   <p class="simpara">
    Функция <span class="function"><a href="function.str-getcsv.php" class="function">str_getcsv()</a></span> теперь выбрасывает
    ошибку <span class="exceptionname"><a href="class.valueerror.php" class="exceptionname">ValueError</a></span>, когда
    длина разделителя <code class="parameter">separator</code> и ограничителя полей <code class="parameter">enclosure</code>
    не равна одному байту, или если в аргументе символа экранирования <code class="parameter">escape</code>
    не передали однобайтовый символ или пустую строку.
    Это выравнивает поведение функции, чтобы оно было идентично поведению
    функций <span class="function"><a href="function.fputcsv.php" class="function">fputcsv()</a></span> и <span class="function"><a href="function.fgetcsv.php" class="function">fgetcsv()</a></span>.
   </p>

   <p class="simpara">
    Функция <span class="function"><a href="function.php-uname.php" class="function">php_uname()</a></span> теперь выбрасывает ошибку
    <span class="exceptionname"><a href="class.valueerror.php" class="exceptionname">ValueError</a></span>,
    если значение аргумента <code class="parameter">mode</code> недопустимо.
   </p>

   <p class="simpara">
    Опция <code class="literal">&quot;allowed_classes&quot;</code> функции
    <span class="function"><a href="function.unserialize.php" class="function">unserialize()</a></span> теперь выбрасывает
    исключения <span class="exceptionname"><a href="class.typeerror.php" class="exceptionname">TypeError</a></span>
    и <span class="exceptionname"><a href="class.valueerror.php" class="exceptionname">ValueError</a></span>, если в аргументе передали
    не массив (<span class="type"><a href="language.types.array.php" class="type array">array</a></span>) имён классов.
   </p>
  </div>

  <div class="sect3" id="migration84.incompatible.new-warnings-exceptions.xmlreader">
   <h4 class="title">Класс XMLReader</h4>

   <p class="simpara">
    Передача недопустимой кодировки символов
    в метод <span class="methodname"><a href="xmlreader.open.php" class="methodname">XMLReader::open()</a></span>
    или <span class="methodname"><a href="xmlreader.xml.php" class="methodname">XMLReader::XML()</a></span> теперь выбрасывает ошибку
    <span class="exceptionname"><a href="class.valueerror.php" class="exceptionname">ValueError</a></span>.
   </p>

   <p class="simpara">
    Передача строки (<span class="type"><a href="language.types.string.php" class="type string">string</a></span>), которая содержит нулевые байты, раньше выдавала
    предупреждение, а теперь выбрасывает ошибку <span class="exceptionname"><a href="class.valueerror.php" class="exceptionname">ValueError</a></span>.
   </p>
  </div>

  <div class="sect3" id="migration84.incompatible.new-warnings-exceptions.xmlwriter">
   <h4 class="title">Класс XMLWriter</h4>

   <p class="simpara">
    Передача строки (<span class="type"><a href="language.types.string.php" class="type string">string</a></span>), которая содержит нулевые байты, раньше выдавала
    предупреждение, а теперь выбрасывает ошибку <span class="exceptionname"><a href="class.valueerror.php" class="exceptionname">ValueError</a></span>.
   </p>
  </div>

  <div class="sect3" id="migration84.incompatible.new-warnings-exceptions.xsl">
   <h4 class="title">Модуль XSL</h4>

   <p class="simpara">
    Метод <span class="methodname"><a href="xsltprocessor.setparameter.php" class="methodname">XSLTProcessor::setParameter()</a></span> теперь выбрасывает ошибку
    <span class="exceptionname"><a href="class.valueerror.php" class="exceptionname">ValueError</a></span>, если значения аргументов содержат нулевые байты.
    Метод никогда не работал корректно,
    поэтому теперь такое поведение приводит к исключению.
   </p>

   <p class="simpara">
    Вызов метода <span class="methodname"><a href="xsltprocessor.importstylesheet.php" class="methodname">XSLTProcessor::importStyleSheet()</a></span> не с XML-объектом теперь
    вместо исключения <span class="exceptionname"><a href="class.valueerror.php" class="exceptionname">ValueError</a></span>
    выбрасывает ошибку <span class="exceptionname"><a href="class.typeerror.php" class="exceptionname">TypeError</a></span>.
   </p>

   <p class="simpara">
    Невозможность вызвать callback-функцию во время оценки теперь выбрасывает исключение,
    а не выдаёт предупреждение.
   </p>
  </div>
 </div>

 <div class="sect2" id="migration84.incompatible.date">
  <h3 class="title">Date</h3>

  <p class="para">
   Синтаксис <a href="datetime.formats.php#datetime.formats.relative" class="link">относительных форматов</a> снова принимает
   в символах <code class="literal">number</code> множественные знаки числа: <code class="literal">+-2</code>.
  </p>
 </div>

 <div class="sect2" id="migration84.incompatible.dom">
  <h3 class="title">Модуль DOM</h3>

  <p class="simpara">
   Отдельные методы модуля DOM раньше возвращали значение <strong><code><a href="reserved.constants.php#constant.false">false</a></code></strong>
   или выбрасывали исключение <span class="exceptionname"><a href="class.domexception.php" class="exceptionname">DOMException</a></span> с кодом
   <strong><code><a href="dom.constants.php#constant.dom-php-err">DOM_PHP_ERR</a></code></strong>, если не получалось выделить новый узел.
   Теперь методы постоянно выбрасывают исключение <span class="exceptionname"><a href="class.domexception.php" class="exceptionname">DOMException</a></span>
   с кодом <strong><code><a href="dom.constants.php#constant.dom-invalid-state-err">DOM_INVALID_STATE_ERR</a></code></strong>.
   Такая ситуация в крайней степени маловероятна и вряд ли затронет прежний код.
   В итоге вместо типа <code class="code">DOMDocument|false</code> методу
   <span class="methodname"><a href="domimplementation.createdocument.php" class="methodname">DOMImplementation::createDocument()</a></span> назначили предварительный
   тип возврата <span class="classname"><a href="class.domdocument.php" class="classname">DOMDocument</a></span>.
  </p>

  <p class="simpara">
   Раньше объекты <span class="classname"><a href="class.domxpath.php" class="classname">DOMXPath</a></span> разрешали клонировать,
   но в итоге получался непригодный объект.
   Клонирование объекта <span class="classname"><a href="class.domxpath.php" class="classname">DOMXPath</a></span> больше невозможно
   и теперь выбрасывает ошибку <span class="exceptionname"><a href="class.error.php" class="exceptionname">Error</a></span>.
  </p>

  <p class="simpara">
   Метод <span class="methodname"><strong>DOMImplementation::getFeature()</strong></span> удалили.
  </p>
 </div>

 <div class="sect2" id="migration84.incompatible.gmp">
  <h3 class="title">Класс GMP</h3>

  <p class="simpara">
   Класс <span class="classname"><a href="class.gmp.php" class="classname">GMP</a></span> сделали окончательным и поэтому расширение класса теперь невозможно.
  </p>
 </div>

 <div class="sect2" id="migration84.incompatible.mbstring">
  <h3 class="title">Модуль MBString</h3>

  <p class="simpara">
   В недопустимых строках с ошибками кодировки функция
   <span class="function"><a href="function.mb-substr.php" class="function">mb_substr()</a></span> теперь интерпретирует индексы символов
   аналогично большей части других функций для работы с многобайтовыми строками.
   Поэтому символьные индексы, которые возвращает функция <span class="function"><a href="function.mb-strpos.php" class="function">mb_strpos()</a></span>,
   разрешили передавать в функцию <span class="function"><a href="function.mb-substr.php" class="function">mb_substr()</a></span>.
  </p>

  <p class="simpara">
   Для строк в кодировке SJIS-Mac, или её псевдониме MacJapanese, индексы символов,
   которые передают в функцию <span class="function"><a href="function.mb-substr.php" class="function">mb_substr()</a></span>, теперь ссылаются на индексы
   кодовых точек кодировки Unicode, которые получаются при преобразовании строки в Unicode.
   Это важно, поскольку около 40 символов кодировки SJIS-Mac преобразовываются
   в последовательность из нескольких кодовых точек Unicode.
  </p>
 </div>

 <div class="sect2" id="migration84.incompatible.mysqli">
  <h3 class="title">Модуль MySQLi</h3>

  <p class="simpara">
   Невостребованную и незадокументированную константу
   <strong><code>MYSQLI_SET_CHARSET_DIR</code></strong> удалили.
  </p>

  <p class="simpara">
   Константу <strong><code><a href="mysqli.constants.php#constant.mysqli-stmt-attr-prefetch-rows">MYSQLI_STMT_ATTR_PREFETCH_ROWS</a></code></strong> удалили.
   Функция недоступна в драйвере mysqlnd.
  </p>

  <p class="simpara">
   Константы <strong><code><a href="mysqli.constants.php#constant.mysqli-cursor-type-for-update">MYSQLI_CURSOR_TYPE_FOR_UPDATE</a></code></strong>
   и <strong><code><a href="mysqli.constants.php#constant.mysqli-cursor-type-scrollable">MYSQLI_CURSOR_TYPE_SCROLLABLE</a></code></strong> удалили.
   Этот функционал никогда не реализовывали ни в драйвере mysqlnd, ни в библиотеке libmysql.
  </p>

  <p class="simpara">
   Невостребованную константу <strong><code><a href="mysqli.constants.php#constant.mysqli-type-interval">MYSQLI_TYPE_INTERVAL</a></code></strong> —
   заглушку и псевдоним константы <strong><code><a href="mysqli.constants.php#constant.mysqli-type-enum">MYSQLI_TYPE_ENUM</a></code></strong> —
   удалили.
  </p>
 </div>

 <div class="sect2" id="migration84.incompatible.mysqlnd">
  <h3 class="title">Драйвер MySQLnd</h3>

  <p class="simpara">
   Код ошибки, которым сообщают о превышении времени ожидания сервера MySQL,
   изменили с <code class="literal">2006</code> на <code class="literal">4031</code>
   для серверов MySQL версии 8.0.24 и выше.
  </p>
 </div>

 <div class="sect2" id="migration84.incompatible.opcache">
  <h3 class="title">Модуль Opcache</h3>

  <p class="simpara">
   Максимальное значение директивы
   <a href="opcache.configuration.php#ini.opcache.interned-strings-buffer" class="link">opcache.interned_strings_buffer</a>
   в 64-разрядных архитектурах теперь составляет <code class="literal">32767</code> МБ.
   Раньше значение составляло <code class="literal">4095</code> мегабайтов.
  </p>

  <div class="sect3">
   <h4 class="title">Компилятор JIT</h4>

   <p class="simpara">
    Значения конфигурации по умолчанию для JIT-компилятора изменились
    с <a href="opcache.configuration.php#ini.opcache.jit" class="link"><code class="literal">opcache.jit=tracing</code></a>
    на <a href="opcache.configuration.php#ini.opcache.jit" class="link"><code class="literal">opcache.jit=disable</code></a>
    и с <a href="opcache.configuration.php#ini.opcache.jit-buffer-size" class="link"><code class="literal">opcache.jit_buffer_size=0</code></a>
    на <a href="opcache.configuration.php#ini.opcache.jit-buffer-size" class="link"><code class="literal">opcache.jit_buffer_size=64M</code></a>.
   </p>

   <p class="simpara">
    Это не влияет на поведение наблюдаемых объектов по умолчанию,
    поскольку JIT по-прежнему отключён по умолчанию.
    Однако теперь JIT-компиляция отключается параметром
    <a href="opcache.configuration.php#ini.opcache.jit" class="link">opcache.jit</a>,
    а не <a href="opcache.configuration.php#ini.opcache.jit-buffer-size" class="link">opcache.jit_buffer_size</a>.
    Изменение затронет пользователей, которые раньше включали JIT только директивой
    <a href="opcache.configuration.php#ini.opcache.jit-buffer-size" class="link">opcache.jit_buffer_size</a>,
    но не указывали режим JIT-компиляции в директиве <a href="opcache.configuration.php#ini.opcache.jit" class="link">opcache.jit</a>.
    Поэтому чтобы включить JIT-компиляцию потребуется указать значение
    конфигурации для директивы <a href="opcache.configuration.php#ini.opcache.jit" class="link">opcache.jit</a>.
   </p>

   <p class="simpara">
    Теперь при включённой <abbr>JIT</abbr>-компиляции
    <abbr title="PHP: Hypertext Preprocessor">PHP</abbr> будет завершаться с критической ошибкой при запуске,
    если инициализация <abbr>JIT</abbr>-компилятора по какой-либо причине не удалась.
   </p>
  </div>
 </div>

 <div class="sect2" id="migration84.incompatible.pcntl">
  <h3 class="title">Модуль PCNTL</h3>

  <p class="simpara">
   Функции <span class="function"><a href="function.pcntl-sigprocmask.php" class="function">pcntl_sigprocmask()</a></span>,
   <span class="function"><a href="function.pcntl-sigwaitinfo.php" class="function">pcntl_sigwaitinfo()</a></span>
   и <span class="function"><a href="function.pcntl-sigtimedwait.php" class="function">pcntl_sigtimedwait()</a></span> теперь при каждом вызове
   возвращают значение <strong><code><a href="reserved.constants.php#constant.false">false</a></code></strong>, если возникла ошибка.
   Раньше в отдельных случаях функции иногда возвращали значение <code class="literal">-1</code>.
  </p>
 </div>

 <div class="sect2" id="migration84.incompatible.pcre">
  <h3 class="title">Модуль PCRE</h3>

  <p class="simpara">
   Библиотеку pcre2lib, которая идёт в комплекте поставки, обновили до версии 10.44.
   Поэтому запись <code class="literal">{,3}</code> теперь распознается как квантификатор, а не как текст.
   Кроме того, изменилось значение отдельных классов символов в режиме UCP.
   Полный перечень изменений приводит
   <a href="https://github.com/PCRE2Project/pcre2/blob/master/NEWS" class="link external">&raquo;&nbsp;список изменений PCRE2</a>.
  </p>
 </div>

 <div class="sect2" id="migration84.incompatible.pdo-dblib">
  <h3 class="title">Драйвер PDO_DBLIB</h3>

  <p class="simpara">
   Атрибуты <strong><code><a href="class.pdo-dblib.php#pdo-dblib.constants.attr-stringify-uniqueidentifier">Pdo\Dblib::ATTR_STRINGIFY_UNIQUEIDENTIFIER</a></code></strong>
   и <strong><code><a href="class.pdo-dblib.php#pdo-dblib.constants.attr-datetime-convert">Pdo\Dblib::ATTR_DATETIME_CONVERT</a></code></strong> теперь действуют как логические атрибуты
   вместо целочисленных.
   Поэтому установка атрибута методом <span class="methodname"><a href="pdo.setattribute.php" class="methodname">PDO::setAttribute()</a></span>
   и получение атрибута методом <span class="methodname"><a href="pdo.getattribute.php" class="methodname">PDO::getAttribute()</a></span> ожидает
   и возвращает логическое значение (<span class="type"><a href="language.types.boolean.php" class="type bool">bool</a></span>).
  </p>
 </div>

 <div class="sect2" id="migration84.incompatible.pdo-firebird">
  <h3 class="title">Драйвер PDO_FIREBIRD</h3>

  <p class="simpara">
   Атрибут <strong><code><a href="pdo.constants.php#pdo.constants.attr-autocommit">PDO::ATTR_AUTOCOMMIT</a></code></strong> теперь действует как логический атрибут
   вместо целочисленного.
   Поэтому установка атрибута методом <span class="methodname"><a href="pdo.setattribute.php" class="methodname">PDO::setAttribute()</a></span>
   и получение атрибута методом <span class="methodname"><a href="pdo.getattribute.php" class="methodname">PDO::getAttribute()</a></span> ожидает
   и возвращает логическое значение (<span class="type"><a href="language.types.boolean.php" class="type bool">bool</a></span>).
  </p>

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

 <div class="sect2" id="migration84.incompatible.pdo-mysql">
  <h3 class="title">Драйвер PDO_MYSQL</h3>

  <p class="simpara">
   Атрибуты <strong><code><a href="pdo.constants.php#pdo.constants.attr-autocommit">PDO::ATTR_AUTOCOMMIT</a></code></strong>, <strong><code><a href="pdo.constants.php#pdo.constants.attr-emulate-prepares">PDO::ATTR_EMULATE_PREPARES</a></code></strong>
   и <strong><code><a href="ref.pdo-mysql.php#pdo.constants.mysql-attr-direct-query">PDO::MYSQL_ATTR_DIRECT_QUERY</a></code></strong> теперь действуют как логические
   атрибуты вместо целочисленных.
   Поэтому установка атрибута методом <span class="methodname"><a href="pdo.setattribute.php" class="methodname">PDO::setAttribute()</a></span>
   и получение атрибута методом <span class="methodname"><a href="pdo.getattribute.php" class="methodname">PDO::getAttribute()</a></span>
   ожидает и возвращает логическое значение (<span class="type"><a href="language.types.boolean.php" class="type bool">bool</a></span>).
  </p>
 </div>

 <div class="sect2" id="migration84.incompatible.pdo-pgsql">
  <h3 class="title">Драйвер PDO_PGSQL</h3>

  <p class="simpara">
   Приоритет учётных данных, которые указали в DSN-строке подключения конструктора класса PDO,
   выше, чем приоритет учётных данных, которые указали во втором и третьем аргументах конструктора,
   поскольку учётные данные в DSN-строке подключения ближе к положениям документации.
  </p>
 </div>

 <div class="sect2" id="migration84.incompatible.simplexml">
  <h3 class="title">Модуль SimpleXML</h3>

  <p class="simpara">
   Объект класса <span class="classname"><a href="class.simplexmlelement.php" class="classname">SimpleXMLElement</a></span> — представляет не только элемент в XML-документе,
   но и интерфейс <span class="classname"><a href="class.recursiveiterator.php" class="classname">RecursiveIterator</a></span>.
   До PHP 8.4.0 отдельные методы класса наподобие <span class="methodname"><a href="simplexmlelement.asxml.php" class="methodname">SimpleXMLElement::asXML()</a></span>
   или <span class="methodname"><a href="simplexmlelement.getname.php" class="methodname">SimpleXMLElement::getName()</a></span>
   и приведение таких экземпляров к строке (<span class="type"><a href="language.types.string.php" class="type string">string</a></span>) неявно сбрасывали итератор.
  </p>
  <p class="para">
   Такое поведение иногда делало циклы бесконечными, поскольку итератор
   отматывался к первому элементу. Приведём пример. Следующий код:
   <div class="informalexample">
    <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br />$xmlString </span><span style="color: #007700">= </span><span style="color: #DD0000">"&lt;root&gt;&lt;a&gt;&lt;b&gt;1&lt;/b&gt;&lt;b&gt;2&lt;/b&gt;&lt;b&gt;3&lt;/b&gt;&lt;/a&gt;&lt;/root&gt;"</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$xml </span><span style="color: #007700">= </span><span style="color: #0000BB">simplexml_load_string</span><span style="color: #007700">(</span><span style="color: #0000BB">$xmlString</span><span style="color: #007700">);<br /><br /></span><span style="color: #0000BB">$nodes </span><span style="color: #007700">= </span><span style="color: #0000BB">$xml</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">a</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">b</span><span style="color: #007700">;<br />foreach (</span><span style="color: #0000BB">$nodes </span><span style="color: #007700">as </span><span style="color: #0000BB">$nodeData</span><span style="color: #007700">) {<br />    echo </span><span style="color: #DD0000">"Данные узла: " </span><span style="color: #007700">. </span><span style="color: #0000BB">$nodeData </span><span style="color: #007700">. </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br /><br />    </span><span style="color: #0000BB">$xml </span><span style="color: #007700">= </span><span style="color: #0000BB">$nodes</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">asXml</span><span style="color: #007700">();<br />}</span></span></code></div>
    </div>

    <p class="simpara">
     …вызовет бесконечный цикл.
    </p>
    <div class="example-contents screen">
<div class="cdata"><pre>
Данные узла: 1
Данные узла: 2
Данные узла: 2
Данные узла: 2
Данные узла: 2
Данные узла: 2
Данные узла: 2
// ...
</pre></div>
    </div>
    <p class="simpara">
     Это поведение исправили, и элемент
     <span class="classname"><a href="class.simplexmlelement.php" class="classname">SimpleXMLElement</a></span> больше не будет
     неявно сбрасывать данные итератора, если только итератор не отмотают вручную.
     Поэтому приведённый пример теперь будет выводить следующие данные:
    </p>
    <div class="example-contents screen">
<div class="cdata"><pre>
Данные узла: 1
Данные узла: 2
Данные узла: 3
</pre></div>
    </div>
   </div>
  </p>
 </div>

 <div class="sect2" id="migration84.incompatible.soap">
  <h3 class="title">Модуль SOAP</h3>

  <p class="simpara">
   Разработчики представили свойство <span class="property"><a href="class.soapclient.php#soapclient.props.typemap">SoapClient::$typemap</a></span>
   массивом (<span class="type"><a href="language.types.array.php" class="type array">array</a></span>), а не ресурсом (<span class="type"><a href="language.types.resource.php" class="type resource">resource</a></span>).
   Проверки функцией <span class="function"><a href="function.is-resource.php" class="function">is_resource()</a></span> наподобие
   <code class="code">is_resource($client-&gt;typemap)</code> потребуется
   заменить проверкой на <strong><code><a href="reserved.constants.php#constant.null">null</a></code></strong> вроде <code class="code">$client-&gt;typemap !== null</code>.
  </p>

  <p class="simpara">
   Модуль SOAP получил необязательную зависимость от модуля
   <a href="book.session.php" class="link">session</a>.
   Теперь при запуске будут возникать ошибки,
   если включить модуль <a href="book.soap.php" class="link">SOAP</a>, а PHP собрать
   без модуля session, но с флагом конфигурации <strong class="option unknown">--enable-rtld-now</strong>.
   Проблему решают двумя способами: либо не включают режим rtld-now, либо загружают модуль сессий.
  </p>
 </div>

 <div class="sect2" id="migration84.incompatible.standard">
  <h3 class="title">Стандартные функции</h3>

  <p class="simpara">
   Теперь при вызове функции <span class="function"><a href="function.strcspn.php" class="function">strcspn()</a></span>
   с передачей в аргументе <code class="parameter">characters</code> пустой строки
   вместо неправильной остановки на первом нулевом байте
   возвращается длина строки.
  </p>

  <p class="simpara">
   Функция <span class="function"><a href="function.http-build-query.php" class="function">http_build_query()</a></span> теперь корректно
   обрабатывает типизированные перечисления.
  </p>

  <p class="simpara">
   Функции <span class="function"><a href="function.stream-bucket-make-writeable.php" class="function">stream_bucket_make_writeable()</a></span>
   и <span class="function"><a href="function.stream-bucket-new.php" class="function">stream_bucket_new()</a></span> теперь возвращают
   экземпляр класса <span class="classname"><strong class="classname">StreamBucket</strong></span>, а не класса
   <span class="classname"><a href="class.stdclass.php" class="classname">stdClass</a></span>.
  </p>
 </div>

 <div class="sect2" id="migration84.incompatible.tidy">
  <h3 class="title">Модуль Tidy</h3>

  <p class="simpara">
   Теперь вместо предупреждений и повреждения объекта
   сбои в конструкторе выбрасывают исключение.
  </p>
 </div>

 <div class="sect2" id="migration84.incompatible.xml">
  <h3 class="title">Парсер XML</h3>

  <p class="simpara">
   Функции семейства <span class="function">xml_set_<span class="replaceable">*</span>_handler</span>
   теперь объявляют и проверяют сигнатуру
   <span class="type"><span class="type"><a href="language.types.callable.php" class="type callable">callable</a></span>|<span class="type"><a href="language.types.string.php" class="type string">string</a></span>|<span class="type"><a href="language.types.null.php" class="type null">null</a></span></span>
   параметров <code class="parameter">handler</code>.
   Больше того, значения с типом <span class="type"><a href="language.types.string.php" class="type string">string</a></span>, которые соответствуют названиям методов,
   которые задали функцией <span class="function"><a href="function.xml-set-object.php" class="function">xml_set_object()</a></span>,
   теперь проверяются на существование метода в классе объекта, который передали прежде.
   Поэтому теперь перед установкой названий методов, которые устанавливаются как <span class="type"><a href="language.types.callable.php" class="type callable">callable</a></span>-обработчики,
   требуется каждый раз вызывать функцию <span class="function"><a href="function.xml-set-object.php" class="function">xml_set_object()</a></span>.
   Передача пустой строки для отключения обработчика по-прежнему разрешается, но устарела.
  </p>

  <p class="simpara">
   Однако, поскольку функция <span class="function"><a href="function.xml-set-object.php" class="function">xml_set_object()</a></span> и передача
   строк, которые не принадлежат типу <span class="type"><a href="language.types.callable.php" class="type callable">callable</a></span>, устарели,
   рекомендуют заменить такие экземпляры <span class="type"><a href="language.types.callable.php" class="type callable">callable</a></span>-обработчиками,
   которые ссылаются непосредственно на метод.
  </p>
 </div>

</div><?php manual_footer($setup); ?>