Menu

PHPの三項演算子:?:の省略形とネストの書き方

PHPの三項演算子は1行で書けるif/elseです:$result = $condition ? 'yes' : 'no';。省略形の?:(エルビス演算子)、??との違い、PHP 8でネストした三項演算子に括弧が必要な理由、matchのほうがすっきりする場面を学びます。

このページのコードはエディタで実行できます - 編集してすぐに結果を確認できます。

三項演算子は、1つの式に収まるif/elseです:condition ? valueIfTrue : valueIfFalse。2つの値のどちらかを返すので、代入したり、echoしたり、関数に渡したりできます。

$ageを15に、$itemsを3に変えて、もう一度実行してみてください。最後の行で三項演算子を括弧で囲んでいる点に注目してください。括弧がないと.が先に文字列を結合してしまい、意図した結果になりません。

HTMLテンプレートの中の三項演算子

テンプレートの中でCSSクラス、ラベル、属性を選ぶときは、三項演算子を使うのが定番です。このブロックはURLから?stock=を読み取ります。実行してからPageタブのリンクをクリックすると、別の値で同じスクリプトがもう一度実行されます。

<?= ... ?>は<?php echo ... ?>の短縮形で、マークアップの中でも1行の条件を読みやすく保てます。

省略形の三項演算子?:(エルビス演算子)

真ん中の部分を省くと$a ?: $bになります。$aがtrueと評価される値なら$aを、そうでなければ$bを返します。空文字列や0のときも代わりの値にしたい場合の既定値に便利です。

falseと評価される値はfalse、0、0.0、""、"0"、[]、nullです。データの中で"0"が正当な答え(数量の欄、暗証番号)である場合、省略形の三項演算子はそれを捨ててしまいます。

?:と??の違い

見た目は似ていますが、確認する内容が違います。?:は左辺がfalseと評価される値のときに代わりの値を使います。??は左辺がnullか未設定のときだけ代わりの値を使い、存在しない変数や配列キーについて警告を出しません。

「値が存在しないかもしれない」(リクエストのデータ、設定の配列、任意のキー)には??を使い、「値は存在するが空かもしれない」には?:を使います。??と??=についてはnull合体演算子のページで詳しく扱っています。

ネストした三項演算子には括弧が必要

PHP 7は、ほかのほとんどの言語と違ってa ? b : c ? d : eを左から右に読み、間違った結果を出していました。PHP 8は推測を拒否します。

<?php
echo $score > 90 ? "A" : $score > 80 ? "B" : "C";
PHP Fatal error:  Unparenthesized `a ? b : c ? d : e` is not supported. Use either `(a ? b : c) ? d : e` or `a ? b : (c ? d : e)` in /home/index.php on line 2

内側の三項演算子を括弧で囲めば動きます。

省略形の三項演算子は例外で、上のエルビスの例のように$a ?: $b ?: $cは括弧なしで書けます。

分岐が3つ以上ならmatch(true)を使う

3段や4段にネストした三項演算子は、括弧があっても読みにくくなります。trueを対象にしたmatchは、条件を上から順に調べて、最初に一致したアームを返します。

1行で2つの結果を選ぶときは三項演算子を使い、3つ目が必要になったらすぐにmatchかif/elseifの連鎖に切り替えましょう。

よくある質問

PHPの三項演算子とは何ですか?

値を返すif/elseの短縮形です:$label = $age >= 18 ? 'adult' : 'minor';。?の前の条件がtrueなら?のあとの式が、そうでなければ:のあとの式が使われます。

PHPの?:はどういう意味ですか?

$a ?: $bは省略形の三項演算子(エルビス演算子とも呼ばれます)です。$aがtrueと評価される値なら$aを、そうでなければ$bを返すので、'' ?: 'default'は'default'です。$a ? $a : $bと同じですが、$aは1回しか評価されません。

PHPで三項演算子をネストできますか?

括弧を付ければできます。PHP 8以降、$a ? 'x' : $b ? 'y' : 'z'は致命的エラーなので、$a ? 'x' : ($b ? 'y' : 'z')と書きます。分岐が3つ以上なら、match(true)かif/elseifの連鎖のほうが読みやすくなります。

else部分のない三項演算子は使えますか?

使えません。三項演算子には常に両方の分岐が必要です。「この値、なければ代わりの値」なら$x ?: 'default'か$x ?? 'default'と書き、条件が成り立つときだけ何かをするなら、普通のifか$condition && doSomething();と書きます。

Coddyのプログラミング言語のイラスト

Coddyでコードを学ぼう

始める