<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/migration74.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'ja',
  ),
  'this' => 
  array (
    0 => 'migration74.new-features.php',
    1 => '新機能',
    2 => '新機能',
  ),
  'up' => 
  array (
    0 => 'migration74.php',
    1 => 'PHP 7.3.x から PHP 7.4.x への移行',
  ),
  'prev' => 
  array (
    0 => 'migration74.php',
    1 => 'PHP 7.3.x から PHP 7.4.x への移行',
  ),
  'next' => 
  array (
    0 => 'migration74.new-classes.php',
    1 => '新しいクラスとインターフェイス',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'ja',
    'path' => 'appendices/migration74/new-features.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="migration74.new-features" class="sect1">
 <h2 class="title">新機能</h2>

 <div class="sect2" id="migration74.new-features.core">
  <h3 class="title">PHP コア</h3>

  <div class="sect3" id="migration74.new-features.core.typed-properties">
   <h4 class="title">型付きプロパティ</h4>

   <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 /></span><span style="color: #007700">class </span><span style="color: #0000BB">User </span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">int $id</span><span style="color: #007700">;<br />    public </span><span style="color: #0000BB">string $name</span><span style="color: #007700">;<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

    </div>
    上の例は、 <code class="literal">$user-&gt;id</code> には <span class="type"><a href="language.types.integer.php" class="type int">int</a></span> の 値だけを、そして <code class="literal">$user-&gt;name</code> には <span class="type"><a href="language.types.string.php" class="type string">string</a></span> の値だけを代入できるように強制します。
   </p>
  </div>

  <div class="sect3" id="migration74.new-features.core.arrow-functions">
   <h4 class="title">アロー関数</h4>

   <p class="para">
    <a href="functions.arrow.php" class="link">アロー関数</a>は、暗黙的な値スコープを持った関数を定義する簡便な文法を提供します。

    <div class="informalexample">
     <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br />$factor </span><span style="color: #007700">= </span><span style="color: #0000BB">10</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$nums </span><span style="color: #007700">= </span><span style="color: #0000BB">array_map</span><span style="color: #007700">(fn(</span><span style="color: #0000BB">$n</span><span style="color: #007700">) =&gt; </span><span style="color: #0000BB">$n </span><span style="color: #007700">* </span><span style="color: #0000BB">$factor</span><span style="color: #007700">, [</span><span style="color: #0000BB">1</span><span style="color: #007700">, </span><span style="color: #0000BB">2</span><span style="color: #007700">, </span><span style="color: #0000BB">3</span><span style="color: #007700">, </span><span style="color: #0000BB">4</span><span style="color: #007700">]);<br /></span><span style="color: #FF8000">// $nums = array(10, 20, 30, 40);<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

    </div>
   </p>
  </div>

  <div class="sect3" id="migration74.new-features.core.type-variance">
   <h4 class="title">戻り値の型を狭めたり、引数の型を広げたりする</h4>

   <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 /></span><span style="color: #007700">class </span><span style="color: #0000BB">A </span><span style="color: #007700">{}<br />class </span><span style="color: #0000BB">B </span><span style="color: #007700">extends </span><span style="color: #0000BB">A </span><span style="color: #007700">{}<br /><br />class </span><span style="color: #0000BB">Producer </span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">method</span><span style="color: #007700">(): </span><span style="color: #0000BB">A </span><span style="color: #007700">{}<br />}<br />class </span><span style="color: #0000BB">ChildProducer </span><span style="color: #007700">extends </span><span style="color: #0000BB">Producer </span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">method</span><span style="color: #007700">(): </span><span style="color: #0000BB">B </span><span style="color: #007700">{}<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

    </div>
    完全な型の変位指定は、オートローディングが使われている場合のみ有効です。単一ファイル内では、型の参照が循環参照していない場合のみ可能です。なぜなら、全てのクラスは参照する前に利用可能でなければならないからです。
    <div class="informalexample">
     <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #FF8000">/**<br /> * これらのクラスは、LSP の要件を満たします。<br /> * なぜなら、C は A の部分型だからです。<br /> * しかし、B が宣言された時点で、C はまだ利用可能ではありません。<br /> */<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">A<br /></span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">method</span><span style="color: #007700">(): </span><span style="color: #0000BB">A </span><span style="color: #007700">{}<br />}<br /><br />class </span><span style="color: #0000BB">B </span><span style="color: #007700">extends </span><span style="color: #0000BB">A<br /></span><span style="color: #007700">{<br />    </span><span style="color: #FF8000">// Fatal error: Could not check compatibility between B::method():C and<br />    // A::method(): A, because class С is not available<br />    </span><span style="color: #007700">public function </span><span style="color: #0000BB">method</span><span style="color: #007700">(): </span><span style="color: #0000BB">С </span><span style="color: #007700">{}<br />}<br /><br />class </span><span style="color: #0000BB">C </span><span style="color: #007700">extends </span><span style="color: #0000BB">B </span><span style="color: #007700">{}<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

    </div>
   </p>
  </div>

  <div class="sect3" id="migration74.new-features.core.null-coalescing-assignment-operator">
   <h4 class="title">Null 合体代入演算子</h4>

   <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 />$array</span><span style="color: #007700">[</span><span style="color: #DD0000">'key'</span><span style="color: #007700">] ??= </span><span style="color: #0000BB">computeDefault</span><span style="color: #007700">();<br /></span><span style="color: #FF8000">// は、以下にほぼ等しい<br /></span><span style="color: #007700">if (!isset(</span><span style="color: #0000BB">$array</span><span style="color: #007700">[</span><span style="color: #DD0000">'key'</span><span style="color: #007700">])) {<br />    </span><span style="color: #0000BB">$array</span><span style="color: #007700">[</span><span style="color: #DD0000">'key'</span><span style="color: #007700">] = </span><span style="color: #0000BB">computeDefault</span><span style="color: #007700">();<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

    </div>
   </p>
  </div>

  <div class="sect3" id="migration74.new-features.core.unpack-inside-array">
   <h4 class="title">配列内での値のアンパック</h4>

   <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 />$parts </span><span style="color: #007700">= [</span><span style="color: #DD0000">'apple'</span><span style="color: #007700">, </span><span style="color: #DD0000">'pear'</span><span style="color: #007700">];<br /></span><span style="color: #0000BB">$fruits </span><span style="color: #007700">= [</span><span style="color: #DD0000">'banana'</span><span style="color: #007700">, </span><span style="color: #DD0000">'orange'</span><span style="color: #007700">, ...</span><span style="color: #0000BB">$parts</span><span style="color: #007700">, </span><span style="color: #DD0000">'watermelon'</span><span style="color: #007700">];<br /></span><span style="color: #FF8000">// ['banana', 'orange', 'apple', 'pear', 'watermelon'];<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

    </div>
   </p>
  </div>

  <div class="sect3" id="migration74.new-features.core.numeric-literal-separator">
   <h4 class="title">数値リテラルのセパレータ</h4>

   <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 />6.674_083e-11</span><span style="color: #007700">; </span><span style="color: #FF8000">// float<br /></span><span style="color: #0000BB">299_792_458</span><span style="color: #007700">;   </span><span style="color: #FF8000">// decimal<br /></span><span style="color: #0000BB">0xCAFE_F00D</span><span style="color: #007700">;   </span><span style="color: #FF8000">// hexadecimal<br /></span><span style="color: #0000BB">0b0101_1111</span><span style="color: #007700">;   </span><span style="color: #FF8000">// binary<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

    </div>
   </p>
  </div>
 
  <div class="sect3" id="migration74.new-features.core.weakreference">
   <h4 class="title">弱い参照</h4>

   <p class="para">
    <a href="class.weakreference.php" class="link">弱い参照</a> により、オブジェクトが破棄されるのを妨げないオブジェクトへの参照を保持することが可能です。
   </p>
  </div>

  <div class="sect3" id="migration74.new-features.core.tostring-exceptions">
   <h4 class="title">__toString() から例外をスロー可能に</h4>

   <p class="para">
    <a href="language.oop5.magic.php#object.tostring" class="link">__toString()</a>
    から例外をスローできるようになりました。以前は、この場合には致命的なエラーが発生していました。この関数内に既に存在する、回復可能な致命的なエラーは
    <span class="classname"><a href="class.error.php" class="classname">Error</a></span> 例外クラスに変換されます。
   </p>
  </div>

 </div>

 <div class="sect2" id="migration74.new-features.curl">
  <h3 class="title">CURL</h3>
  
  <p class="para">
   <span class="classname"><a href="class.curlfile.php" class="classname">CURLFile</a></span> は、CURL拡張モジュールが libcurl 7.56.0 より新しいものでビルドされた場合は、通常のファイル名に加えて、ストリームラッパーをサポートするようになります。
  </p>
 </div>

 <div class="sect2" id="migration74.new-features.filter">
  <h3 class="title">Filter</h3>
  
  <p class="para">
   <strong><code><a href="filter.constants.php#constant.filter-validate-float">FILTER_VALIDATE_FLOAT</a></code></strong> フィルタは
   <code class="literal">min_range</code> と <code class="literal">max_range</code>
   オプションをサポートするようになりました。
   これは、<strong><code><a href="filter.constants.php#constant.filter-validate-int">FILTER_VALIDATE_INT</a></code></strong> と同じセマンティクスです。
  </p>
 </div>

 <div class="sect2" id="migration74.new-features.ffi">
  <h3 class="title">FFI</h3>

  <p class="para">
   FFI は、ネイティブ関数を呼び出したり、ネイティブな値にアクセスしたり、Cライブラリで定義されたデータ構造を生成/アクセスする簡単な方法を提供する新しい拡張モジュールです。
  </p>
 </div>

 <div class="sect2" id="migration74.new-features.gd">
  <h3 class="title">GD</h3>

  <p class="para">
   画像に scatter フィルタを適用するための
   <strong><code><a href="image.constants.php#constant.img-filter-scatter">IMG_FILTER_SCATTER</a></code></strong> が追加されました。
  </p>
 </div>

 <div class="sect2" id="migration74.new-features.hash">
  <h3 class="title">Hash</h3>

  <p class="para">
   Castagnoli 多項式を使った <code class="literal">crc32c</code>
   ハッシュが追加されました。
   CRC32 バリアントは、 iSCSI, SCTP, Btrfs, ext4
   のようなストレージシステムで使われています。
  </p>
 </div>

 <div class="sect2" id="migration74.new-features.mbstring">
  <h3 class="title">マルチバイト文字列</h3>

  <p class="para">
   <span class="function"><a href="function.str-split.php" class="function">str_split()</a></span> と同等の機能を提供するものの、バイトではなく、コードポイント単位で動作する <span class="function"><a href="function.mb-str-split.php" class="function">mb_str_split()</a></span> 関数が追加されました。
  </p>
 </div>

 <div class="sect2" id="migration74.new-features.opcache">
  <h3 class="title">OPcache</h3>

  <p class="para">
   <a href="opcache.preloading.php" class="link">コードを事前ロードする機能</a> がサポートされました。
  </p>
 </div>

 <div class="sect2" id="migration74.new-features.pcre">
  <h3 class="title">正規表現 (Perl互換)</h3>

  <p class="para">
   <span class="function"><a href="function.preg-replace-callback.php" class="function">preg_replace_callback()</a></span> および <span class="function"><a href="function.preg-replace-callback-array.php" class="function">preg_replace_callback_array()</a></span>
   関数は、追加のフラグを受け入れるようになりました。
   <strong><code><a href="pcre.constants.php#constant.preg-offset-capture">PREG_OFFSET_CAPTURE</a></code></strong> と <strong><code><a href="pcre.constants.php#constant.preg-unmatched-as-null">PREG_UNMATCHED_AS_NULL</a></code></strong> です。これは、コールバック関数に渡される matches配列のフォーマットに影響します。
  </p>
 </div>

 <div class="sect2" id="migration74.new-features.pdo">
  <h3 class="title">PDO</h3>

  <p class="para">
   ユーザー名とパスワードが、PDO DSN の一部として指定できるようになりました。対象となるのは、mysql, mssql, sybase, dblib, firebird, oci ドライバです。以前は、この機能は pgsql ドライバでのみサポートされていました。ユーザー名/パスワードがコンストラクタとDSNの両方で指定された場合は、コンストラクタの指定が優先します。
  </p>
  <p class="para">
      SQLクエリのクエスチョンマークが、パラメータのプレースホルダーとして解釈されるのを防ぐためにエスケープできるようになりました。<code class="literal">??</code> を書くことで、単一のクエスチョンマークをデータベースに送信できるようになります。PostgreSQL のJSONのキーが存在するかを確認する演算子 (<code class="literal">?</code>) として使って下さい。
  </p>
 </div>

 <div class="sect2" id="migration74.new-features.pdo_oci">
  <h3 class="title">PDO_OCI</h3>

  <p class="para">
   <span class="methodname"><a href="pdostatement.getcolumnmeta.php" class="methodname">PDOStatement::getColumnMeta()</a></span> が利用できるようになりました。
  </p>
 </div>

 <div class="sect2" id="migration74.new-features.pdo_sqlite">
  <h3 class="title">PDO_SQLite</h3>

  <p class="para">
   <code class="literal">PDOStatement::getAttribute(PDO::SQLITE_ATTR_READONLY_STATEMENT)</code>
   は、ステートメントが読み取り専用かどうか、つまりそれがデータベースを変更しないかをチェックできるようになりました。
  </p>
  <p class="para">
   <code class="literal">PDO::setAttribute(PDO::SQLITE_ATTR_EXTENDED_RESULT_CODES,
   true)</code> 関数によって、<span class="function"><a href="pdo.errorinfo.php" class="function">PDO::errorInfo()</a></span> と
   <span class="function"><a href="pdostatement.errorinfo.php" class="function">PDOStatement::errorInfo()</a></span> 経由で SQLite3
   の拡張結果コードを使えるようになりました。
  </p>
 </div>

 <div class="sect2" id="migration74.new-features.sqlite3">
  <h3 class="title">SQLite3</h3>

  <p class="para">
   最新の拡張結果コードを取得するために、 <span class="methodname"><strong>SQLite3::lastExtendedErrorCode()</strong></span> が追加されました。 
  </p>
  <p class="para">
   <code class="literal">SQLite3::enableExtendedResultCodes($enable = true)</code>
   が追加されました。これによって、
   <span class="methodname"><a href="sqlite3.lasterrorcode.php" class="methodname">SQLite3::lastErrorCode()</a></span>
   が拡張結果コードを返すようになります。
  </p>
 </div>

 <div class="sect2" id="migration74.new-features.standard">
  <h3 class="title">標準ライブラリ</h3>

  <div class="sect3" id="migration74.new-features.standard.strip-tags">
   <h4 class="title">strip_tags() をタグ名の配列とともに使う</h4>
   <p class="para">
    <span class="function"><a href="function.strip-tags.php" class="function">strip_tags()</a></span>
    関数は、許可するタグの配列も受け入れるようになりました。つまり、<code class="literal">strip_tags($str,
    &#039;&lt;a&gt;&lt;p&gt;&#039;)</code> の代わりに、 <code class="literal">strip_tags($str,
    [&#039;a&#039;, &#039;p&#039;])</code> と書けるようになったということです。
   </p>
  </div>

  <div class="sect3" id="migration74.new-features.standard.magic-serialize">
   <h4 class="title">カスタムオブジェクトのシリアル化</h4>
   <p class="para">
    新しいカスタムオブジェクトのシリアル化の機構が追加されました。これは、新しいふたつのマジックメソッド
    <code class="literal">__serialize</code> と <code class="literal">__unserialize</code>
    を使います。
    <div class="informalexample">
     <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #FF8000">// オブジェクトに必要な状態を全て保持した配列を返す<br /></span><span style="color: #007700">public function </span><span style="color: #0000BB">__serialize</span><span style="color: #007700">(): array<br />{<br />}<br /><br /></span><span style="color: #FF8000">// 与えられた data 配列から、オブジェクトの状態を復元する<br /></span><span style="color: #007700">public function </span><span style="color: #0000BB">__unserialize</span><span style="color: #007700">(array </span><span style="color: #0000BB">$data</span><span style="color: #007700">): </span><span style="color: #0000BB">void<br /></span><span style="color: #007700">{<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

    </div>
    新しいシリアル化の機構は、 <span class="interfacename"><a href="class.serializable.php" class="interfacename">Serializable</a></span>
    インターフェイス を置き換えるものです。
    <span class="interfacename"><a href="class.serializable.php" class="interfacename">Serializable</a></span>
    インターフェイスは将来非推奨になるでしょう。
   </p>
  </div>

  <div class="sect3" id="migration74.new-features.standard.array-merge-no-args">
   <h4 class="title">引数を渡さずに array_merge 系の関数を使用する</h4>
   <p class="para">
    <span class="function"><a href="function.array-merge.php" class="function">array_merge()</a></span> および
    <span class="function"><a href="function.array-merge-recursive.php" class="function">array_merge_recursive()</a></span>
    関数は、引数なしでも呼び出せるようになりました。この場合、空の配列が返されます。これは、<code class="literal">array_merge(...$arrays)</code>
    のように、... 演算子と組み合わせて使う時に便利です。
   </p>
  </div>

  <div class="sect3" id="migration74.new-features.standard.proc-open">
   <h4 class="title"><span class="function"><a href="function.proc-open.php" class="function">proc_open()</a></span> 関数</h4>
   <p class="para">
    <span class="function"><a href="function.proc-open.php" class="function">proc_open()</a></span>
    関数は、コマンドの文字列ではなく、配列を受け入れるようになりました。この場合、プロセスは(shellを通さず) 直接オープンされ、PHP が必要な引数のエスケープをすべて行います。
    <div class="informalexample">
     <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br />proc_open</span><span style="color: #007700">([</span><span style="color: #DD0000">'php'</span><span style="color: #007700">, </span><span style="color: #DD0000">'-r'</span><span style="color: #007700">, </span><span style="color: #DD0000">'echo "Hello World\n";'</span><span style="color: #007700">], </span><span style="color: #0000BB">$descriptors</span><span style="color: #007700">, </span><span style="color: #0000BB">$pipes</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

    </div>
   </p>
   <p class="para">
    <span class="function"><a href="function.proc-open.php" class="function">proc_open()</a></span> が、
    <code class="literal">redirect</code> と <code class="literal">null</code> ディスクリプタをサポートしました。
    <div class="informalexample">
     <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #FF8000">// シェルにおける 2&gt;&amp;1 のような操作<br /></span><span style="color: #0000BB">proc_open</span><span style="color: #007700">(</span><span style="color: #0000BB">$cmd</span><span style="color: #007700">, [</span><span style="color: #0000BB">1 </span><span style="color: #007700">=&gt; [</span><span style="color: #DD0000">'pipe'</span><span style="color: #007700">, </span><span style="color: #DD0000">'w'</span><span style="color: #007700">], </span><span style="color: #0000BB">2 </span><span style="color: #007700">=&gt; [</span><span style="color: #DD0000">'redirect'</span><span style="color: #007700">, </span><span style="color: #0000BB">1</span><span style="color: #007700">]], </span><span style="color: #0000BB">$pipes</span><span style="color: #007700">);<br /></span><span style="color: #FF8000">// シェルにおける 2&gt;/dev/null や 2&gt;null のような操作<br /></span><span style="color: #0000BB">proc_open</span><span style="color: #007700">(</span><span style="color: #0000BB">$cmd</span><span style="color: #007700">, [</span><span style="color: #0000BB">1 </span><span style="color: #007700">=&gt; [</span><span style="color: #DD0000">'pipe'</span><span style="color: #007700">, </span><span style="color: #DD0000">'w'</span><span style="color: #007700">], </span><span style="color: #0000BB">2 </span><span style="color: #007700">=&gt; [</span><span style="color: #DD0000">'null'</span><span style="color: #007700">]], </span><span style="color: #0000BB">$pipes</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

    </div>
   </p>
  </div>

  <div class="sect3" id="migration74.new-features.standard.sodium-argon-hash">
   <h4 class="title">libargon なしでの argon2i(d)</h4>
   <p class="para">
    PHP が libargon
    を使わずにビルドされた場合、<span class="function"><a href="function.password-hash.php" class="function">password_hash()</a></span> 関数は sodium
    拡張モジュールの argon2i と argon2id を使った実装を使うようになります。
   </p>
  </div>

 </div>

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