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

contributors($setup);

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

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

  <div class="sect3" id="migration83.incompatible.core.overflowing-call-stack">

   <h4 class="title">Программы, которые были очень близки к переполнению стека вызовов</h4>
   <p class="para">
    Программы, которые были очень близки к переполнению стека вызовов, теперь могут выбрасывать
    исключение <span class="classname"><a href="class.error.php" class="classname">Error</a></span>, когда занятый в байтах размер стека больше, чем определено в настройке
    zend.max_allowed_stack_size-zend.reserved_stack_size
    (fiber.stack_size-zend.reserved_stack_size для файберов).
   </p>
  </div>

  <div class="sect3" id="migration83.incompatible.core.proc-get-status-multiple-times">
   <h4 class="title">Выполнение функции proc_get_status() несколько раз</h4>
   <p class="para">
    Выполнение функции proc_get_status() несколько раз теперь всегда
    возвращает правильное значение в POSIX-системах. Ранее только первый вызов
    функции возвращал правильное значение. Выполнение
    функции <span class="function"><a href="function.proc-close.php" class="function">proc_close()</a></span> после функции <span class="function"><a href="function.proc-get-status.php" class="function">proc_get_status()</a></span>
    теперь также возвращает правильный код выхода. Ранее это вернуло бы
    значение <code class="literal">-1</code>.
    Внутренне это работает через кеширование результата на POSIX-системах.
    Если требуется прежнее поведение, можно проверить
    ключ <code class="literal">«cached»</code> в массиве, который возвращает функция
    <span class="function"><a href="function.proc-get-status.php" class="function">proc_get_status()</a></span>, чтобы проверить, был ли кеширован результат.
   </p>
  </div>

  <div class="sect3" id="migration83.incompatible.core.zend-max-execution-timers">
   <h4 class="title">Таймеры Zend Max Execution</h4>
   <p class="para">
    Таймеры Zend Max Execution теперь по умолчанию включены для сборок ZTS
    в системах Linux.
   </p>
  </div>

  <div class="sect3" id="migration83.incompatible.core.traits-with-static-properties">
   <h4 class="title">Включение трейтов со статическими свойствами</h4>
   <p class="para">
    Включение трейтов со статическими свойствами теперь будет повторно определять статические свойства,
    унаследованные из родительского класса. Это создаст разные хранилища статических
    свойств для текущего класса. Это аналогично добавлению
    статического свойства в классе, без трейтов.
   </p>
  </div>

  <div class="sect3" id="migration83.incompatible.core.negative-index-to-empty-array">
   <h4 class="title">Присваивание отрицательного индекса пустому массиву</h4>
   <p class="para">
    При добавлении в массив с занятым отрицательным индексом,
    который, предположим, хранится в переменной <var class="varname">$n</var>,
    нового значения,
    следующий индекс получит значение <code class="code">$n + 1</code>, а не <code class="literal">0</code>.
   </p>
  </div>

  <div class="sect3" id="migration83.incompatible.core.class-constant-visibility-check">
   <h4 class="title">Проверка несоответствия видимости констант классов</h4>
   <p class="para">
    Несоответствия видимости констант классов теперь будет корректно проверено
    при реализации интерфейсов.
   </p>
  </div>

  <div class="sect3" id="migration83.incompatible.core.weakmap-entries-maps-to-itself">
   <h4 class="title">Записи WeakMap, ключ которых соответствует самим себе</h4>
   <p class="para">
    Записи объекта <span class="classname"><a href="class.weakmap.php" class="classname">WeakMap</a></span>, ключ которых сопоставлен с самим собой, (возможно,
    транзитивно) теперь можно удалить во время сбора цикла если ключ недоступен,
    кроме как путём перебора значений WeakMap (доступность во время перебора
    считается слабой).
    Ранее такие записи не были бы удалены автоматически.
   </p>
  </div>
 </div>

 <div class="sect2" id="migration83.incompatible.date">
  <h3 class="title">Модуль Date</h3>

  <p class="para">
   Вместо предупреждений и общих исключений
   в модуль DateTime были добавлены свойственные только ему исключения
   и ошибки в иерархии классов <span class="classname"><a href="class.dateerror.php" class="classname">DateError</a></span> и
   <span class="classname"><a href="class.dateexception.php" class="classname">DateException</a></span>. Это улучшает обработку ошибок и исключений,
   когда нужно проверить их существование.
  </p>
 </div>

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

  <p class="para">
   Вызов методов <span class="methodname"><a href="domchildnode.after.php" class="methodname">DOMChildNode::after()</a></span>,
   <span class="methodname"><a href="domchildnode.before.php" class="methodname">DOMChildNode::before()</a></span>
   и <span class="methodname"><a href="domchildnode.replacewith.php" class="methodname">DOMChildNode::replaceWith()</a></span>
   на узле, у которого нет родительского узла теперь неработоспособно, а не
   исключением иерархии, чтобы поведение было совместимым со спецификацией DOM.
  </p>

  <p class="para">
   Вызов методов классов <span class="classname"><a href="class.domparentnode.php" class="classname">DOMParentNode</a></span>
   и <span class="classname"><a href="class.domchildnode.php" class="classname">DOMChildNode</a></span> без документа теперь
   работает, а не выбрасывает исключения <strong><code><a href="dom.constants.php#constant.dom-hierarchy-request-err">DOM_HIERARCHY_REQUEST_ERR</a></code></strong>
   класса <span class="classname"><a href="class.domexception.php" class="classname">DOMException</a></span>.
   Это соответствует поведению спецификации DOM.
  </p>

  <p class="para">
   Вызов метода <span class="methodname"><a href="domdocument.createattributens.php" class="methodname">DOMDocument::createAttributeNS()</a></span> без префикса
   неправильно бы создал пространство имён по умолчанию,
   помещая элемент внутрь пространства имён вместо атрибута. Эта ошибка теперь исправлена.
  </p>

  <p class="para">
   Метод <span class="methodname"><a href="domdocument.createattributens.php" class="methodname">DOMDocument::createAttributeNS()</a></span> раньше
   неправильно бросал исключение <strong><code>DOM_NAMESPACE_ERRNAMESPACE_ERR</code></strong>
   класса <span class="classname"><a href="class.domexception.php" class="classname">DOMException</a></span>, когда префикс уже был занят другим
   URI. Теперь он правильно выбирает другой префикс при конфликте префиксов.
  </p>

  <p class="para">
   Новые методы и свойства были добавлены в ряд классов DOM.
   Если пользовательский класс наследуется от этих классов и объявляет метод или свойство
   с таким же именем, оно должно быть совместимым. В других случаях будет выброшена типичная ошибка
   компиляции о несовместимости.
   Познакомиться со списком новых методов и свойств можно
   в разделах <a href="migration83.new-features.php#migration83.new-features.dom" class="link">список новой функциональности</a>
   и <a href="migration83.new-functions.php#migration83.new-functions.dom" class="link">новые функции</a>.
  </p>
 </div>

 <div class="sect2" id="migration83.incompatible.ffi">
  <h3 class="title">Класс FFI</h3>

  <p class="para">
   Функции языка Си, для которых задан возвращаемый тип <span class="type"><span class="type"><a href="language.types.void.php" class="type void">void</a></span></span>, теперь возвращают значение <strong><code><a href="reserved.constants.php#constant.null">null</a></code></strong> вместо
   вместо объекта <code class="literal">object(FFI\CData:void) { }</code>.
  </p>
 </div>

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

  <p class="para">
   Настройка INI-директивы <a href="opcache.configuration.php#ini.opcache.consistency-checks" class="link">opcache.consistency_checks</a>
   была удалена. Эта функция не работала при трассировке JIT,
   а также с кешем наследования, и была отключена в PHP 8.1.18 и PHP 8.2.5;
   теперь её невозможно включить.
   И трассирующий JIT, и кеш наследования могут изменить разделяемую память (shm) после
   сохранения скрипта путём аннулирования его контрольной суммы. Были попытки исправить
   пропуски через модифицируемые указатели, но была отклонена из-за сложности.
   Из-за этого решили удалить эту функцию.
  </p>
 </div>

 <div class="sect2" id="migration83.incompatible.phar">
  <h3 class="title">Модуль Phar</h3>

  <p class="para">
   Тип констант класса <span class="classname"><a href="class.phar.php" class="classname">Phar</a></span> теперь объявлен.
  </p>
 </div>

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

  <p class="para">
   В функцию <span class="function"><a href="function.range.php" class="function">range()</a></span> был внесён ряд изменений:
   <ul class="simplelist">
    <li>
     Теперь выбрасывается исключение <span class="classname"><a href="class.typeerror.php" class="classname">TypeError</a></span>, когда объекты (<span class="type"><a href="language.types.object.php" class="type object">object</a></span>),
     ресурсы (<span class="type"><a href="language.types.resource.php" class="type resource">resource</a></span>) или массивы (<span class="type"><a href="language.types.array.php" class="type array">array</a></span>) передаются в качестве граничных значений.
    </li>
    <li>
     Теперь при передаче в параметр <code class="parameter">$step</code> значения <code class="literal">0</code>
     выбрасывается подробнее описанное исключение <span class="classname"><a href="class.valueerror.php" class="classname">ValueError</a></span>.
    </li>
    <li>
     Теперь выбрасывается исключение <span class="classname"><a href="class.valueerror.php" class="classname">ValueError</a></span>, когда
     в параметр <code class="parameter">$step</code> передаются отрицательные значения для увеличения диапазонов.
    </li>
    <li>
     Если в параметр <code class="parameter">$step</code> передаётся число с плавающей точкой,
     которое может быть интерпретировано как целое число, то оно так и оценивается.
    </li>
    <li>
     Теперь выбрасывается исключение <span class="classname"><a href="class.valueerror.php" class="classname">ValueError</a></span>, если любой аргумент
     представляет бесконечное число или нечисло (NAN).
    </li>
    <li>
     Теперь вызвается ошибка уровня <strong><code><a href="errorfunc.constants.php#constant.e-warning">E_WARNING</a></code></strong>,
     если параметр <code class="parameter">$start</code> или <code class="parameter">$end</code>
     принимает значение пустой строки. Значение продолжает приводиться к значению <code class="literal">0</code>.
    </li>
    <li>
     Теперь вызвается ошибка уровня <strong><code><a href="errorfunc.constants.php#constant.e-warning">E_WARNING</a></code></strong>,
     если параметр <code class="parameter">$start</code> или <code class="parameter">$end</code> принимает
     нечисловую строку размером более одного байта.
    </li>
    <li>
     Теперь вызвается ошибка уровня <strong><code><a href="errorfunc.constants.php#constant.e-warning">E_WARNING</a></code></strong>,
     если значение, переданное в параметр <code class="parameter">$start</code> или <code class="parameter">$end</code>,
     приводится к целому числу из-за того, что другое значение — число
     (например, <code class="code">range(5, &#039;z&#039;);</code>).
    </li>
    <li>
     Теперь при попытке сгенерировать диапазон символов вызвается ошибка уровня <strong><code><a href="errorfunc.constants.php#constant.e-warning">E_WARNING</a></code></strong>,
     если значение параметра <code class="parameter">$step</code> — число с плавающей точкой,
     кроме случаев, когда оба входных значения — числовые строки (например,
     <code class="code">range(&#039;5&#039;, &#039;9&#039;, 0.5);</code> не вызовет предупреждения).
    </li>
    <li>
     Теперь вместо приведения одного из значений к целому числу
     функция <span class="function"><a href="function.range.php" class="function">range()</a></span> создаёт список символов, если одно
     из них — числовая строка (например, <code class="code">range(&#039;9&#039;, &#039;A&#039;);</code>).
    </li>
   </ul>

   <div class="informalexample">
    <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br />range</span><span style="color: #007700">(</span><span style="color: #DD0000">'9'</span><span style="color: #007700">, </span><span style="color: #DD0000">'A'</span><span style="color: #007700">);  </span><span style="color: #FF8000">// ["9", ":", ";", "&lt;", "=", "&gt;", "?", "@", "A"], начиная с PHP 8.3.0<br /></span><span style="color: #0000BB">range</span><span style="color: #007700">(</span><span style="color: #DD0000">'9'</span><span style="color: #007700">, </span><span style="color: #DD0000">'A'</span><span style="color: #007700">);  </span><span style="color: #FF8000">// [9, 8, 7, 6, 5, 4, 3, 2, 1, 0], до PHP 8.3.0</span></span></code></div>
    </div>

   </div>
  </p>

  <p class="para">
   Теперь функция <span class="function"><a href="function.number-format.php" class="function">number_format()</a></span> обрабатывает отрицательные
   значения <code class="parameter">$decimals</code> и округляет
   значения <code class="parameter">$num</code> до <code class="code">abs($decimals)</code> знаков перед
   десятичной точкой. Раньше функция игнорировала отрицательные значения <code class="parameter">$decimals</code>.
  </p>

  <p class="para">
   Флаги проверки ошибок в функции <span class="function"><a href="function.file.php" class="function">file()</a></span> теперь перехватывает все недопустимые флаги.
   Константа <strong><code><a href="filesystem.constants.php#constant.file-append">FILE_APPEND</a></code></strong> раньше без предупреждения принималась.
  </p>
 </div>

 <div class="sect2" id="migration83.incompatible.SNMP">
  <h3 class="title">SNMP</h3>

  <p class="para">
   Тип констант класса <span class="classname"><a href="class.snmp.php" class="classname">SNMP</a></span> теперь объявлен.
  </p>
 </div>

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