PHP
PHP7
PHP7.3

PHP7.3の新機能

PHP7.3 / PHP7.2 / PHP7.1

2018/06/07にPHP7.3.0 alpha1がリリースされました。
リリースノートはいつものようにFixed bugで埋まってますが、幾つかRFCで決定した新機能が取り込まれてるので見てみます。

RFC

Flexible Heredoc and Nowdoc Syntaxes

ヒアドキュメントnowdocが微妙に使いづらかったのが改善されます。

class foo {
    public $bar = <<<EOT
bar
EOT;
}

終端IDは必ず行頭に置き、空白を入れてはいけない、終端ID以外の文字を置いてもいけない、ということになっています。
クラスやメソッド中などに出てくると、その部分だけインデントがなくなって残念な見た目になります。

// これまでの形式
echo <<<END
      a
     b
    c
END;
/*
      a
     b
    c
*/

// 追加の記法
echo <<<END
      a
     b
    c
    END;
/*
  a
 b
c
*/

上記例では、スペース4個の後に終端IDを書いています。
この場合、ヒアドキュメント文字列も、各行の行頭スペース4個が削除された状態の文字列になります。
自然に書くだけで思ったような文字列が書けるようになるので、これまでよりずっと使いやすくなりそうです。

また、インデントにはスペース以外にタブも使えます。

// 文字列のインデントが足りないとParseError
echo <<<END
  a
 b
c
 END;

// インデントにタブとスペースを混ぜるとParseError
{
    echo <<<END
          a
         END;
}

さらに何故か終端IDの改行要件も削除されます。
正直こちらは入れなくてもよかったんじゃないかという気がしてならないのですが、賛成26反対8の圧倒的多数で導入されました。

// 動く
$values = [<<<END
a
b
ENDING
END, 'd e f'];

// ParseError
$values = [<<<END
a
b
END ING
END, 'd e f'];

// ParseError
echo <<<END
END{$var}
END;

終端IDと同じ文字列がヒアドキュメント文字列中にあると、場合によってはパースエラーになります。
ここは明らかに互換性がなく、英文をヒアドキュメントにしているとひっかかるかもしれません。
ほとんど無いとは思いますが、ヒアドキュメントを多用している場合はバージョンバップに注意しましょう。

Allow a trailing comma in function calls

関数呼び出しで末尾カンマが使えるようになります。

末尾カンマというのは

    use Foo\Bar\{
        Foo,
        Bar,
    };

    $array = [1, 2, ];

最後の,のことで、これまでも配列などで使うことができました。
今後は関数とメソッド、および関数っぽいものの呼び出しにも使えるようになります。

    sprintf($format, $arg1, $arg2, );
    var_dump($a, $b, );
    isset($c, $d, );

    $datetime->format('Y-m-d', );

これができて何がうれしいかというと、可変長引数の関数にコピペで引数追加したいときですね。
var_dump()の末尾,にひっかかったことのある人も多いはず。

    // ParseError 2個は駄目
    foo('function', 'bar',,);

    // ParseError 途中省略は不可
    foo(, 'function', 'bar');

個人的には途中省略がほしいのですが。

JSON_THROW_ON_ERROR

json_encode()json_decode()は処理に失敗したかどうかがわかりにくいです。
json_decodeは失敗時にnullを返しますが、json_decode(null)もnullになるので区別がつきません。
nullになるたびにjson_last_errorで調べなければならないという状態です。

そこで定数JSON_THROW_ON_ERRORを追加します。
json_encode/decodeがエラーになるとJsonExceptionが発生するようになります。

    try{
        json_decode($invalidJson, true, 512, JSON_THROW_ON_ERROR);
    }catch(JsonException $e){
        echo 'JSONデコードでなんかエラー' . json_last_error_msg();
    }

そもそもjson_decodeのオプションが第4引数ってのはどうにかならんのですかね。

PCRE2 Migration

現在のPHPに入っている正規表現ライブラリPCREはバージョン8.xですが、これをPCRE2に移行します。
PCREとどう違うのかはよくわかりません。
既存のテストではbug75207だけがPCRE2の影響を受けたようです。

list() Reference Assignment

list()リファレンス渡しが使えるようになります。

    // 7.2まではFatal error
    $array = [1, 2];
    list($a, &$b) = $array;

おいやめろ馬鹿。この機能は早くも終了ですね。
こんなもの実装するとかちょとsYレならんしょこれは・・・?

is_countable function

PHP7.2でcount()にE_WARNINGが発生するようになったことに伴い、countできるかどうかの判定が必要になりました。

if (is_array($foo) || $foo instanceof Countable) {
    // $foo is countable
}

面倒なので標準関数を用意しました。

if (is_countable($foo)) {
    // $foo is countable
}

そこまでしなくてもという気もしますが、なんというかPHPらしい関数ですね。

その他

PHP7.3で取り込まれたRFCは以上ですが、RFCには載ってないような小さな改修も多々あります。

No way to get current scale in use

bcscaleはスケール値を設定しますが、現在設定されているスケール値を取得する方法がありません
そこで引数がない場合は現在のスケール値を返すようになります。

Add DateTime::createFromImmutable() method

DateTimeからDateTimeImmutableを作るDateTimeImmutable::createFromMutableというメソッドがあるのですが、それの対となるDateTime::createFromImmutableが追加されます。
そもそもどちらにしろ誰が使うのかわかりませんが。

Added support for WebP in imagecreatefromstring()

imagecreatefromstring関数がWebP形式に対応しました。
Image関数は多すぎるのでもうちょっと整理してほしいですね。

Add net_get_interfaces()

net_get_interfaces関数が追加されました。
ネットワークインターフェイスを取得する関数で、IPアドレスにネットマスク、MACアドレスなどを取得できるみたいです。
ifconfigみたいなものでしょうか。

Added gmp_** function

gmp_binomialgmp_lcmgmp_perfect_powergmp_kroneckerの各関数が追加されました。
今のところ詳細がソースにしかないので詳細はわかりませんが、おそらくはまあ名前どおりでしょう。
それにしても名前かっこいいなパーフェクトパワー。

Added openssl_pkey_derive function

openssl_pkey_derive関数が追加されました。
公開鍵暗号の共有鍵を生成する関数で、単にOpenSSLのEVP_PKEY_derive関数を呼んでいるだけのようです。
わざわざPHPでやる必要もない気はしますが。

Removed support for BeOS / ODBCRouter / Birdstep

マジか!これは許されざる変更!!

ところでBeOSでPHPを使ってた人ってどれだけ居るんですかね。
そもそもBeOSが使われているところ自体見たことないですけどね。

感想

ヒアドキュメントと末尾カンマがいいかんじですが、listリファレンスがそれらを補って余りあるマイナスだ。
使うなよ!絶対に使うなよ!

本リリースは名前のとおりまだα版で、本番環境で利用するものではありません。
今後もまたバグを潰していって完成度が高まったところでリリース版が出るでしょうから、遊びで使う人以外はそれまで待ちましょう。
7.2からの互換性が壊れるところはほぼないので、リリースされたらさくっとバージョンアップしてもよさそうです。