PHP字符串比较意想不到的类型杂耍
我在PHP中比较了一些字符串值时遇到了一个奇怪且意外的行为。 当我期望它们返回false时,下面的前两个语句返回true。 最后一条语句按预期返回错误。 我知道PHP的类型杂耍,但我从文档中了解到,类型杂耍发生在比较两种不同的数据类型(如字符串和整数)时。 在下面的例子中,虽然这两个文字都是字符串。 这是否意味着,当你在PHP中进行字符串比较时,它会检查这两个字符串,看看它们是否看起来像整数,如果是,则将这两个字符串转换为整数,然后比较这些整数值。 所以我的问题是在这种行为发生的条件下,字符串比较在PHP中的工作原理是什么?
var_dump("10" == "10.0000");
var_dump("10" == "+10.");
var_dump("10" == "10 ");
#output
bool(true)
bool(true)
bool(false)
更新
所以巴巴在比较下面的答案涉及到数字字符串的确帮助我理解发生了什么。 无论字符串是否被认为是数字字符串,函数is_numeric都会返回给您。 有趣的是, "10 "
不被视为数字字符串,而是" 10"
。 我挖掘了PHP源代码,我相信is_numeric的实现位于is_numeric_string_ex函数中。 从那个人可以确切地知道什么时候PHP将字符串视为数字字符串。
由于空间的位置,这将返回true,所以你会看到错误
var_dump("10" == " 10"); // true
所以如果你运行
var_dump("10" == "10 "); //false
你实际上正在运行的是因为它会被视为一个字符串
var_dump("10" == 0); //false
这是因为类型杂耍会将"10 "
转换为0
这是在PHP文档中
FROM PHP DOC
如果$ a在玩杂耍后等于$ b,则为TRUE。
如果您将数字与字符串进行比较或者比较涉及数字字符串,则将每个字符串转换为数字,并以数字形式进行比较。 这些规则也适用于switch语句。 当比较结果为===或!==时,类型转换不会发生,因为这涉及比较类型和值。
如果你想欺骗类型杂耍
var_dump("10" == 0 + "10 "); // true
这是因为
PHP的自动类型转换的一个例子是加法运算符'+'。 如果任一操作数是一个浮点数,那么这两个操作数都被评估为浮点数,结果将是一个浮点数。 否则,操作数将被解释为整数,结果也将是一个整数。 请注意,这不会改变操作数本身的类型; 唯一的变化就是如何评估操作数以及表达式本身的类型。
我猜想肯定的答案是埋在PHP-src / Zend / zend_operators.c中的compare_function
的巨大地方,以及在那里使用的宏。
在这种情况下,除最后一个之外的所有“字符串”都被视为浮动或整数,然后进行比较。 这就是为什么第1行和第2行是真实的。
在第3行中,字符串中有一个空格,这意味着对于php来说,这是一个“真实”字符串,并且该行可以比较字符串。
我不喜欢loose typed
语言,但对于PHP来说,这是它的工作方式。