<?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 => 'uk',
  ),
  'this' => 
  array (
    0 => 'migration83.incompatible.php',
    1 => 'Backward Incompatible Changes',
    2 => 'Backward Incompatible Changes',
  ),
  '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' => 'en',
    '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">Backward Incompatible Changes</h2>

 <div class="sect2" id="migration83.incompatible.core">
  <h3 class="title">PHP Core</h3>

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

   <h4 class="title">Programs that were very close to overflowing the call stack</h4>
   <p class="para">
    Programs that were very close to overflowing the call stack may now throw an
    <span class="classname"><a href="class.error.php" class="classname">Error</a></span> when using more than
    zend.max_allowed_stack_size-zend.reserved_stack_size bytes of stack
    (fiber.stack_size-zend.reserved_stack_size for fibers).
   </p>
  </div>

  <div class="sect3" id="migration83.incompatible.core.proc-get-status-multiple-times">
   <h4 class="title">Executing proc_get_status() multiple times</h4>
   <p class="para">
    Executing <span class="function"><a href="function.proc-get-status.php" class="function">proc_get_status()</a></span> multiple times will now always
    return the right value on POSIX systems. Previously, only the first call
    of the function returned the right value. Executing
    <span class="function"><a href="function.proc-close.php" class="function">proc_close()</a></span> after <span class="function"><a href="function.proc-get-status.php" class="function">proc_get_status()</a></span>
    will now also return the right exit code. Previously this would return
    <code class="literal">-1</code>.
    Internally, this works by caching the result on POSIX systems.
    If the previous behaviour is required, it is possible to check the
    <code class="literal">&quot;cached&quot;</code> key in the array returned by
    <span class="function"><a href="function.proc-get-status.php" class="function">proc_get_status()</a></span> to check whether the result was cached.
   </p>
  </div>

  <div class="sect3" id="migration83.incompatible.core.zend-max-execution-timers">
   <h4 class="title">Zend Max Execution Timers</h4>
   <p class="para">
    Zend Max Execution Timers is now enabled by default for ZTS builds on
    Linux.
   </p>
  </div>

  <div class="sect3" id="migration83.incompatible.core.traits-with-static-properties">
   <h4 class="title">Uses of traits with static properties</h4>
   <p class="para">
    Uses of traits with static properties will now redeclare static properties
    inherited from the parent class. This will create a separate static
    property storage for the current class. This is analogous to adding the
    static property to the class directly without traits.
   </p>
  </div>

  <div class="sect3" id="migration83.incompatible.core.negative-index-to-empty-array">
   <h4 class="title">Assigning a negative index to an empty array</h4>
   <p class="para">
    Assigning a negative index <var class="varname">$n</var> to an empty array will now make sure that the
    next index is <code class="code">$n+1</code> instead of <code class="literal">0</code>.
   </p>
  </div>

  <div class="sect3" id="migration83.incompatible.core.class-constant-visibility-check">
   <h4 class="title">Class constant visibility variance check</h4>
   <p class="para">
    Class constant visibility variance is now correctly checked when inherited
    from interfaces.
   </p>
  </div>

  <div class="sect3" id="migration83.incompatible.core.weakmap-entries-maps-to-itself">
   <h4 class="title">WeakMap entries whose key maps to itself</h4>
   <p class="para">
    <span class="classname"><a href="class.weakmap.php" class="classname">WeakMap</a></span> entries whose key maps to itself (possibly
    transitively) may now be removed during cycle collection if the key is not
    reachable except by iterating over the WeakMap (reachability via iteration is
    considered weak).
    Previously, such entries would never be automatically removed.
   </p>
  </div>
 </div>

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

  <p class="para">
   The DateTime extension has introduced Date extension specific exceptions
   and errors under the <span class="classname"><strong class="classname">DateError</strong></span> and
   <span class="classname"><strong class="classname">DateException</strong></span> hierarchies, instead of warnings and
   generic exceptions. This improves error handling, at the expense
   of having to check for errors and exceptions.
  </p>
 </div>

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

  <p class="para">
   Calling <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>
   on a node that has no parent is now a no-op instead of a hierarchy
   exception, which is the behaviour demanded by the DOM specification.
  </p>

  <p class="para">
   Using the <span class="classname"><a href="class.domparentnode.php" class="classname">DOMParentNode</a></span>
   and <span class="classname"><a href="class.domchildnode.php" class="classname">DOMChildNode</a></span> methods without a document now
   works instead of throwing a <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>.
   This is in line with the behaviour demanded by the DOM specification.
  </p>

  <p class="para">
   Calling <span class="methodname"><a href="domdocument.createattributens.php" class="methodname">DOMDocument::createAttributeNS()</a></span> without specifying
   a prefix would incorrectly create a default namespace, placing the element
   inside the namespace instead of the attribute. This bug is now fixed.
  </p>

  <p class="para">
   <span class="methodname"><a href="domdocument.createattributens.php" class="methodname">DOMDocument::createAttributeNS()</a></span> would previously
   incorrectly throw a <strong><code>DOM_NAMESPACE_ERRNAMESPACE_ERR</code></strong>
   <span class="classname"><a href="class.domexception.php" class="classname">DOMException</a></span> when the prefix was already used for a
   different URI. It now correctly chooses a different prefix when there&#039;s a
   prefix name conflict.
  </p>

  <p class="para">
   New methods and properties were added to some DOM classes.
   If a userland class inherits from these classes and declare a method or property
   with the same name, the declarations must be compatible. Otherwise, a typical
   compile error about incompatible declarations will be thrown.
   See the <a href="migration83.new-features.php#migration83.new-features.dom" class="link">list of new features</a>
   and <a href="migration83.new-functions.php#migration83.new-functions.dom" class="link">new functions</a> for
   a list of the newly implemented methods and properties.
  </p>
 </div>

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

  <p class="para">
   C functions that have a return type of <span class="type"><span class="type"><a href="language.types.void.php" class="type void">void</a></span></span> now return <strong><code><a href="reserved.constants.php#constant.null">null</a></code></strong> instead of
   returning the following object <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">
   The <a href="opcache.configuration.php#ini.opcache.consistency-checks" class="link">opcache.consistency_checks</a>
   INI directive was removed. This feature was broken with the tracing JIT,
   as well as with inheritance cache, and has been disabled without a way to
   enable it since PHP 8.1.18 and PHP 8.2.5.
   Both the tracing JIT and inheritance cache may modify shm after the script
   has been persisted by invalidating its checksum. The attempted fix skipped
   over the modifiable pointers but was rejected due to complexity. For this
   reason, it was decided to remove the feature instead.
  </p>
 </div>

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

  <p class="para">
   The type of <span class="classname"><a href="class.phar.php" class="classname">Phar</a></span> class constants are now declared.
  </p>
 </div>

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

  <p class="para">
   The <span class="function"><a href="function.range.php" class="function">range()</a></span> function has had various changes:
   <ul class="simplelist">
    <li>A <span class="classname"><a href="class.typeerror.php" class="classname">TypeError</a></span> is now thrown when passing <span class="type"><a href="language.types.object.php" class="type object">object</a></span>s,
    <span class="type"><a href="language.types.resource.php" class="type resource">resource</a></span>s, or <span class="type"><a href="language.types.array.php" class="type array">array</a></span>s as the boundary inputs.</li>
    <li>A more descriptive <span class="classname"><a href="class.valueerror.php" class="classname">ValueError</a></span> is thrown when
    passing <code class="literal">0</code> for <code class="parameter">$step</code>.</li>
    <li>A <span class="classname"><a href="class.valueerror.php" class="classname">ValueError</a></span> is now thrown when using a
    negative <code class="parameter">$step</code> for increasing ranges.</li>
    <li>If <code class="parameter">$step</code> is a float that can be interpreted
    as an int, it is now done so.</li>
    <li>A <span class="classname"><a href="class.valueerror.php" class="classname">ValueError</a></span> is now thrown if any argument
    is infinity or NAN.</li>
    <li>An <strong><code><a href="errorfunc.constants.php#constant.e-warning">E_WARNING</a></code></strong> is now emitted if
    <code class="parameter">$start</code> or <code class="parameter">$end</code> is the empty
    string. The value continues to be cast to the value <code class="literal">0</code>.</li>
    <li>An <strong><code><a href="errorfunc.constants.php#constant.e-warning">E_WARNING</a></code></strong> is now emitted if
    <code class="parameter">$start</code> or <code class="parameter">$end</code> has more than
    one byte, only if it is a non-numeric string.</li>
    <li>An <strong><code><a href="errorfunc.constants.php#constant.e-warning">E_WARNING</a></code></strong> is now emitted if
    <code class="parameter">$start</code> or <code class="parameter">$end</code> is cast to an
    integer because the other boundary input is a number.
    (e.g. <code class="code">range(5, &#039;z&#039;);</code>).</li>
    <li>An <strong><code><a href="errorfunc.constants.php#constant.e-warning">E_WARNING</a></code></strong> is now emitted if
    <code class="parameter">$step</code> is a float when trying to generate a range of
    characters, except if both boundary inputs are numeric strings (e.g.
    <code class="code">range(&#039;5&#039;, &#039;9&#039;, 0.5);</code> does not produce a warning).</li>
    <li><span class="function"><a href="function.range.php" class="function">range()</a></span> now produce a list of characters if one
    of the boundary inputs is a string digit instead of casting the other input
    to int (e.g. <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 />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"], as of 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], prior to PHP 8.3.0<br /></span><span style="color: #0000BB">?&gt;</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> now handles negative
   <code class="parameter">$decimals</code> values by rounding
   <code class="parameter">$num</code> to <code class="code">abs($decimals)</code> digits before the
   decimal point. Previously, negative <code class="parameter">$decimals</code> values
   were ignored.
  </p>

  <p class="para">
   The <span class="function"><a href="function.file.php" class="function">file()</a></span> flags error check now catches all invalid flags.
   Notably <strong><code><a href="filesystem.constants.php#constant.file-append">FILE_APPEND</a></code></strong> was previously silently accepted.
  </p>
 </div>

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

  <p class="para">
   The type of <span class="classname"><a href="class.snmp.php" class="classname">SNMP</a></span> class constants are now declared.
  </p>
 </div>

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