PHPのXORについて

採用はこちら

PHPのXORとは、主に 「どちらか一方だけが真の場合に真になる」 という考え方を持つ演算のことです。

XORは「exclusive OR」の略で、日本語では 排他的論理和 と呼ばれます。

通常の「OR」は、AまたはBのどちらか一方、あるいは両方が真であれば真になります。

一方、XORは AとBのどちらか一方だけが真の場合に true になります。

両方が true の場合や、両方が false の場合は false になります。

PHPでは、XORに関係するものとして、主に次の2つがあります。

xor
^

この2つはどちらもXORに関係しますが、意味や使い方は異なります。

xor論理演算子 です。

条件分岐などで、true / false の判定に使います。

一方、^ビット演算子 です。

整数や文字列に対して、ビット単位のXOR演算を行うときに使います。

そのため、PHPのXORを理解するときは、まず 論理演算子の xor とビット演算子の ^ は別物 と考えることが大切です。

目次

PHPの論理演算子 xor の意味

xor はどちらか一方だけが true のときに true になる

PHPの xor は、左右の条件のうち どちらか一方だけが true の場合に true になります。

基本的な結果は、以下のようになります。

true xor true   // false
true xor false  // true
false xor true  // true
false xor false // false

表にすると、次の通りです。

左辺右辺結果
truetruefalse
truefalsetrue
falsetruetrue
falsefalsefalse

ポイントは、両方が true の場合は false になる ことです。

通常の or であれば、両方が true の場合も true になります。

しかし、xor は「どちらか一方だけ」という条件なので、両方が true の場合は条件に合いません。

orxor の違い

orxor は似ていますが、判定結果が異なります。

var_dump(true or true);  // bool(true)
var_dump(true xor true); // bool(false)

or は、片方でも true なら true です。

そのため、両方が true でも true になります。

一方、xor は、片方だけが true のときに true です。

そのため、両方が true の場合は false になります。

例えば、次のような条件を考えてみます。

$hasEmail = true;
$hasPhone = false;

if ($hasEmail xor $hasPhone) {
    echo 'メールアドレスまたは電話番号のどちらか一方だけが入力されています。';
}

この場合、$hasEmail は true、$hasPhone は false です。

つまり、どちらか一方だけが true なので、xor の結果は true になります。

しかし、次のように両方が true の場合は、結果が変わります。

$hasEmail = true;
$hasPhone = true;

if ($hasEmail xor $hasPhone) {
    echo 'どちらか一方だけ入力されています。';
} else {
    echo '両方入力されている、または両方入力されていません。';
}

この場合、両方が true なので、xor の結果は false です。

PHPで xor を使う場面

どちらか一方だけを許可したい場合

xor は、「AまたはBのどちらか一方だけを許可したい」という条件を表すときに使えます。

例えば、フォームで「メールアドレス」または「電話番号」のどちらか一方だけを入力させたい場合です。

$email = 'test@example.com';
$phone = '';

if (!empty($email) xor !empty($phone)) {
    echo 'OK';
} else {
    echo 'メールアドレスまたは電話番号のどちらか一方だけを入力してください。';
}

このコードでは、!empty($email)!empty($phone) の結果を xor で判定しています。

$email だけが入力されている場合は true になります。

$phone だけが入力されている場合も true になります。

しかし、両方入力されている場合や、両方未入力の場合は false になります。

フォームバリデーションで使う例

実務で考えると、xor はバリデーション処理で使えることがあります。

例えば、「メールアドレスか電話番号のどちらか一方だけを受け付ける」関数は、次のように書けます。

function validateContact($email, $phone): bool
{
    $hasEmail = !empty($email);
    $hasPhone = !empty($phone);

    return $hasEmail xor $hasPhone;
}

使用例は次のとおりです。

var_dump(validateContact('test@example.com', ''));             // bool(true)
var_dump(validateContact('', '09012345678'));                  // bool(true)
var_dump(validateContact('test@example.com', '09012345678'));  // bool(false)
var_dump(validateContact('', ''));                             // bool(false)

このように、xor を使うと「どちらか一方だけ」という条件を短く表現できます。

ただし、xor に慣れていない人にとっては少し読みづらい場合があります。

チーム開発では、可読性を優先して別の書き方を選ぶこともあります。

