programing

PHP가 0을 문자열과 같은 것으로 간주하는 이유는 무엇입니까?

nasanasas 2020. 8. 16. 20:44
반응형

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

반응형