4.

PHPの論理演算子|&& || ! and or xor・優先順位と短絡評価

編集
この記事の要点
  • 論理演算子は真偽値(bool)どうしを組み合わせて新しい真偽値を作る演算子
  • PHP には記号版(&& || !)と単語版(and or xor)の 2 系統があり、優先順位が違う
  • &&||短絡評価(short-circuit): 左辺だけで結果が決まるなら右辺を評価しない
  • 代入と一緒に使うときは記号版を使う($x = $a or $b; は意図と違う挙動になる)
  • 関連の演算子として三項 ? :、null 合体 ??、null 合体代入 ??= も覚えておくと条件分岐が短く書ける

論理演算子とは

論理演算子は 真偽値(bool) どうしを組み合わせて新しい真偽値を作る演算子です。if 文や while 文の条件式で複数の条件を合成するときに使います。

PHP の論理演算子一覧

演算子名前意味
$a && $bAND(記号版)両方が true のとき true
$a || $bOR(記号版)どちらかが true のとき true
!$aNOTtrue / false を反転
$a and $bAND(単語版)両方が true のとき true
$a or $bOR(単語版)どちらかが true のとき true
$a xor $b排他的 ORどちらか一方だけが true のとき true

基本の真理値表

ABA && BA || BA xor B!A
truetruetruetruefalsefalse
truefalsefalsetruetruefalse
falsetruefalsetruetruetrue
falsefalsefalsefalsefalsetrue

基本的な使用例

<?php
$age = 25;
$hasLicense = true;

// AND(両方とも成立)
if ($age >= 20 && $hasLicense) {
    echo "運転 OK\n";
}

// OR(どちらかが成立)
if ($age < 18 || $age > 65) {
    echo "割引対象\n";
}

// NOT(反転)
if (!$hasLicense) {
    echo "免許が必要です\n";
}

// 複合
$isMember = false;
if (($age >= 20 && $hasLicense) || $isMember) {
    echo "入場可\n";
}

短絡評価(Short-Circuit Evaluation)

PHP の &&||左辺だけで結果が決まるなら右辺を評価しない という性質を持ちます。これを利用して、null チェックと使用を 1 行で書けます。

<?php
// $user が null でないときだけ $user->name を参照
if ($user !== null && $user->name === 'Taro') {
    echo "Hi, Taro!\n";
}

// $user が null だと右辺は評価されないので安全
// ※ 左右を入れ替えると null->name で警告 / エラー

// 「もし存在すれば呼び出す」イディオム
$callback && $callback();   // $callback が truthy なら実行

記号版と単語版の優先順位の違い

PHP では 記号版(&& ||)の方が単語版(and or)より優先順位が高い代入演算子 = よりも、単語版は低く、記号版は高いのがポイントです。

<?php
// 記号版: && は = より優先順位が高い → 期待通り動く
$ok = $a && $b;   // ($a && $b) を $ok に代入

// 単語版: and は = より優先順位が低い → 直感に反する
$ok = $a and $b;  // ($ok = $a) のあとに and $b($b は捨てられる)

そのため 代入と一緒に使うときは必ず && / || を使うのが鉄則です。and / or はあえて優先順位を下げたいケース(早期 return との組み合わせなど)で使われる程度です。

真偽値として扱われる値(truthy / falsy)

PHP は弱い型付け言語のため、論理演算子に bool 以外の値を渡しても自動で真偽判定されます。falsy(偽として扱われる) な値は以下のとおりです。

判定
falsefalsy
nullfalsy
0 / 0.0falsy
"0"falsy(文字列「0」も偽になる)
""(空文字)falsy
[](空配列)falsy
それ以外(負数 / "false" 文字列 / オブジェクト等)truthy

とくに "0" が falsy になる挙動は他言語と異なるため要注意です。意図せず空判定で弾かれることがあります。

三項演算子と null 合体演算子(関連)

論理演算子と一緒に覚えると条件分岐が短く書けます。

<?php
// 三項演算子: 条件 ? 真の値 : 偽の値
$msg = $age >= 20 ? "大人" : "子ども";

// 短縮三項(PHP 5.3+): $a ?: $b → $a が truthy なら $a、そうでなければ $b
$name = $input ?: "ゲスト";

// null 合体(PHP 7+): $a ?? $b → $a が null(または未定義)なら $b
$name = $_GET["name"] ?? "ゲスト";

// null 合体代入(PHP 7.4+)
$config["timeout"] ??= 30;  // 未設定ならデフォルトを入れる

「未定義変数 + 既定値」の組み合わせは ??、「空文字も含めて偽として扱いたい」のは ?:、「真偽そのものを取りたい」のは三項 ? : と使い分けます。

よくあるハマりどころ

症状原因 / 対処
$x = $a or $b; が想定通り動かないor= より優先度が低い。$x = $a || $b; を使う
"0" が if で偽になるPHP の falsy ルール。厳密判定したいなら $x !== "" と書く
右辺を評価したいのに評価されない&& / || は短絡評価。副作用が必要なら左右順序を入れ替えるか and / or
複雑な条件で読みづらい変数に分けて命名する($canEnter = $age >= 20 && $hasLicense;
否定の二重否定 !!$valuetruthy/falsy を bool 型に正規化するイディオム。(bool)$value と同義

関連

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. 算術演算子
  2. 代入演算子
  3. 比較演算子
  4. 論理演算子

最近更新/作成されたページ