为什么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为错误的问题时往往会发现的结果,我认为这会帮助其他人。

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

你应该使用===而不是== ,因为普通的操作符不会比较types的types。 但===考虑到项目的types。