Почему 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 равным «е».

Как это можно объяснить?

Редактировать:
Когда цена указана как 0 (после инициализации), поведение является ошибочным: иногда if оценивается как true, иногда оно оценивается как false.

90

Решение

ты делаешь == который сортирует типы для вас.

0 это int, так что в этом случае он будет разыгрывать 'e' к инт. Который не разбирается как единое целое и станет 0, Строка '0e' станет 0и будет соответствовать!

использование ===

89

Другие решения

Это связано с тем, как PHP выполняет операцию сравнения, == оператор сравнения обозначает:

Если вы сравниваете число со строкой или сравнение включает числовые строки, то каждая строка преобразуется в число, и сравнение выполняется численно. […] Преобразование типов не выполняется при сравнении === или же !== поскольку это включает в себя сравнение типа, а также значения.

Поскольку первый операнд является числом (0) а вторая строка ('e'), строка также преобразуется в число (см. также Таблица Сравнение с различными типами). Страница руководства по строковому типу данных определила, как преобразование строки в число готово:

Когда строка оценивается в числовом контексте, результирующее значение и тип определяются следующим образом.

Если строка не содержит символов.‘,’e‘, или же ‘E‘и числовое значение вписывается в пределы целочисленного типа (как определено PHP_INT_MAX), строка будет оцениваться как целое число. Во всех остальных случаях он будет оцениваться как число с плавающей запятой.

В этом случае строка 'e' и, таким образом, он будет оцениваться как float:

Значение задается начальной частью строки. Если строка начинается с допустимых числовых данных, это будет используемое значение. В противном случае значение будет 0 (нуль). Допустимые числовые данные — это необязательный знак, за которым следуют одна или несколько цифр (необязательно содержащих десятичную точку), за которыми следует необязательный показатель степени. Экспонентаe‘ или же ‘E‘следуют одна или несколько цифр.

Как 'e' не начинается с правильных числовых данных, он оценивается как плавающий 0,

44

"ABC" == 0

оценивает true так как первый "ABC" преобразуется в целое число и становится 0 затем это по сравнению с 0,

Это странный поведение языка PHP: обычно можно ожидать 0 быть повышен до строки "0" а затем по сравнению с "ABC" с результатом false,
Возможно, это то, что происходит в других языках, таких как JavaScript, где слабое сравнение "ABC" == 0 оценивает 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;
}
11

Оператор == будет пытаться сопоставить значения, даже если они имеют разные типы. Например:

'0' == 0 will be true

Если вам также нужно сравнение типов, используйте оператор ===:

'0' === 0 will be false
8

Ваша проблема — оператор двойного равенства, который приведёт правый член к типу левого. Используйте строгий, если вы предпочитаете.

if($item['price'] == 'e') {
$item['price'] = -1;
}

Давайте вернемся к вашему коду (скопировано выше). В этом случае в большинстве случаев $ item [‘price’] является целым числом (за исключением случаев, когда, очевидно, оно равно e). Таким образом, по законам PHP, PHP будет приведен "e" в целое число, которое дает int(0), (Не верите мне? <?php $i="e"; echo (int)$i; ?>).

Чтобы легко избежать этого, используйте оператор тройного равенства (точное сравнение), который проверит тип и не будет неявно преобразовывать тип.

P.S: PHP забавный факт: a == b не означает, что b == a, Возьмите свой пример и переверните его: if ("e" == $item['price']) фактически никогда не будет выполнено при условии, что $ item [‘price’] всегда является целым числом.

8

В PHP есть довольно удобный метод проверки сочетания «0», «false», «off» как == false и «1», «on», «true» как == true, который часто упускается из виду. Это особенно полезно для разбора аргументов GET / POST:

filter_var( $item['price'], FILTER_VALIDATE_BOOLEAN );

Это не совсем относится к этому варианту использования, но, учитывая сходство и факт, этот результат поиска имеет тенденцию обнаруживаться при задании вопроса о проверке (строка) «0» как ложного, я думал, что это поможет другим.

http://www.php.net/manual/en/filter.filters.validate.php

6

Вы должны использовать === вместо ==потому что обычный оператор не сравнивает типы. Вместо этого он попытается выполнить типизацию предметов.

Между тем === принимает во внимание тип предметов.

  • === означает «равно»,
  • == означает «ээээ .. вроде как»
5

Я думаю, что лучше всего показать на примерах, которые я сделал, в то же время столкнувшись с таким же странным поведением. Смотрите мой тестовый пример, и, надеюсь, он поможет вам лучше понять поведение:

//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)

Надеюсь, поможет.

0
По вопросам рекламы [email protected]