最近 PHP の資格を取ろうとしているんですが、どうせなら国際資格にしようと思って Zend 社の Zend Certified PHP Engineer を勉強しています。
その中で、論理演算について目からウロコ(ただし使うかどうかは不明)な情報があったので紹介したいと思います。
TL;DR
- PHP の論理演算子は英語でも書ける
- 記号で書く方が英語で書く方より処理が先に行われる
- うまいこと使えば括弧地獄を軽減できる(が、おすすめはしない)
- 「かつ」「または」の意味で使うなら記号で書いた方が安全
論理演算子とは
論理演算子は真偽値同士の演算をするための演算子です。
-
&&: 演算子の両側がtrueの場合に限り、結果がtrueとなる。「論理積」ともいう。 -
||: 演算子の片側がtrueの場合に結果がtrueとなる。両側がtrueでもよい。「論理和」ともいう。 -
!: 真偽値の左側について、真偽値を反転させる。例えば!trueはfalseになる。
これらの記号には英語表記も存在します。
-
andは上記の&&の説明と同じ動作をする。 -
orは上記の||の説明と同じ動作をする。 -
xor: 演算子のどちらか片側がtrueの場合に限り、結果がtrueとなる。両側がtrueの場合はfalseとなる。
論理和が先に計算されてしまう罠
優先順位は、 && と || では && が先、 and と or では and が先です。
では、以下の場合はどうでしょうか?
-
指摘がありましたので削除しました&&とor -
andと||
論理和と論理積の計算順序によって結果が変わるような例で確認してみましょう。
<?php
echo "'and' と '||' では ";
if (true || false and false) {
echo "'and' が優先される", PHP_EOL;
} else {
echo "'||' が優先される", PHP_EOL;
}
'and' と '||' では '||' が優先される
なんと、記号の方が先に計算され、特に 2 つ目の例では論理積と論理和の順番に関する「神話」が崩れてしまったではありませんか。
急いでマニュアルの 演算子 のところを確認しましょう!
マニュアルによると
マニュアル の Operator Precedence の表によると、論理演算子の優先順位は以下のようになります。
| 順位 | 演算子 |
|---|---|
| 1 | ! |
| 2 | && |
| 3 | || |
| 4 | and |
| 5 | xor |
| 6 | or |
記号の方が順位が上に来ていることがわかります。
PHP において && と and 、 || と or はそれぞれ全く同じ意味というわけではないため、動きを理解したうえで使う必要があります。
(個人的非推奨) 括弧地獄の軽減に役立てる例
PHP で開発中に条件分岐が複雑になり、 if の中身がこんな感じになってしまった人もいるのではないでしょうか?
if (($person->入場券を持っている() && ($person->ちゃんと列に並んでる() || $person->isおりこうさん())) || ($person->特別な券を持っている() && $person->is55歳以上である())
) {
// 処理
}
論理演算子の優先順位を正しく理解すれば、括弧を使わずに書くこともできます。
if (
$person->入場券を持っている()
and $person->ちゃんと列に並んでる() || $person->isおりこうさん()
or $person->特別な券を持っている() && $person->is55歳以上である()
) {
// 処理
}
でも個人的には流行らないのかなあと思っています。
なぜかというと使う記号が増えて直感的に読めなくなり、 PHP の論理演算子に関する深い理解を強いられるからです。
というか、ここまで複雑な条件を書くことになる前にコードそのものを見直してください。
会社で提供したいサービスに合わせて言語を選定している企業さんや、新人さんをたくさん採用されている企業さんでは、引き続き括弧を補助的に用いて && と || だけで論理を記述することをおすすめします。
PHP の資格を取りたい人は私と一緒に頑張って覚えましょう。
資格取得のためには、言語仕様を細かく理解する必要があります。