PHP가 0을 문자열과 같은 것으로 간주하는 이유는 무엇입니까?
다음 코드가 있습니다.
$item['price'] = 0;
/*code to get item information goes in here*/
if($item['price'] == 'e') {
$item['price'] = -1;
}
아이템 가격을 0으로 초기화 한 다음 이에 대한 정보를 얻기위한 것입니다. 가격이 'e'로 표시되면 판매가 아닌 교환을 의미하며 데이터베이스에 음수로 저장됩니다.
아이템이 보너스이거나 나중에 가격이 설정되기 때문에 가격을 0으로 둘 가능성도 있습니다.
그러나 가격이 설정되지 않고 초기 값이 0으로 남을 때마다 if
위에 표시된 루프는 참으로 평가되고 가격은 -1로 설정됩니다. 즉, 0을 'e'로 간주합니다.
어떻게 설명 할 수 있습니까?
편집 : 가격이 0 (초기화 후)으로 제공되면 동작이 불규칙합니다. 경우에 따라 if가 true로 평가되고 때로는 false로 평가됩니다.
당신은 당신 ==
을 위해 유형을 분류하는 것을하고 있습니다.
0
은 int이므로이 경우 'e'
에는 int 로 캐스트 됩니다. 하나로 파싱 할 수 없으며 0
. 문자열 '0e'
은가되고 0
일치합니다!
사용하다 ===
이것은 PHP가 ==
비교 연산자가 나타내는 비교 연산을 수행하는 방식 때문입니다 .
숫자를 문자열과 비교하거나 비교에 숫자 문자열이 포함 된 경우 각 문자열이 숫자로 변환되고 비교가 숫자로 수행됩니다. […] 유형 변환은 비교 일 때
===
또는!==
값뿐만 아니라 유형을 비교하는 것을 포함하기 때문에 발생하지 않습니다 .
첫 번째 피연산자는 숫자 ( 0
)이고 두 번째 피연산자는 문자열 ( 'e'
)이므로 문자열도 숫자로 변환됩니다 ( 다양한 유형과의 비교 표 참조 ). 문자열 데이터 유형에 대한 매뉴얼 페이지는 문자열을 숫자로 변환 하는 방법을 정의 했습니다.
숫자 컨텍스트에서 문자열을 평가할 때 결과 값과 유형은 다음과 같이 결정됩니다.
문자열에 '
.
', 'e
'또는 'E
' 문자가 포함되어 있지 않고 숫자 값이 정수 유형 제한 (에서 정의 됨PHP_INT_MAX
)에 맞으면 문자열이 정수로 평가됩니다. 다른 모든 경우에는 부동 소수점으로 평가됩니다.
이 경우 문자열은 'e'
이므로 float로 평가됩니다.
값은 문자열의 초기 부분으로 제공됩니다. 문자열이 유효한 숫자 데이터로 시작하는 경우이 값이 사용됩니다. 그렇지 않으면 값은
0
(영)이됩니다. 유효한 숫자 데이터는 선택적 부호, 하나 이상의 숫자 (선택적으로 소수점 포함), 선택적 지수입니다. 지수는 'e
'또는 'E
'뒤에 하나 이상의 숫자가 있습니다.
으로 'e'
유효한 숫자 데이터로 시작하지 않는, 그것은 떠 평가합니다 0
.
"ABC" == 0
첫 번째 는 정수로 변환되고 다음 이 true
되기 때문에 평가 됩니다 . "ABC"
0
0
이것은 PHP 언어 의 이상한 동작입니다. 일반적으로 0
문자열로 승격 된 "0"
다음 "ABC"
결과와 비교됩니다 false
. 아마도 그것은 약한 비교가 "ABC" == 0
평가 되는 JavaScript와 같은 다른 언어에서 일어나는 일입니다 false
.
엄격한 비교를 수행하면 문제가 해결됩니다.
"ABC" === 0
평가 false
합니다.
하지만 숫자를 숫자와 문자열로 비교해야한다면 어떻게해야할까요?
"123" === 123
false
왼쪽 및 오른쪽 항이 다른 유형이기 때문에 평가 됩니다.
실제로 필요한 것은 PHP 유형 저글링의 함정이없는 약한 비교입니다.
해결책은 용어를 문자열로 명시 적으로 승격 한 다음 비교를 수행하는 것입니다 (엄격하거나 약한 것은 더 이상 중요하지 않음).
(string)"123" === (string)123
이다
true
동안
(string)"123" === (string)0
이다
false
원래 코드에 적용 :
$item['price'] = 0;
/*code to get item information goes in here*/
if((string)$item['price'] == 'e') {
$item['price'] = -1;
}
The == operator will try to match values even if they are of different types. For instance:
'0' == 0 will be true
If you need type comparison as well, use the === operator:
'0' === 0 will be false
Your problem is the double equal operator, which will typecast the right member to the type of the left. Use strict if you prefer.
if($item['price'] == 'e') {
$item['price'] = -1;
}
Let's go back to your code (copied above). In this case, in most cases, $item['price'] is an integer (except when it is equal to e, obviously). As such, by laws of PHP, PHP will typecast "e"
to integer, which yields int(0)
. (Don't believe me? <?php $i="e"; echo (int)$i; ?>
).
To easily get away from this, use the triple equal (exact comparison) operator, which will check the type and will not implicitly typecast.
P.S: a PHP fun fact: a == b
does not imply that b == a
. Take your example and reverse it: if ("e" == $item['price'])
will never actually be fulfilled provided that $item['price'] is always an integer.
There's a rather handy method in PHP for validating a mix of "0", "false", "off" as == false and "1", "on", "true" as == true which is often overlooked. It's particularly useful for parsing GET/POST arguments:
filter_var( $item['price'], FILTER_VALIDATE_BOOLEAN );
It's not wholy relevant to this use-case but given the similarity and fact this is the result search tends to find when asking the question of validating (string)"0" as false I thought it would help others.
http://www.php.net/manual/en/filter.filters.validate.php
You should use ===
instead of ==
, because the ordinary operator does not compare the types. Instead it will attempt to typecast the items.
Meanwhile the ===
takes in consideration type of items.
===
means "equals",==
means "eeeeh .. kinda looks like"
I think it is best to show by examples i did, while running into the same weird behavior. See my test case and hopefully it will help you understand the behavior better:
//Normal comparison using the == Operator
echo (0 == "0"); // true
echo (0 == "a"); // true
echo (0 == "safta!"); //true
echo (1000 == "bla"); //false. It appears that PHP has a weird behavior only with the number / string 0 / "0" according to the past 3 examples.
echo (23 == "23"); //true. So as we said, PHP has a problem (not a problem but weird behavior) only when the number / string 0 (or "0") is present
echo (23 == "24"); //false. values aren't equal (unlike last example). type is less relevant with the == operator as we can see.
//now using the === and !== Operators
echo ("0" === 0); //false, since === requires both value and type to be the same. here, type is different (int vs string)
echo ("0" !== 0); //true because they aren't the same in terms of === comparison (type is different and that's why its true)
echo ("bla" === "blaa"); //false because the values are not the same. The type is the same but === check for both equal type and equal value
//Now using casting and === Operator:
echo ((string)123 === "123"); //true. The casting of the int 123 to string changed it to "123" and now both vars have same value and are of same type
echo ((int)"123" === 123); //true. The casting of the string 123 to int, changed it to int, and now both vars are of same value and type (which is exactly what the === operator is looking for)
//Now using casting and == Operator. Basically, as we've seen above, the == care less for the
//type of var, but more to the value. So the casting is less relevant here, because even
//without casting, like we saw earlier, we can still compare string to int with the == operator
//and if their value is same, we'll get true. Either way, we will show that:
echo ((string)123 == "123"); //true. The casting of the int 123 to string changed it to "123" and now both vars have same value and are of same type
echo ((int)"123" == 123); //true. The casting of the string 123 to int, changed it to int, and now both vars are of same value and type (which is exactly what the === operator is looking for)
Hope it helps.
참고URL : https://stackoverflow.com/questions/6843030/why-does-php-consider-0-to-be-equal-to-a-string
'programing' 카테고리의 다른 글
리플렉션을 사용하여 메서드가 정적인지 어떻게 확인할 수 있습니까? (0) | 2020.08.16 |
---|---|
WSDL 대 REST 장단점 (0) | 2020.08.16 |
Visual Studio 2013에서 솔루션 파일 (SLN)을 강제로 열려면 어떻게해야합니까? (0) | 2020.08.16 |
json 데이터를 html 테이블로 변환 (0) | 2020.08.16 |
현재 분기의 모든 변경 사항을 Git의 새 분기로 이동 (0) | 2020.08.16 |