## 新機能

### nullable な型

パラメータや戻り値の型宣言で nullable 指定ができるようになりました。 型の前にクエスチョンマークをつけると、nullable であることを指定できます。 nullable 指定をすると、指定した型だけでなく `null` も渡せるようになります。

    <?php

    function testReturnA(): ?string
    {
        return 'elePHPant';
    }

    var_dump(testReturnA());

    function testReturnB(): ?string
    {
        return null;
    }

    var_dump(testReturnB());

    function test(?string $name)
    {
        var_dump($name);
    }

    test('elePHPant');
    test(null);
    test();

上の例の出力は以下となります。

    string(9) "elePHPant"
    NULL
    string(9) "elePHPant"
    NULL
    Fatal error: Uncaught ArgumentCountError: Too few arguments to function test(), 0 passed in...

### void 関数

戻り値の型として void が導入されました。戻り値の型を void と宣言した関数は、関数内での return 文を省略するか、あるいは空の return を使う必要があります。 void 関数から `null` を返すことはできません。

    <?php
    function swap(&$left, &$right): void
    {
        if ($left === $right) {
            return;
        }

        $tmp = $left;
        $left = $right;
        $right = $tmp;
    }

    $a = 1;
    $b = 2;
    var_dump(swap($a, $b), $a, $b);

上の例の出力は以下となります。

    null
    int(2)
    int(1)

void 関数の戻り値を使おうとした場合はその値は `null` と評価されます。 警告は発生しません。警告を発生させると、一般的な高階関数の利用にも影響するからです。

### 対称的な配列の分解

配列の短縮構文 (`[]`) を使って、 代入用に配列の値を取り出せるようになりました (`foreach` でも使えます)。 これは、list() の代替として使えます (list() もまだ使えます)。

    <?php
    $data = [
        [1, 'Tom'],
        [2, 'Fred'],
    ];

    // list() 形式
    list($id1, $name1) = $data[0];

    // [] 形式
    [$id1, $name1] = $data[0];

    // list() 形式
    foreach ($data as list($id, $name)) {
        // $id と $name を使う処理をここに書きます
    }

    // [] 形式
    foreach ($data as [$id, $name]) {
        // $id と $name を使う処理をここに書きます
    }

### クラス定数のアクセス範囲指定

クラス定数のアクセス範囲を指定できるようになりました。

    <?php
    class ConstDemo
    {
        const PUBLIC_CONST_A = 1;
        public const PUBLIC_CONST_B = 2;
        protected const PROTECTED_CONST = 3;
        private const PRIVATE_CONST = 4;
    }

### iterable 擬似型

新しい擬似型 (callable と同じような型) である iterable が導入されました。 パラメータおよび戻り値の型指定で使うことができます。 配列か、あるいは Traversable インターフェイスを実装したオブジェクトを受け付けるようになります。 派生型に貸しては、子クラスのパラメータの型が、 親クラスの array や Traversable を拡張して iterable に広げることができます。 戻り値の型に関しては、親クラスの iterable 型指定を子クラスで 配列あるいはオブジェクト (Traversable を実装したもの) に絞り込むことができます。

    <?php
    function iterator(iterable $iter)
    {
        foreach ($iter as $val) {
            //
        }
    }

### 例外処理における複数の例外の catch

ひとつの catch ブロックで複数の例外を扱えるようになりました。 パイプ文字 (`|`) を使って指定します。 これは、異なるクラス階層に由来する異なる例外を同じように処理したい場合に有用です。

    <?php
    try {
        // 何かのコード
    } catch (FirstException | SecondException $e) {
        // FirstException と SecondException をこのブロックで処理します
    }

### list() におけるキーのサポート

list() (あるいはその短縮版である `[]` 構文) の内部でキーを指定できるようになりました。 つまり、キーが整数でなかったりシーケンシャルでなかったりした場合でも、 配列の値を取り出せるようになったということです。

    <?php
    $data = [
        ["id" => 1, "name" => 'Tom'],
        ["id" => 2, "name" => 'Fred'],
    ];

    // list() 形式
    list("id" => $id1, "name" => $name1) = $data[0];

    // [] 形式
    ["id" => $id1, "name" => $name1] = $data[0];

    // list() 形式
    foreach ($data as list("id" => $id, "name" => $name)) {
        // $id と $name を使う処理をここに書きます
    }

    // [] 形式
    foreach ($data as ["id" => $id, "name" => $name]) {
        // $id と $name を使う処理をここに書きます
    }

### 負の文字列オフセットのサポート

文字列操作関数 のうちオフセット指定のできるものすべてについて、負のオフセットを指定できるようになりました。 `[]` や `{}` による 文字列への文字単位のアクセス についても同様です。 負のオフセットは、文字列の末尾からのオフセットと解釈されます。

    <?php
    var_dump("abcdef"[-2]);
    var_dump(strpos("aabbcc", "b", -3));

上の例の出力は以下となります。

    string (1) "e"
    int(3)

文字列や配列に対する負のオフセットが、文字列内での単純な変数パース構文においても使えるようになりました。

    <?php
    $string = 'bar';
    echo "The last character of '$string' is '$string[-1]'.\n";
    ?>

上の例の出力は以下となります。

    The last character of 'bar' is 'r'.

### ext/openssl における AEAD のサポート

openssl_encrypt() および openssl_decrypt() の追加のパラメータで、 AEAD (GCM モードおよび CCM モード) をサポートするようになりました。

### Closure::fromCallable() による callables から Closure への変換

Closure クラスに新しいstaticメソッドが追加されました。 callable を、簡単に Closure オブジェクトに変換できるようにするものです。

    <?php
    class Test
    {
        public function exposeFunction()
        {
            return Closure::fromCallable([$this, 'privateFunction']);
        }

        private function privateFunction($param)
        {
            var_dump($param);
        }
    }

    $privFunc = (new Test)->exposeFunction();
    $privFunc('some value');

上の例の出力は以下となります。

    string(10) "some value"

### 非同期シグナルハンドリング

新しい関数 pcntl_async_signals() が追加されました。これは、tick を使わない非同期シグナルハンドリングを有効にするものです (tick は相当大きなオーバーヘッドになります)。

    <?php
    pcntl_async_signals(true); // 非同期シグナルを有効にします

    pcntl_signal(SIGHUP,  function($sig) {
        echo "SIGHUP\n";
    });

    posix_kill(posix_getpid(), SIGHUP);

上の例の出力は以下となります。

    SIGHUP

### ext/curl における HTTP/2 サーバープッシュのサポート

CURL 拡張モジュールがサーバープッシュに対応するようになりました (curl バージョン 7.46 以降が必要です)。 curl_multi_setopt() 関数に新しい定数 `CURLMOPT_PUSHFUNCTION` を指定すれば、この機能を使えます。 また、定数 `CURL_PUSH_OK` と `CURL_PUSH_DENY` も新たに追加されました。 これらは、サーバープッシュコールバックの実行を許可したり拒否したりするものです。

### ストリームコンテキストオプション

tcp_nodelay ストリームコンテキストオプションが追加されました。

`↑` and `↓` to navigate • `Enter` to select • `Esc` to close • `/` to open