PHP / 연산자 / 논리 연산자
PHP 논리 연산자는 조건들을 결합하거나 반대로 바꾸어 true 또는 false를 만듭니다. &&와 and는 둘 다 참일 때, ||와 or는 하나 이상 참일 때 참이고, xor는 정확히 하나만 참일 때 참입니다. 뜻이 비슷한 연산자도 우선순위가 달라 대입문에서 결과가 달라질 수 있습니다.
논리 연산자의 뜻과 진리표
아래 표에서 A와 B는 각각 하나의 조건식입니다. 조건식의 결과를 참·거짓으로 판단한 뒤 연산하므로, 비교식 두 개를 묶거나 여러 검증 조건을 합칠 때 사용할 수 있습니다. !는 오른쪽 값 하나의 참·거짓을 뒤집는 부정 연산자입니다.
| A | B | A && B | A || B | A xor B | !A |
|---|---|---|---|---|---|
| true | true | true | true | false | false |
| true | false | false | true | true | false |
| false | true | false | true | true | true |
| false | false | false | false | false | true |
and는 &&와, or는 ||와 진리표가 같습니다. or는 두 조건이 모두 참인 경우도 포함합니다. 둘 중 하나만 허용하려면 xor를 사용합니다. 문법과 동작은 PHP 논리 연산자 문서에서 확인할 수 있습니다.
PHP가 설치된 환경에서 다음 코드를 logical.php로 저장하고 php logical.php로 실행하면 표의 네 행을 JSON 형식으로 확인할 수 있습니다. 각 예제는 별도 파일로 저장해 실행하세요. PHP의 echo는 false를 빈 문자열로 표시하므로, 참·거짓을 확인할 때는 JSON이나 var_dump()가 더 분명합니다.
<?php
foreach ([[true, true], [true, false], [false, true], [false, false]] as [$a, $b]) {
echo json_encode([
'a' => $a, 'b' => $b,
'and' => $a && $b, 'or' => $a || $b,
'xor' => ($a xor $b), 'not_a' => !$a,
]), PHP_EOL;
}
첫 줄에서는 and와 or가 true이고 xor는 false입니다. 마지막 줄에서는 and·or·xor가 모두 false이고 not_a만 true입니다. 연산 결과는 피연산자 값 자체가 아니라 bool 자료형입니다.
and와 &&는 대입 우선순위가 다릅니다
논리 연산자를 변수 대입과 함께 쓰면 연산 순서를 주의해야 합니다. &&와 ||는 대입 연산자 =보다 먼저 묶이지만, and·xor·or는 =보다 나중에 묶입니다. 다음 예제를 실행하면 같은 참·거짓을 결합해도 저장된 값이 달라지는 이유를 확인할 수 있습니다.
<?php
$a = true && false;
$b = true and false;
$c = false || true;
$d = false or true;
var_dump($a, $b, $c, $d);
$both = (true and false);
$either = (false or true);
$one = (true xor false);
var_dump($both, $either, $one);
처음 네 결과는 차례로 false, true, true, false입니다. $b = true and false는 ($b = true) and false로 묶이므로 $b에는 true가 남습니다. 전체 and 식의 결과인 false가 $b에 대입되는 것이 아닙니다. $d도 같은 이유로 false를 저장합니다.
괄호로 전체 조건을 묶은 마지막 세 결과는 false, true, true입니다. 조건의 결과를 저장하려면 $both처럼 괄호로 의도를 명확히 하세요. 한 식에 서로 다른 연산자를 섞기보다 조건을 나누거나 괄호를 쓰는 편이 읽기 쉽습니다. 자세한 순서는 PHP 연산자 우선순위 표를 참고하세요.
단락 평가로 오른쪽 식이 실행되지 않을 수 있습니다
&&와 and는 왼쪽이 false이면 오른쪽 식을 평가하지 않습니다. ||와 or는 왼쪽이 true이면 오른쪽 식을 평가하지 않습니다. 이미 결과가 결정되었기 때문에 나머지를 생략하는 동작을 단락 평가라고 합니다. xor는 두 값이 모두 필요하므로 같은 방식으로 생략하지 않습니다.
<?php
function checkRight(): bool {
echo "right evaluated", PHP_EOL;
return true;
}
var_dump(false && checkRight());
var_dump(true || checkRight());
var_dump(true && checkRight());
var_dump(false xor checkRight());
처음 두 var_dump()는 각각 bool(false), bool(true)만 출력하며 함수의 문구가 나오지 않습니다. 세 번째와 네 번째 호출에서는 right evaluated가 먼저 출력되고 bool(true)가 이어집니다. 함수를 실행해야 값이 만들어지는 경우에도 오른쪽 호출 자체가 건너뛰어질 수 있다는 뜻입니다.
파일 저장이나 메일 전송처럼 반드시 수행해야 하는 작업을 조건식 오른쪽에 숨겨 두면 의도하지 않게 생략될 수 있습니다. 먼저 필요한 작업을 수행하고 결과를 변수에 받은 뒤 조건을 판단할지, 조건이 맞을 때만 실행할 것인지 구분해서 작성하세요. 우선순위가 식을 묶는 순서와 일반적인 피연산자 평가 순서를 모두 보장하는 것도 아니므로, 한 식에서 같은 변수를 여러 번 변경하는 코드는 피하는 편이 좋습니다.
숫자·문자열의 참·거짓 변환과 조건 작성
논리 연산자에 bool 이외의 값을 주면 PHP의 bool 변환 규칙이 적용됩니다. 흔한 거짓 값에는 false, 정수 0, 실수 0.0, 빈 문자열, 문자열 "0", 빈 배열, null이 있습니다. 문자열 "false"와 원소가 하나인 배열 [0]은 참이므로 문자열의 뜻을 읽어서 판단한다고 생각하면 안 됩니다.
<?php
$value = '12';
if (is_numeric($value) && (float) $value > 0) {
echo "양수입니다.", PHP_EOL;
} else {
echo "양수인 숫자 값이 아닙니다.", PHP_EOL;
}
var_dump((bool) '0', (bool) 'false', (bool) [], (bool) [0]);
이 예제는 양수라는 문장 다음에 false, true, false, true를 순서대로 출력합니다. $value를 abc로 바꾸면 첫 번째 조건이 false여서 숫자 변환과 비교는 생략되고 다른 문장이 출력됩니다. 숫자인지와 양수인지라는 서로 다른 조건을 각각 검사하는 구조입니다.
bool 변환만으로 빈 값, 문자열 "0", 유효하지 않은 입력을 같은 상태로 취급해도 되는지 먼저 판단해야 합니다. 0도 유효한 값이라면 if ($value) 하나로 검증하지 말고 자료형·허용 범위·존재 여부를 명시적으로 검사하세요. 전체 변환 규칙과 객체 등 예외는 PHP bool 자료형 문서에서 확인할 수 있습니다.