xor を使わずに同じ条件を書く例

xor を使わずに、「どちらか一方だけ」を表すこともできます。

if (($hasEmail && !$hasPhone) || (!$hasEmail && $hasPhone)) {
    echo 'どちらか一方だけ入力されています。';
}

この書き方は少し長くなりますが、条件の意味は明確です。

  • メールがあり、電話番号がない
  • または、メールがなく、電話番号がある

という条件をそのままコードにしています。

xor を使うと短く書けますが、読み手によっては意味をすぐに理解できない場合があります。

そのため、実務では 短さよりも分かりやすさを優先する ことも大切です。

xor^ の違い

xor は論理演算子

PHPの xor は、論理演算子です。

条件式の true / false を判定するために使います。

$a = true;
$b = false;

var_dump($a xor $b);

結果は次のようになります。

bool(true)

これは、$a が true、$b が false で、どちらか一方だけが true だからです。

一方、両方が true の場合は false になります。

$a = true;
$b = true;

var_dump($a xor $b);

結果は次の通りです。

bool(false)

xor は、あくまで論理的な判定に使うものです。

数値のビットを直接操作するものではありません。

^ はビット演算子

PHPの ^ は、ビット演算子です。

整数に対して使うと、ビット単位でXOR演算を行います。

$a = 5; // 0101
$b = 3; // 0011

echo $a ^ $b;

結果は次のようになります。

6

2進数で見ると、次のようになります。

5 = 0101
3 = 0011
---------
    0110 = 6

^ は、各ビットを比較して、片方だけが 1 の場合に 1 にします。

両方が 1 の場合や、両方が 0 の場合は 0 になります。

つまり、^ は true / false の条件判定というより、ビット単位の計算 に使う演算子です。

xor^ を混同しない

PHPでは、xor^ を混同しないことが重要です。

演算子種類主な用途
xor論理演算子条件式で true / false を判定する
^ビット演算子整数や文字列をビット単位で処理する

条件分岐で「どちらか一方だけ true か」を判定したい場合は、基本的に xor を使います。

if ($a xor $b) {
    echo 'どちらか一方だけ true です。';
}

一方、数値のビットを操作したい場合は ^ を使います。

$result = $a ^ $b;

この2つは見た目も用途も違うため、記事やコード内で説明するときは明確に分ける必要があります。

ビット演算子 ^ の使い方

整数に対する ^ の例

^ は、整数のビット演算で使えます。

$a = 10; // 1010
$b = 6;  // 0110

echo $a ^ $b;

この場合、2進数で考えると次のようになります。

10 = 1010
 6 = 0110
---------
     1100 = 12

そのため、結果は次のようになります。

12

^ は、同じビットなら 0、異なるビットなら 1 にする演算です。

^ はビットの切り替えにも使える

ビットXORは、特定のビットを反転させる用途にも使えます。

$flags = 0b0101;
$mask  = 0b0001;

$flags = $flags ^ $mask;

echo $flags;

この場合、右端のビットが反転します。

0101
0001
----
0100

もう一度同じマスクでXORを行うと、元に戻ります。

$flags = $flags ^ $mask;
0100
0001
----
0101

この性質から、XORはオン・オフを切り替えるような処理で使われることがあります。

ただし、一般的なWebアプリケーションやWordPress開発では、ビット演算を頻繁に使う場面はそれほど多くありません。

^ は文字列にも使える

PHPでは、文字列同士に対して ^ を使うこともできます。

$a = "A";
$b = "B";

$result = $a ^ $b;

var_dump($result);

文字列同士に ^ を使うと、文字を構成するバイトに対してビット演算が行われます。

そして、結果も文字列になります。

ただし、この使い方は一般的なPHP開発ではあまり登場しません。

通常のフォーム処理、データベース操作、Webサイト制作、WordPressテーマ開発などでは、文字列に対して ^ を使う機会は少ないです。

使われるとすれば、バイナリデータ処理や低レイヤー寄りの処理、簡易的な難読化などです。

そのため、初心者向けの記事では、文字列の ^ については「使えるが、一般的にはあまり使わない」と説明すると分かりやすいです。

PHPの xor で注意すべき優先順位

xor は優先順位が低い

PHPの xor で特に注意したいのが、演算子の優先順位です。

