Php 为什么in_array()会错误地使用这些(大数字)字符串返回true?

Php 为什么in_array()会错误地使用这些(大数字)字符串返回true?,php,arrays,Php,Arrays,我不明白这个代码有什么问题。它正在返回“已找到”,但不应该返回 $lead = "418176000000069007"; $diff = array("418176000000069003","418176000000057001"); if (in_array($lead,$diff)) echo "Found"; else echo "Not found"; 这是因为PHP中的一个缺陷4181760000000069007修改为2147483647(PHP的整数限制)。

我不明白这个代码有什么问题。它正在返回“已找到”,但不应该返回

$lead = "418176000000069007";
$diff = array("418176000000069003","418176000000057001");

if (in_array($lead,$diff))
    echo "Found";
else
    echo "Not found";

这是因为PHP中的一个缺陷<代码>4181760000000069007修改为2147483647(PHP的整数限制)。这就是找到
的原因

在数组中尝试
($lead,$diff,true)

注意:这是PHP旧版本中的一个错误,在
PHP5.4
和更新版本中已更正。

这是因为
PHP

这里真正的问题是因为
PHP\u INT\u MAX
——在我们的例子中超出了这个值

在不使用引号的情况下,尝试
echo
/
打印
$lead
$diff
。结果会是

$lead ---> 418176000000070000  
$diff ---> Array ( [0] => 418176000000070000 [1] => 418176000000060000 )
因此,在这种情况下,数组中的
结果为真

因此,通过将
中的第三个参数设置为
true,在
中使用
strict
比较
     if(in_array($lead,$diff,true)) //use type too
       echo "Found";
     else
       echo "Not found";
?>

试试这个。它会工作。

值超过
PHP\u INT\u MAX
。尝试执行
if(在数组中($lead,$diff,true))

注意:此行为在PHP5.4中已更改

默认情况下,_array
中的
使用松散比较(
=
),这意味着数字字符串将转换为数字并作为数字进行比较。在PHP5.4之前,如果您的平台的浮点类型没有足够的精度,那么就会丢失差异,并得到错误的答案

解决方案是通过向数组中的
传递额外的
布尔值
参数来启用
严格的
比较(
==
):

  $lead = "418176000000069007";
  $diff = array("418176000000069003", "418176000000057001");

  if ( in_array($lead, $diff, true) ) 
    echo "Found";
  else
    echo "Not found";
然后将这些字符串作为没有数字强制的字符串进行比较。但是,这意味着您确实会丢失“01234”和“1234”等字符串的默认等价性


这种行为在PHP5.4中得到了修复。与
=
相比,数字字符串仍然会转换为数字,但前提是字符串的值符合平台的数字类型

尝试使用括号并使用严格模式:

$lead = "418176000000069007";
$diff = array("418176000000069003","418176000000057001");

if(in_array($lead, $diff, true)) {
    echo "Found";
} else {
    echo "Not found";
}

_数组中的
应严格执行

$lead = "418176000000069007";
  $diff = array("418176000000069003","418176000000057001");

  if(in_array($lead,$diff,true)) 
    echo "Found";
  else
    echo "Not found";
此问题是由于您的数字超出了定义的整数限制


注:最大值取决于系统。32位系统的最大有符号整数范围为
-2147483648
2147483647
。例如,在这样一个系统上,
intval('1000000000000')
将返回
2147483647
。64位系统的最大有符号整数值为
9223372036854775807

如果第三个参数strict设置为TRUE,那么
in_array()
函数还将检查干草堆中的针的类型,因为限制超出了最大整数值

因此,如果PHP遇到一个超出整数类型边界的数字,它将被解释为浮点。此外,导致数字超出整数类型边界的操作将返回浮点值。查看PHP手册

if (in_array($lead,$diff,true))
发件人:

在数值上下文中计算字符串时,结果值 和类型确定如下

如果字符串包含以下任何一项,则该字符串将作为浮点值进行计算: 字符“.”、“e”或“e”。否则,它将被评估为 整数

正如其他一些人提到的,您应该使用strict for:

bool-in_数组(混合$needle,数组$haystack[,bool$strict=
FALSE])使用松散比较搜索haystack中的针,除非 严格规定

一些人提到了
PHP\u INT\u MAX
。这将是我的系统上的
2147483647
。我不太确定这是否是问题所在,因为:

如果PHP遇到超出整数类型边界的数字,则 将被解释为浮动。还有,一个操作 结果将返回超出整数类型边界的数字 而是一个浮子

但是应该足够高


无论这个问题的“真正”根源是什么,只要在数组中使用strict for
就可以解决这个问题。

如果这是您的问题,并且您确实想在数组中进行比较/查找,那么有一个技巧

$lead = "a418176000000069007";
$diff = array("a418176000000069003","a418176000000057001");

if (in_array($lead,$diff))
    echo "Found";
else
    echo "Not found";

i、 不知何故,你必须在每个数字前加上一个特别的字符。它们将作为字符串进行比较,从而给出正确的结果。

事实是。你能用非数字复制它吗?@ThiefMaster太容易攻击了。下次请提供一个答案而不是咆哮:)@ClementHerreman:已经有好的答案了;)下面是一个相关的bug条目:。这是一个相当幽默的读物。哦……天哪……我几乎尝试了每种组合……无论如何,有什么解决办法吗??问题是,为什么它会将其转换为
int
?@Amit将
$strict
设置为
true
在数组中($lead,$diff,true)
据我所知==不将字符串转换为数字。如果类型不同,它会转换类型,但是比较两个字符串IMHO不会t@gavriel:不幸的是,那不是真的;如果字符串看起来像一个数字,它将转换为一。添加一些零,这样即使在您的64位安装中,数字比较也会失去精度,并且很容易演示:
php-r'echo(“41817600000000000069003”==“41817600000000000057001”),“\n”返回1.so在您看来$lead=“001”$arr=数组(“1”、“01”);_阵列中的回波($lead,$arr);应该返回true吗?@tomerw:问题已经回答了,所以我们不应该在评论中偏离正题;如果你愿意,可以随意开始聊天。但我要说的是:(1)您的代码实际上返回1(=true),并且(2)我早就放弃了PHP的行为,因为它与我认为的“应该”做的事情有任何相似之处
     if(in_array($lead,$diff,true)) //use type too
       echo "Found";
     else
       echo "Not found";
?>