为什么PHP认为0等于一个string?
我有以下一段代码:
$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(初始化后),行为是不稳定的:有时候,如果评估为真,有时评估为假。
你正在做==
为你sorting的types。
0
是一个int,所以在这种情况下,它将把'e'
为一个int。 这是不能parsing为一个,将成为0
。 一个string'0e'
将变成0
,并且会匹配!
使用===
这是因为PHP如何执行==
比较运算符表示的比较操作 :
如果您将数字与string进行比较,或者比较涉及数字string,则将每个string转换为数字,并以数字forms进行比较。 […]当比较是
===
或!==
时,不会发生types转换,因为这涉及比较types和值。
由于第一个操作数是一个数字( 0
),第二个操作数是一个string( 'e'
),该string也被转换为一个数字(另请参见与各种types比较表 )。 string数据types的手册页定义了如何完成string到数字的转换 :
当在数值上下文中计算string时,结果值和types如下确定。
如果该string不包含任何字符'
.
','e
'或'E
',并且数字值符合整数types限制(由PHP_INT_MAX
定义),则string将被评估为整数。 在所有其他情况下,它将被评估为浮动。
在这种情况下,string是'e'
,因此它将被评估为一个浮点数:
该值由string的起始部分给出。 如果string以有效的数字数据开始,则这将是使用的值。 否则,该值将是
0
(零)。 有效的数字数据是一个可选符号,后跟一个或多个数字(可选地包含一个小数点),后跟一个可选的指数。 指数是一个“e
”或“E
”,后跟一个或多个数字。
由于'e'
不以有效的数字数据开始,因此它评估为浮点数0
。
==运算符将尝试匹配值,即使它们是不同的types。 例如:
'0' == 0 will be true
如果您还需要types比较,请使用===运算符:
'0' === 0 will be false
你的问题是双等号运算符,它会将右边的成员转换成左边的types。 严格使用,如果你喜欢。
if($item['price'] == 'e') { $item['price'] = -1; }
让我们回到您的代码(上面复制)。 在这种情况下,在大多数情况下,$ item ['price']是一个整数(除非明显等于e)。 因此,通过PHP的法律,PHP会将"e"
转换为整数,从而得到int(0)
。 (不要相信我? <?php $i="e"; echo (int)$i; ?>
)。
为了轻易摆脱这种情况,使用三等分(精确比较)运算符,它将检查types,不会隐含types转换。
PS:一个PHP有趣的事实: a == b
并不意味着b == a
。 拿你的例子来说吧, if ("e" == $item['price'])
$ item ['price']总是一个整数, if ("e" == $item['price'])
永远不会实现。
PHP中有一个相当方便的方法来validation“0”,“false”,“off”为== false和“1”,“on”,“true”as == true的混合,这经常被忽略。 这对parsingGET / POST参数特别有用:
filter_var( $item['price'], FILTER_VALIDATE_BOOLEAN );
这与用例并不相关,但考虑到相似性和事实,这是search在将(string)“0”validation为错误的问题时往往会发现的结果,我认为这会帮助其他人。
你应该使用===
而不是==
,因为普通的操作符不会比较types的types。 但===
考虑到项目的types。