У меня есть следующий фрагмент кода:
$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 оценивается как истина, иногда как ложь. *
if((string)$item['price'] == 'e')
исправляет странное поведение. См. Stackoverflow.com/a/48912540/1579327 для получения более подробной информацииОтветы:
Вы делаете то,
==
что сортируете для вас.0
является int, поэтому в этом случае он будет приведен'e'
к int. Который не разобрать как один и станет0
. Строка'0e'
стала0
бы и соответствовала!Использовать
===
источник
Это связано с тем, как PHP выполняет операцию
==
сравнения, которую обозначает оператор сравнения :Поскольку первый операнд - это число (
0
), а второй - строка ('e'
), строка также преобразуется в число (см. Также таблицу Сравнение с различными типами ). На странице руководства, посвященной строковому типу данных, определено, как выполняется преобразование строки в число :В этом случае строка будет
'e'
и поэтому будет оцениваться как число с плавающей запятой:Поскольку
'e'
не начинается с действительных числовых данных, он оценивается как плавающий0
.источник
вычисляет,
true
потому что сначала"ABC"
преобразуется в целое число, а0
затем становится равным0
.Это странное поведение языка PHP: обычно можно ожидать,
0
что он будет преобразован в строку,"0"
а затем будет сравниваться"ABC"
с результатомfalse
. Возможно, это то, что происходит в других языках, таких как JavaScript, где"ABC" == 0
оценивается слабое сравнениеfalse
.Строгое сравнение решает проблему:
оценивает
false
.Но что, если мне нужно сравнить числа как строки с числами?
оценивается,
false
потому что левый и правый член имеют разные типы.Что действительно необходимо, так это слабое сравнение без ловушек, связанных с подтасовкой типов PHP.
Решение состоит в том, чтобы явно преобразовать термины в строку, а затем выполнить сравнение (строгий или слабый больше не имеет значения).
является
true
пока
является
false
Применяется к исходному коду:
источник
Оператор == будет пытаться сопоставить значения, даже если они разных типов. Например:
Если вам также нужно сравнение типов, используйте оператор ===:
источник
Ваша проблема - оператор двойного равенства, который преобразует правый член в тип левого. Если хотите, используйте строгий.
Вернемся к вашему коду (скопирован выше). В этом случае в большинстве случаев $ item ['price'] является целым числом (кроме случаев, когда оно, очевидно, равно e). Таким образом, по законам PHP тип PHP преобразуется
"e"
в целое число, что даетint(0)
. (Не верите?<?php $i="e"; echo (int)$i; ?>
).Чтобы легко уйти от этого, используйте оператор тройного равенства (точное сравнение), который проверяет тип и не выполняет неявное приведение типов.
PS: забавный факт о PHP:
a == b
это не означаетb == a
. Возьмите ваш пример и переверните его: наif ("e" == $item['price'])
самом деле никогда не будет выполнено при условии, что $ item ['price'] всегда является целым числом.источник
В PHP есть довольно удобный метод проверки сочетания «0», «false», «off» как == false и «1», «on», «true» как == true, который часто упускается из виду. Это особенно полезно для анализа аргументов GET / POST:
Это не совсем уместно для этого варианта использования, но, учитывая сходство и факт, что это результат поиска, как правило, он находит, когда задается вопрос о проверке (строка) «0» как ложного. Я думал, что это поможет другим.
http://www.php.net/manual/en/filter.filters.validate.php
источник
Вы должны использовать
===
вместо==
, потому что обычный оператор не сравнивает типы. Вместо этого он попытается привести элементы к типу.При этом
===
учитывается тип предметов.===
означает "равно",==
означает "ээээ ... вроде как"источник
if((string)$item['price']=='e'){ $item['price'] = -1; }
===
операторомЯ думаю, что лучше всего показать это на примерах, которые я сделал, столкнувшись с тем же странным поведением. Посмотрите мой тестовый пример, и, надеюсь, он поможет вам лучше понять поведение:
источник
По сути, всегда используйте
===
оператор, чтобы гарантировать безопасность типа.источник