次のコードを見てください。

$result = true xor true;

var_dump($result);

一見すると、true xor true が先に計算されて、$result には false が入るように見えるかもしれません。

しかし、実際には $result には true が入ります。

なぜなら、PHPでは xor の優先順位が代入演算子 = よりも低いからです。

つまり、次のように解釈されます。

($result = true) xor true;

この場合、まず $result = true が行われます。

そのため、$result には true が代入されます。

その後、true xor true のような評価が行われますが、代入済みの $result の値は true のままです。

代入するときは括弧を使う

xor の結果を変数に代入したい場合は、必ず括弧を使うのが安全です。

$result = (true xor true);

var_dump($result);

結果は次のようになります。

bool(false)

このように書けば、true xor true の結果が先に評価され、その結果が $result に代入されます。

PHPで xor を使う場合、特に代入と組み合わせるときは、次のように括弧を付けるとよいです。

$result = ($a xor $b);

括弧を付けることで、意図しない評価順になるのを防げます。

andorxor は優先順位に注意が必要

PHPには、論理演算子として次のようなものがあります。

&&
||
and
or
xor

このうち、&&|| はよく使われます。

一方で、andorxor は優先順位が低いため、代入と組み合わせると注意が必要です。

例えば、次のコードを見てください。

$result = true && false;

この場合は、true && false の結果が $result に入ります。

つまり、$result は false になります。

しかし、次のコードでは結果が変わります。

$result = true and false;

この場合、and の優先順位が低いため、次のように解釈されます。

($result = true) and false;

そのため、$result には true が入ります。

xor も同じように優先順位が低いため、代入と組み合わせるときは特に注意が必要です。

複雑な条件式では括弧を使う

次のようなコードは、非常に分かりにくくなります。

$result = $a xor $b && $c;

このコードは、ぱっと見ただけではどの順番で評価されるのか分かりにくいです。

意図としては、次のどちらかかもしれません。

$result = ($a xor ($b && $c));

または、

$result = (($a xor $b) && $c);

どちらの意味にしたいかによって、結果は変わる可能性があります。

さらに、xor は代入演算子よりも優先順位が低いため、括弧なしで書くと、期待した通りに $result へ結果が代入されないことがあります。

そのため、複雑な条件式では、必ず括弧を使って意図を明確にするべきです。

$result = ($a xor ($b && $c));

または、

$result = (($a xor $b) && $c);

コードは、実行結果が正しければよいだけではありません。

後から読んだ人が正しく理解できることも重要です。

xor と真偽値の扱い

xor は値を真偽値として評価する

xor は論理演算子なので、対象の値を true / false として評価します。

PHPでは、次のような値は false として扱われます。

false
0
0.0
''
'0'
[]
null

一方、空でない文字列や、0以外の数値などは true として扱われます。

例えば、次のコードを見てください。

var_dump('hello' xor '');

'hello' は true として扱われます。

空文字 '' は false として扱われます。

そのため、結果は次のようになります。

bool(true)

このように、xor は必ずしも boolean 型だけに使われるわけではありません。

ただし、実務では暗黙の型変換に頼りすぎると、コードの意図が分かりにくくなります。

明示的な真偽値にしてから使うと分かりやすい

フォーム入力の判定などでは、次のように一度 boolean 型の変数にしてから xor を使うと読みやすくなります。

$hasEmail = !empty($email);
$hasPhone = !empty($phone);

if ($hasEmail xor $hasPhone) {
    echo 'どちらか一方だけ入力されています。';
}

このように書くと、$hasEmail$hasPhone が何を意味しているのかが分かりやすくなります。

直接次のように書くこともできます。

if (!empty($email) xor !empty($phone)) {
    echo 'どちらか一方だけ入力されています。';
}

ただし、条件が長くなる場合は、変数に分けた方が可読性は高くなります。

xor!= の違い

真偽値同士なら似た結果になる

真偽値同士であれば、xor!= は似た結果になります。

$a = true;
$b = false;

var_dump($a xor $b); // bool(true)
var_dump($a != $b);  // bool(true)

両方が同じ場合は false になります。

var_dump(true xor true);    // bool(false)
var_dump(true != true);     // bool(false)

var_dump(false xor false);  // bool(false)
var_dump(false != false);   // bool(false)

