PHP7.4の新機能その2

PHP7.4その1 / PHP7.4その2

2019/06/13、PHP7.4.0α1がリリースされました

今後はベータ、RCと完成度を高めていき、7.4.0のリリースは2019/11/28が予定されています。

なお仕様フィックスは2019/07/13で、それ以降は大きな変更は入らないようになります。

逆に言うとそれまでは追加が入る可能性はあるのですが、既にα1も出たことですし、さすがにこれからのタイミングでプロパティ型指定やらアロー関数レベルの大改修が入ることはないでしょう。

ということで前回以降入った新機能や変更点を見てみることにします。


RFC


Arrow functions 2.0

賛成51、反対8で受理。

アロー関数です。

    // 新構文

$fn = fn($x) => $x + $y;

// ↓と同じ
$fn = function ($x) use ($y) {
return $x + $y;
};

functionのもったり感から解放されます。


Change the precedence of the concatenation operator

賛成31、反対4で受理。

演算子+-.の優先順位変更です。

    // PHP7.3まで

echo "3" . "5" + 7; // 42

// PHP7.4
echo "3" . "5" + 7; // 42だがE_DEPRECATED

// PHP8
echo "3" . "5" + 7; // "312"

数値演算が文字列結合より優先されるようになり、イメージした通りの計算結果になりやすくなります。

まあ、こういうのはそもそも括弧を使うべきだとは思いますが。


Numeric Literal Separator

賛成33、反対11で受理。

数値セパレータです。

$threshold = 1_000_000_000;

$testValue = 107_925_284.88;
$discount = 135_00;

数値が見やすくなります。

テストに失敗して一時期Pending行きになっていたのですが、その後無事にマージすることができたようです。


Deprecate left-associative ternary operator

賛成35、反対10で受理。

三項演算子のネスト制限です。

1 ? 2 : 3 ? 4 : 5;   // deprecated

(1 ? 2 : 3) ? 4 : 5; // ok
1 ? 2 : (3 ? 4 : 5); // ok

何故か他言語と異なる評価順の三項演算子を今後合わせていくための布石で、括弧を使わずにネストするとE_DEPRECATEDが発生するようになります。


Allow throwing exceptions from __toString()

賛成42、反対0で受理。

__toString()が例外を吐けるようになります。

ユーザ側というより、エクステンション開発者向けの機能なのかもしれません。

「マージしたらめっちゃコンフリクトした」とかnikicが言ってました。


Covariant Returns and Contravariant Parameters

賛成39、反対1で受理。

共変戻り値と反変パラメータのRFC。

単語の意味はよくわかりませんが、簡単に言うと、子クラスの型宣言で親クラスの型宣言を狭められるというものです。

class A {

function test(): DateTimeInterface{
return new DateTimeImmutable();
}
}

class B extends A {
function test(): DateTimeImmutable{
return new DateTimeImmutable();
}
}

PHP7.3まではB:testの返り値の型がA::testと違う、と怒られていました。

Javaあたりでは普通にできるので、それを取り入れたものでしょう。

継承関係にないクラスを指定したり、逆に型宣言を広げたりすると、当然ながら今後も怒られます。


Spread Operator in Array Expression

賛成43、反対1で受理。

引数アンパックを配列中でも使えるようになります。

$array1 = [11, 12];

$array2 = [21, 22];
$array = [1, ...$array1, 2, ...$array2, 3]; // [1, 11, 12, 2, 21, 22, 3]

地味だけど、正直今回の変更点の中で一番有用なんじゃないかと思わないでもない。

配列の後ろに他の配列を追加したいという要件はよくあって、+array_mergeでは思ったようにいかないことが多いですからね。


Deprecate and remove ext/interbase

賛成49、反対0で受理。

Firebird/InterBaseいらんだろ、というRFC。

今後はPDO_FIREBIRDを使うことになります。

そもそもこれを使っている人は居るのだろうか。


weakrefs

賛成28、反対5で受理。

弱い参照です。

PHPには既にWeakRefがあるのだけど、それよりさらに弱く、必要最低限のcreategetしかないみたいです。

使いどころは正直よくわかりません。


Unbundle ext/wddx

賛成30、反対0で受理。

WDDXをPHPコアから削除するRFC。

今後はPECLに移動になります。

WDDXとは異なる言語間でデータをやりとりするための仕組みですが、全く普及しないままXML-RPCやSOAPに取って代わられ、そしてそれらも滅んでJSONにほぼ統一されました。

wddx_deserializeには安全でないデシリアライゼーションという仕様上の脆弱性があり、それをどうにかしようというRFCが提出されて話し合われたものの、そもそもWDDX自体いらなくね?って展開になったみたいです。


New custom object serialization mechanism

賛成20、反対7で受理。

マジックメソッド__serialize__unserializeを追加します。

PHPでオブジェクトのシリアライズ方法にはSerializable__sleep/__wakeupがあるのですが、実は両方とも問題を抱えています。

そこで新たな直列化方法を提供します。

ということらしいのですが問題点が細かすぎてよくわかりませんでした。

複雑な書き方をしたりすると正しくシリアライズできない、ということらしいのですが、そんな複雑な書き方をしない方がよいですよね。

そもそも個人的にはオブジェクトをシリアライズするってことを(無意識のセッション以外)全くしないので、利点も欠点もなんとも言えないのですが。


Pending

本来PHP7.4で入るはずだったのに、保留行きにされているRFC。

今後の展開次第では7.4に入るかもしれませんし、入らないかもしれません。


Deprecate PHP's Short Open Tags

賛成38、反対18で受理。

short_open_tagが削除されます。

やっぱ延長するかも?みたいな話になっていて、ちょっとどうなるかわかりません。


感想

PHP7.4やばすぎでは…?

変更があまりにドラスティックすぎて、PG能力がPHP7.4以前と以後で分断されるんじゃないかレベル。

現状PHP8で入る予定の大きな変更がJITくらいしかないので、もしかしたらPHP7.4→8よりPHP7.3→7.4のほうが大きな差になったりするかもしれませんね。さすがにないかな?