DarkLogo

意外と知らないPHP 論理値

· Kishimoto

この記事はZennに過去私が投稿していた記事になります。 -> 過去記事

結論

$variableA = true;
$variableB = true;
if ($variableA && $variableB) {
    print_r("&& true \n");
}
// && true

$variableC = true;
$variableD = false;
if ($variableC || $variableD) {
    print_r("|| true \n");
}
// || true

上を下に書き換えることできるの知ってる?

$variableA = true;
$variableB = true;
if ($variableA and $variableB) {
    print_r("and true \n");
}
// and true

$variableC = true;
$variableD = false;
if ($variableC or $variableD) {
    print_r("or true \n");
}
// or true

※ちなみにandとorはANDとORでも良い

経緯/切っ掛け

業務中に後ろの同僚がコード書いてたのでチラッと覗くとPHP書いてて 流し読みしたら明らかに違和感ある"or"を書いてて思わず「何これ??」って言っちゃいました。

それでドキュメント読んでみたら本当に使える様でそれなりにPHPやってきたけど こんな初歩的な事でもマジで知らない事あるんだなとそりゃもうビックリしました。 https://www.php.net/manual/ja/language.operators.logical.php

とは言え全く同じと言うわけではない様なのでもうちょっとだけ掘って見ました。

深堀

いつも通りpaiza code editor使って検証します。 https://paiza.io/ja/projects/new

上記に貼ったドキュメント見れば書いてあるんですが “and"および"or"演算子が 2 種類あるのは、演算が行われる際の優先順位が異なっているためです だそうです。

この”優先順位“がイマイチピンと来なかったので実際に動かして見ようと思ったわけです。

いつものif文とかで使うのと同じ状況を再現します。

$a = (true && false);
// bool(false)
$b = (true and false);
// bool(false)
$c = (false || true);
// bool(true)
$d = (false or true);
// bool(true)

これは特に差異は無さそうですね。 だから結論に記載した置き換えが可能になるわけです。

では括弧を外すとどうなるでしょうか?

$e = true && false;
// bool(false)
$f = true and false;
// bool(true)
$g = false || true;
// bool(true)
$h = false or true;
// bool(false)

直感と反した物になってますね。

これもドキュメントに書いてるのですがどうやら”優先順位“とは和差積商とかで言う、掛け算や割り算だったり括弧の中を優先的に計算する的な意味で &&|| は優先順位が高いので先に処理され同じ結果になるのですが andor は優先順位が低いため今回の場合

$f = true
$h = false

が先に処理されて

$f and false
$h or true

が後に処理されるので結果が異なってきます。

ちょっと分かり辛いので念の為補足するとe, gには先に計算された結果が格納されるけれど、 f, hには先に単にtrueやfalseが代入されてその後、式の処理する。これはあくまで処理するだけなので”この処理結果は特にf, hには格納しない“という事です。

感想

いやマジでこんなことあんのか、知らんかった・・・・。に尽きます 他の言語とかでも?と思ってJavaScriptのドキュメントも見て見ましたがどうやらそんなことはなさそう。 そんでこれ知ったのは良いけどバグ産むだけやろ・・・どこで使うねん・・・と思っております。

なんかこのケースだと必須やで!みたいなのあれば是非教えてください!! 以上です。