このように、boolean の比較だけを見ると、xor!= は似ています。

xor は論理演算、!= は比較演算

ただし、xor!= は同じものではありません。

xor は論理演算子です。

左右の値を真偽値として評価し、「どちらか一方だけが true か」を判定します。

一方、!= は比較演算子です。

左右の値が等しくないかどうかを比較します。

つまり、意味としては次のように分けて考えると分かりやすいです。

書き方意味
$a xor $b真偽値として見たとき、どちらか一方だけが true か
$a != $b値として等しくないか

排他的な真偽判定をしたいなら xor、値の不一致を調べたいなら != を使うとよいです。

xor を使うときの実務上の注意点

可読性を重視する

xor は便利ですが、PHPのコードで頻繁に使われる演算子ではありません。

そのため、xor に慣れていない人が読むと、意味を理解するのに少し時間がかかる場合があります。

例えば、次のコードは短く書けます。

if ($hasEmail xor $hasPhone) {
    echo 'どちらか一方だけ入力されています。';
}

しかし、人によっては次のように書いた方が直感的に理解しやすい場合があります。

if (($hasEmail && !$hasPhone) || (!$hasEmail && $hasPhone)) {
    echo 'どちらか一方だけ入力されています。';
}

前者は短く、後者は条件の意味が明確です。

どちらがよいかは、プロジェクトの方針やチームの理解度によって変わります。

保守性を重視するなら、無理に xor を使わず、分かりやすい条件式にするのもよい選択です。

副作用のある処理を直接書かない

xor の左右に、関数呼び出しを直接書く場合は注意が必要です。

if (checkA() xor checkB()) {
    echo '条件に一致しました。';
}

このようなコードでは、checkA()checkB() の中で何が行われるかによって、コードの安全性や読みやすさが変わります。

特に、関数の中で次のような処理をしている場合は注意が必要です。

  • データベースを更新する
  • ファイルを書き換える
  • メールを送信する
  • ログを記録する
  • 外部APIを呼び出す

xor は、&&|| のように左辺だけで結果を確定できる演算子ではありません。

そのため、左右に副作用のある処理を置くと、コードの意図が分かりにくくなります。

安全に書くなら、一度変数に分けるとよいです。

$isA = checkA();
$isB = checkB();

if ($isA xor $isB) {
    echo '条件に一致しました。';
}

このように書くと、どの処理がいつ実行されるのかが分かりやすくなります。

3つ以上の条件には慎重に使う

xor は2つの条件を比較するときには分かりやすいですが、3つ以上の条件に使うと意味が分かりにくくなります。

if ($a xor $b xor $c) {
    echo '条件に一致しました。';
}

このコードは、読み手にとって解釈が難しくなります。

「3つのうち1つだけ true」を意味しているのか、「true の数が奇数なら true」を意味しているのか、意図が伝わりにくいからです。

3つ以上の条件で「1つだけ true」を判定したい場合は、カウントした方が分かりやすいです。

$count = 0;

if ($a) $count++;
if ($b) $count++;
if ($c) $count++;

if ($count === 1) {
    echo '1つだけ true です。';
}

配列を使う場合は、次のようにも書けます。

$values = [$a, $b, $c];

$count = count(array_filter($values));

if ($count === 1) {
    echo '1つだけ true です。';
}

ただし、array_filter() はコールバックを指定しない場合、PHPで false とみなされる値を取り除きます。

厳密に true だけを数えたい場合は、次のように書くと明確です。

$values = [$a, $b, $c];

$count = count(array_filter($values, fn($value) => $value === true));

if ($count === 1) {
    echo '1つだけ true です。';
}

boolean 型の値だけを扱うのか、PHP的に true と評価される値を扱うのかによって、書き方を選ぶとよいです。

PHPのXORを使うべき場面

「どちらか一方だけ」を明確に表したい場合

xor が向いているのは、条件の意味が明確に「どちらか一方だけ」の場合です。

例えば、次のようなケースです。

$usePassword = true;
$useOAuth = false;

if ($usePassword xor $useOAuth) {
    echo '認証方式は1つだけ選択されています。';
}

このコードでは、パスワード認証かOAuth認証のどちらか一方だけが選ばれているかを判定しています。

