WebエンジニアのLoL日記

LoLをプレイしたりLJLの試合を見たりするのが好きなエンジニア。LoLのイベントやパッチノートなど気になった点を記事にしたり、LJLについの記事をかいたりしています。某社でWeb系のエンジニアとして働いているので、技術系の記事もたまに書きます。コンタクトを取りたい場合はtwitterまで。

PHP 7.4で追加される ??= 演算子はそんなに使えないんじゃないだろうか

f:id:yoshiki_utakata:20190111231914p:plain

概要

PHP 7.4 から ??= 演算子が追加されることが確定しました。

github.com

??= 演算子とは

$var ??= <value> は、 $varnull のときに $var<value> を代入する演算子です。

$parameter ??= 'デフォルト値';

// これは以下と同じ意味になります
$parameter = $parameter ?? 'デフォルト値';

この演算子が使えない理由

単純に読みづらいのもありますが「変数の再代入(mutable)」が前提なのが非常に悪です。

使用例を見てみましょう

$text = 'デフォルトテキスト';

// リクエストからtextが入力された場合はそのテキストを
// リクエストがない場合はデフォルトテキストを利用する
$text ??= $request->getParam('text');

しかしこれはこうでいいです

$text = $request->getParam('text') ?? 'デフォルトテキスト';

記述の手間がそんなに変わってないうえに再代入がなくなり非常にすっきりします。コード追っていく中で同じ変数名の中身が変化する再代入はバグの元になり、一般的にはよろしくないと言われています。

関係する演算子の歴史

??= がどういう流れの中でできたか、そしてついでに関連する演算子についても詳しくなろうのコーナー。

三項演算子 a ? b : c

多くの言語の実装されている演算子です。

$text = $request->getParam('text') === null ? $request->getParam('text') : 'デフォルトテキスト';
  • aがtrueのときはb
  • aがfalseのときはc

が結果として返ります。

二項演算子 ?:

上記の a ? b : c だと$request->getParam('text') が2回出てきた場合に冗長なので省略形です。PHP5.3から追加されました。

$text = $request->getParam('text') ?: 'デフォルトテキスト';

これは以下の書き方の省略形です。

$text = $request->getParam('text') ? $request->getParam('text') : 'デフォルトテキスト';

ただしこれには問題があります。$request->getParam('text') が falsy な値、例えば空文字('')などでも 'デフォルトテキスト' が入ってしまうのです。本当は空文字が入れたいのにデフォルトテキストが。それを解決するのが次の ?? 演算子です。

演算子 ??

$text = $request->getParam('text') ?: 'デフォルトテキスト';

これは以下と同じ意味になります。

$text = $request->getParam('text') === null ? $request->getParam('text') : 'デフォルトテキスト';

うん、この ?? 演算子めっちゃ便利そうですね。PHP7から追加されました。ここから今回の ??= へとつながるわけですが、、、 ?? までで十分だったのでは。個人的には ??= は「実装されないほうがよかった」まであります。

まとめ

とはいえ、今後追加される新機能との組み合わせすごい便利な演算子になったりする...?かもしれません。

参考

Web API: The Good Parts

Web API: The Good Parts

パーフェクトPHP (PERFECT SERIES 3)

パーフェクトPHP (PERFECT SERIES 3)