奇怪的PHP字符串整数比较和转换

6

在我处理数据解析代码时,我遇到了以下问题。

$line = "100 something is amazingly cool";
$key = 100;

var_dump($line == $key);

大多数人都会期望该转储产生一个false,但令我惊讶的是,转储出现了true

我了解在PHP中存在这样的类型转换:

$x = 5 + "10 is a cool number"; // as documented on PHP manual
var_dump($x); // int(15) as documented.

但是为什么像我在第一个例子中提到的比较会将我的字符串转换为整数而不是将整数转换为字符串呢。

我知道你可以对我的示例进行严格比较===,但我只想知道:

  • PHP文档中是否有提到这种行为?
  • 有人能解释一下在PHP中发生了什么吗?
  • 程序员如何避免这种问题?

"==" 在编程中表示数字比较,当你将一个字符串转换成数字时,如果它以数字开头,它会使用该数字。如果不是数字,则可能返回类似 NaN 的内容。 - rubixibuc
当将一个字符串转换为整数(比较字符串和数字时会发生这种情况),大多数人都会期望PHP在遇到第一个非数字字符时停止转换,例如"100 something"中的空格。所以结果值为100。 - Mark Baker
请参见https://dev59.com/Z2w15IYBdhLWcg3wFHtZ#8672423。 - Gumbo
http://php.net/manual/en/language.operators.comparison.php - rubixibuc
@mark 是的,大多数人在进行算术运算时都会期望进行转换,但在比较运算中呢? - mauris
这一切都有详细的记录在PHP手册中,可参考页面http://www.php.net/manual/en/language.types.string.php 的 “将字符串转换为数字”章节了解有关字符串->数值转换的详细信息,并参考页面http://php.net/manual/en/language.operators.comparison.php 中的“与各种类型比较”表格来了解关于字符串/数值比较将字符串转换为数值的解释。 - Mark Baker
2个回答

4

如果我没记错的话,PHP会将这两个变量强制转换为最低可能的类型。他们称之为类型转换。

例如,请尝试运行:var_dump("something" == 0);,这将给你返回 true。我曾经因此遇到过问题。

更多信息可以查看:http://php.net/manual/en/language.operators.comparison.php


PHP手册现在在http://php.net/manual/en/language.types.type-juggling.php描述了类型转换,该页面链接到有关字符串转换为数字的部分http://php.net/manual/en/language.types.string.php#language.types.string.conversion。 - Josip Rodin

1

我知道这个问题已经有答案并被接受,但我想补充一些可能会帮助到通过搜索找到这篇文章的其他人的内容。

当我在比较一个PHP数组中的post数组和键时,我遇到了同样的问题,在我的post数组中,我有一个额外的字符串值。

$_POST["bar"] = array("other");

$foo = array(array("name"=>"foobar"));

foreach($foo as $key=>$data){
    $foo[$key]["bar"]="0";
    foreach($_POST["bar"] as $bar){
        if($bar==$key){
            $foo[$key]["bar"]="1";
        }
    }
}

从这个例子中,你可能会认为最终$foo[0]["bar"]等于"0",但实际上发生的是当$key = int 0$bar = string "other"松散比较时结果是true。为了解决这个问题,我进行了严格比较,但之后需要将$key = int 0转换成$key = string "0"以适应POST数组定义为array("other","0");。以下是成功的解决方法:

$_POST["bar"] = array("other");

$foo = array(array("name"=>"foobar"));

foreach($foo as $key=>$data){
    $foo[$key]["bar"]="0";
    foreach($_POST["bar"] as $bar){
        if($bar==="$key"){
            $foo[$key]["bar"]="1";
        }
    }
}

如果"0"在POST bar数组中,结果为$foo[0]["bar"]="1",否则结果为$foo[0]["bar"]="0"。请记住,在比较变量时,由于PHP的弱类型,您的变量可能不会像您想象的那样进行比较。

也许只是我个人的看法,但你的示例过于复杂了。问题似乎在于你将 $foo 定义为嵌套在常规数组中的关联数组,但随后使用关联数组表达式 ($key=>$data) 来解析常规数组。如果数据必须进行这种嵌套,为什么不在另一个循环中嵌套该循环以处理常规数组呢? - Josip Rodin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接