このように、2つの選択肢のうち片方だけを許可したい場合、xor は簡潔に条件を表現できます。

条件を短く書きたい場合

xor を使うと、条件式を短く書けます。

if ($a xor $b) {
    // どちらか一方だけ true
}

これを &&||! で書くと、次のようになります。

if (($a && !$b) || (!$a && $b)) {
    // どちらか一方だけ true
}

どちらも意味は同じですが、xor の方が短く書けます。

ただし、短く書けることが常に良いとは限りません。

読み手が理解しやすいかどうかも考える必要があります。

PHPのXORを使わない方がよい場面

読み手が理解しにくい場合

xor は一般的な &&|| に比べると、使用頻度が低い演算子です。

そのため、チーム内で xor に慣れていない人が多い場合は、あえて使わない方がよいこともあります。

例えば、次のように明示的に書いた方が、初心者には分かりやすい場合があります。

if (($hasEmail && !$hasPhone) || (!$hasEmail && $hasPhone)) {
    echo 'どちらか一方だけ入力されています。';
}

可読性を重視する場合は、無理に xor を使う必要はありません。

代入と組み合わせる場合

xor は代入演算子より優先順位が低いため、代入と組み合わせると意図しない結果になりやすいです。

避けた方がよい書き方は、次のようなものです。

$result = $a xor $b;

この書き方では、$a xor $b の結果が $result に入るとは限りません。

安全に書くなら、次のように括弧を使います。

$result = ($a xor $b);

特に初心者向けの記事では、xor の優先順位について必ず説明しておくと親切です。

条件が複雑になる場合

条件が複雑になる場合も、xor は避けた方がよいことがあります。

if (($a xor $b) && ($c xor $d)) {
    // 処理
}

このようなコードは、慣れていない人には分かりにくくなります。

複雑な条件では、途中の判定を変数に分けると読みやすくなります。

$isContactValid = $hasEmail xor $hasPhone;
$isLoginValid = $usePassword xor $useOAuth;

if ($isContactValid && $isLoginValid) {
    echo '条件を満たしています。';
}

さらに明確にしたい場合は、xor を使わずに条件を分解してもよいです。

PHPのXORに関するよくある間違い

xoror を同じ意味だと思ってしまう

xoror は似ていますが、同じではありません。

true or true   // true
true xor true  // false

or は、両方が true でも true です。

xor は、両方が true だと false です。

「どちらか一方だけ」という条件が必要な場合に xor を使います。

xor^ を同じように使ってしまう

xor^ は、どちらもXORに関係しますが、用途が違います。

$a xor $b

これは論理演算です。

$a ^ $b

これはビット演算です。

条件分岐で使いたいのか、ビット計算をしたいのかによって、使う演算子を分ける必要があります。

括弧を付けずに代入してしまう

次のコードは、間違いやすい例です。

$result = true xor true;

この場合、$result には false ではなく true が入ります。

正しくは、次のように書きます。

$result = (true xor true);

xor を代入と一緒に使う場合は、括弧を付ける習慣を持つと安全です。

PHPのXORのまとめ

xor は「どちらか一方だけ true」を判定する演算子

PHPの xor は、論理演算子です。

左右の条件のうち、どちらか一方だけが true の場合に true になります。

true xor false  // true
false xor true  // true
true xor true   // false
false xor false // false

「AまたはBのどちらか一方だけを許可したい」という条件を表すときに便利です。

^ はビット単位のXORを行う演算子

PHPの ^ は、ビット演算子です。

整数に対して使うと、ビット単位でXOR演算を行います。

$a = 5; // 0101
$b = 3; // 0011

echo $a ^ $b; // 6

xor は論理演算、^ はビット演算です。

この違いを混同しないようにしましょう。

実務では優先順位と可読性に注意する

PHPで xor を使うときに最も注意したいのは、演算子の優先順位です。

特に、次のような書き方は避けた方が安全です。

$result = $a xor $b;

xor の結果を代入したい場合は、次のように括弧を付けます。

$result = ($a xor $b);

また、xor は便利な演算子ですが、使い慣れていない人にとっては分かりにくい場合があります。

コードの短さだけでなく、後から読んだ人が理解しやすいかどうかも考えることが大切です。

以上、PHPのXORについてでした。

最後までお読みいただき、ありがとうございました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次