PHPのand,or演算子の使い道を考えてみる

PHPのand,or演算子の使い道を考えてみる
LINEで送る
Pocket

突然ですが、PHPの問題です。

おなじみのand, or演算子の優先順位テストです。
それぞれの$aには何が代入されているでしょうか。

答え

答えは以下の通りです。

だいぶ気持ち悪いですね。

特に、

  • $a = true and false => true
  • $a = false or true => false

上記2つは初見殺しにも程が有ります。

なぜこのような問題が起こるかというと、
and, or演算子は=よりも優先度が低いため、

評価される際には、このような式になっているためです。

このように非常に難解な動きをするand, or演算子ですが、
論理式とは少し違う使い方を見つけたので、メモを残しておきます。


面白い書き方

and, orは論理演算子なので基本的にif文やwhile等の評価式の中に使用します。
しかし、評価式として使用しない使用方法があるようです。

こんなコードを用意してみました。
このコードを実行すると何が出力されるでしょう。

はい。どうでしょうか。

  • andの手前の式がtrueと評価される場合には後ろの式が実行され、
  • orの手前の式がfalseと評価される場合には後ろの式が実行され、
  • それ意外の場合は後ろの式が実行されない

という書き方ができます。

※ ちなみにechoをそのまま書くと構文エラーになります
PHP Parse error: syntax error, unexpected ‘echo’ (T_ECHO)


実用例

(実用的かどうか微妙な例ですが、)実際にある場面を例にあげます。

構文の都合上、関数の引数のデフォルト値に指定できない値
例えばクロージャ(function() {})などを初期化する際には、

と書くことがあると思います。 こんな時に、andを使うことで、初期化の式を少しだけシンプルに出来ます。

実際に試してみると、

初期化できています。

ちなみに、意味が分かりづらいので個人的には嫌いですが、 更にタイプ量を削るなら、デフォルト値をnullでなくfalseにしておき、

orを使ってこう書くこともできます。
結局トリッキーさは抜けませんが、慣れれば案外見やすい書き方かもしれません。

トリッキーなので自分は使いませんが、こんな使い方もできるそうです。
というご紹介でした。


あとがき

ちなみに&&||でも同じことができます。
あれ、その書き方どこかで・・・

jsはちょっと違いましたね。

LINEで送る
Pocket

  • コメントありがとうございます!

    三項演算子の省略は、issetと合わせた結果を使用できれば良いのですが、今回のような必ず変数が定義されているケースでないとNoticeが出るので悩ましいところですね。

    isset($hoge[‘key’]) ? $hoge[‘key’] : ‘some value’;
    といったよくある三項演算をやってくれる機能が欲しいです…。

  • とず

    function foo($fn = null) {
     $fn = $fn ?: function() {};
    }

    jsの||みたいに書くには?:を使います。
    エルビス演算子といいます。
    内部解釈はjsとは若干違って、3項演算子の1項目と2項目が同じ場合は2項目を省略可能であることを利用しています。