<?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 => 'ja',
  ),
  '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 => 'PHP 8.3.x で推奨されなくなる機能',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'ja',
    '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">
    コールスタックがオーバーフローしそうになっているプログラムは、zend.max_allowed_stack_size - zend.reserved_stack_size (ファイバーの場合は fiber.stack_size - zend.reserved_stack_size) バイト以上のスタックを使い切った時点で <span class="classname"><a href="class.error.php" class="classname">Error</a></span> をスローするようになりました。 
   </p>
  </div>

  <div class="sect3" id="migration83.incompatible.core.proc-get-status-multiple-times">
   <h4 class="title">proc_get_status() を複数回コールする</h4>
   <p class="para">
    <span class="function"><a href="function.proc-get-status.php" class="function">proc_get_status()</a></span> を複数回コールした場合、POSIX システムでは常に正しい値を返すようになりました。これより前のバージョンでは、最初の呼び出しの場合にだけ正しい値を返していました。<span class="function"><a href="function.proc-get-status.php" class="function">proc_get_status()</a></span> をコールしたあとに <span class="function"><a href="function.proc-close.php" class="function">proc_close()</a></span> を呼び出した場合も、正しい終了コードを返すようになりました。これより前のバージョンでは、<code class="literal">-1</code> を返していました。内部的に、この処理は POSIX システム上で結果の値をキャッシュすることで実現しています。以前の振る舞いを望む場合は、<span class="function"><a href="function.proc-get-status.php" class="function">proc_get_status()</a></span> が返す配列の <code class="literal">&quot;cached&quot;</code> キーをチェックすることで、結果がキャッシュされているかを確認できます。
   </p>
  </div>

  <div class="sect3" id="migration83.incompatible.core.zend-max-execution-timers">
   <h4 class="title">実行時間の最大秒数を制御するタイマー</h4>
   <p class="para">
    実行時間の最大秒数を制御するタイマーが、Linux 上で ZTS を有効にしてビルドした場合でもデフォルトで有効になりました。
   </p>
  </div>

  <div class="sect3" id="migration83.incompatible.core.traits-with-static-properties">
   <h4 class="title">static プロパティと一緒にトレイトを使う</h4>
   <p class="para">
    static プロパティと一緒にトレイトを使うと、親クラスから継承する static プロパティを再宣言するようになりました。つまり、現在のクラスのために別の static プロパティを作成するということです。これは、トレイトを使わずに直接 static プロパティを追加する操作に似ています。
   </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="literal">0</code> ではなく、必ず <code class="code">$n+1</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 をループしている場合を除きます (ループ経由で到達できることは、weak と見なされるためです)。これより前のバージョンでは、こうしたエントリは自動で決して削除されませんでした。
   </p>
  </div>
 </div>

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

  <p class="para">
   日付・時刻の拡張モジュールでは、<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">
   prefix を指定せずに <span class="methodname"><a href="domdocument.createattributens.php" class="methodname">DOMDocument::createAttributeNS()</a></span> をコールすると、デフォルトの名前空間を誤って作成し、その名前空間中に属性ではなく要素を置いていました。PHP 8.3 では、このバグが修正されています。
  </p>

  <p class="para">
   以前のバージョンでは、<span class="methodname"><a href="domdocument.createattributens.php" class="methodname">DOMDocument::createAttributeNS()</a></span> は、prefix が既に異なる URI で使われている場合に <strong><code>DOM_NAMESPACE_ERRNAMESPACE_ERR</code></strong> <span class="classname"><a href="class.domexception.php" class="classname">DOMException</a></span> をスローしていました。
   このバージョンからは、prefix の名前が衝突していた場合でも、異なる prefix を正しく選べるようになりました。
  </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> 型を返すC言語の関数は、<code class="literal">object(FFI\CData:void) { }</code> ではなく、<strong><code><a href="reserved.constants.php#constant.null">null</a></code></strong> を返すようになりました。
  </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> が削除されました。この機能は tracing JIT や、inheritance cache (継承関係をキャッシュする機能) と一緒に使った場合に壊れてしまっていました。その後、このディレクティブを有効にする方法が見つからないまま、PHP 8.1.18 と 8.2.5 で無効にされました。tracing JIT と inheritance cache は両方、スクリプトが永続化された後に共有メモリを変更し、そのチェックサムを無効にする可能性があります。変更されうるポインタをスキップする変更も試みられましたが、複雑過ぎて受け入れられませんでした。以上の理由から、壊れてしまうバグを修正するのではなく、ディレクティブそのものが削除されることになりました。
  </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> がスローされるようになりました。</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>範囲が増加しているのに、<code class="parameter">$step</code> に負の値を渡すと、<span class="classname"><a href="class.valueerror.php" class="classname">ValueError</a></span> がスローされるようになりました。</li>
    <li><code class="parameter">$step</code> が整数型として解釈できる float の場合、整数型として解釈するようになりました。</li>
    <li>引数のいずれかが無限大または NAN の場合、<span class="classname"><a href="class.valueerror.php" class="classname">ValueError</a></span> がスローされるようになりました。</li>
    <li><code class="parameter">$start</code> や <code class="parameter">$end</code> が空文字列の場合、<strong><code><a href="errorfunc.constants.php#constant.e-warning">E_WARNING</a></code></strong> が発生するようになりました。値そのものが <code class="literal">0</code> にキャストされる動作は変更されていません。</li>
    <li><code class="parameter">$start</code> や <code class="parameter">$end</code> が1バイトより長い場合、<strong><code><a href="errorfunc.constants.php#constant.e-warning">E_WARNING</a></code></strong> が発生するようになりました。但し、それが数値形式の文字列でない場合に限ります。</li>
    <li><code class="parameter">$start</code> や <code class="parameter">$end</code> が整数型にキャストした値の場合、<strong><code><a href="errorfunc.constants.php#constant.e-warning">E_WARNING</a></code></strong> が発生するようになりました。なぜなら、他の境界の入力値は数値だからです。(例: <code class="code">range(5, &#039;z&#039;);</code>)</li>
    <li><code class="parameter">$step</code> が float の場合で、ある範囲の文字を生成しようとした場合、<strong><code><a href="errorfunc.constants.php#constant.e-warning">E_WARNING</a></code></strong> が発生するようになりました。但し、境界の値がともに数値形式の文字列の場合を除きます。(例: <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 />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">// PHP 8.3.0 以降は、["9", ":", ";", "&lt;", "=", "&gt;", "?", "@", "A"]<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">// PHP 8.3.0 より前は、[9, 8, 7, 6, 5, 4, 3, 2, 1, 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> は、負の
    <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> 関数の flags パラメータは、すべての不正な値をチェックするようになりました。注意すべきなのは、これより前のバージョンでは <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); ?>