PHP 8에서는 숫자(numeric)를 비교할 때 숫자 비교(number comparison) 방식을 사용합니다. 반면 비교 대상이 숫자가 아니라면, 해당 값을 문자열로 변환한 후 문자열 비교(string comparison)를 수행합니다.
이때 문자열은 다음과 같은 세 가지 유형으로 분류할 수 있습니다.
1. 순수 숫자 문자열(Numeric String)
오직 숫자로만 구성된 문자열입니다. 예: 1234 또는 1.24e1
2. 선행 숫자 문자열(Leading-Numeric String)
숫자로 시작하지만, 그 뒤에 공백을 포함한 비숫자(non-numeric) 문자가 이어지는 문자열입니다. 예: 12xyz 또는 "123"
3. 비숫자 문자열(Non-Numeric String)
숫자로 해석될 수 없으며, 선행 숫자 문자열에도 해당하지 않는 문자열입니다.
PHP 7과 PHP 8의 비교 결과 차이
이러한 분류 기준의 변화로 인해, PHP 7과 PHP 8은 같은 비교 연산에서 서로 다른 결과를 반환합니다.
예제 - PHP 7
0 == 'foo' // PHP 7은 true를 반환합니다.
예제 - PHP 8
0 == 'foo' // PHP 8은 false를 반환합니다.
PHP 7에서는 숫자와 문자열을 비교할 때 문자열이 먼저 숫자로 변환되었기 때문에, 'foo'가 0으로 변환되어 true가 반환되었습니다. 반면 PHP 8에서는 숫자가 아닌 문자열과의 비교 시 숫자를 문자열로 변환하여 비교하기 때문에 false를 반환합니다. 이는 PHP 7까지 존재하던 직관적이지 않은 비교 동작을 개선하여, 개발자가 더욱 예측 가능한 코드를 작성할 수 있도록 돕는 중요한 변화입니다.
예제 - PHP 8 프로그램(Saner String to Number Comparisons)
<?php
$x=[
"1" => "first Integer",
"0123" => "The integer index with leading 0",
"12str" => "using leading numeric string",
" 1" => "using leading whitespace",
"2.2" => "using floating number",
];
print_r($x);
?>
실행 결과
Array
(
[1] => first Integer
[0123] => The integer index with leading 0
[12str] => using leading numeric string
[ 1] => using leading whitespace
[2.2] => using floating number
)
위 실행 결과에서 주목할 점은 배열 키(key)의 처리 방식입니다. PHP 8에서는 "1"처럼 표준적인(canonical) 정수 형태의 문자열만 정수 키로 변환되고, "0123"(앞에 0이 붙은 경우)이나 "12str", " 1"(공백 포함), "2.2"(실수 형태)와 같은 문자열은 문자열 키로 그대로 유지됩니다. 이처럼 PHP 8의 개선된 숫자 비교 규칙은 배열 키 처리에서도 일관성을 제공하여, 의도치 않은 타입 변환으로 인한 버그를 크게 줄여줍니다.