新機能

nullable な型

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

<?php

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

var_dump(testReturn());

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

var_dump(testReturn());

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

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

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

string(10) "elePHPant"
NULL
string(10) "elePHPant"
NULL
Uncaught Error: 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 インターフェイスを実装したオブジェクトを受け付けるようになります。 派生型に貸しては、子クラスのパラメータの型が、 親クラスの arrayTraversable を拡張して 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_OKCURL_PUSH_DENY も新たに追加されました。 これらは、サーバープッシュコールバックの実行を許可したり拒否したりするものです。

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

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