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


Why does in_array() wrongly return true with these (large numeric) strings?

我不明白这段代码有什么问题。它返回"已找到",它不应该返回。

$lead = "418176000000069007";
$diff = array("418176000000069003","418176000000057001");
if (in_array($lead,$diff))
    echo "Found";
else
    echo "Not found";

注意:此行为在 PHP 5.4 中已更改。

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

一个解决方案是通过向in_array传递一个额外的Boolean参数来打开strict比较(===(:

  $lead = "418176000000069007";
  $diff = array("418176000000069003", "418176000000057001");
  if ( in_array($lead, $diff, true) ) 
    echo "Found";
  else
    echo "Not found";

然后将字符串作为没有数字强制的字符串进行比较。 但是,这意味着您确实会丢失"01234"和"1234"等字符串的默认等效性。

此行为被报告为错误,并在 PHP 5.4 中修复。 与==相比,数字字符串仍会转换为数字,但前提是字符串的值适合平台的数字类型。

注意:这是PHP旧版本中的错误,在PHP 5.4和新版本中得到了纠正。

这是因为PHP中号码存储的限制

这里真正的问题是因为PHP_INT_MAX - 在我们的例子中超过了值。

尝试在不使用引号的情况下echo/print_r $lead$diff。它将导致

$lead ---> 418176000000070000  
$diff ---> Array ( [0] => 418176000000070000 [1] => 418176000000060000 )

所以,在这种情况下,in_array结果是真的!

因此,通过在in_array()中使用strict比较,将in_array()中的第三个参数设置为true

     if(in_array($lead,$diff,true)) //use type too
       echo "Found";
     else
       echo "Not found";
?>

试试这个。它会起作用。

这是因为 PHP 中的一个缺陷。 418176000000069007被修改为2147483647(PHP 的整数限制(。这就是为什么你会得到Found.

试试in_array($lead, $diff, true)

If the third parameter strict is set to TRUE then the in_array() 
function will also check the types of the needle in the haystack. 

值超过 PHP_INT_MAX 。试着做if(in_array($lead,$diff,true))

in_array应该严格。

$lead = "418176000000069007";
  $diff = array("418176000000069003","418176000000057001");
  if(in_array($lead,$diff,true)) 
    echo "Found";
  else
    echo "Not found";

此问题是由于您的数字超出了定义的整数限制

注意:最大值取决于系统。 32 位系统的最大有符号整数范围为 -21474836482147483647 。因此,例如在这样的系统上,intval('1000000000000')将返回2147483647.64 位系统的最大有符号整数值为 9223372036854775807

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

$lead = "418176000000069007";
$diff = array("418176000000069003","418176000000057001");
if(in_array($lead, $diff, true)) {
    echo "Found";
} else {
    echo "Not found";
}

如果第三个参数 strict 设置为 TRUE,则 in_array() 函数还将检查大海捞针的类型,并且因为限制超出了最大整数值。

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

if (in_array($lead,$diff,true))

来自 PHP 手册: 字符串转换为数字:

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

如果字符串包含任何 字符"."、"e"或"E"。否则,它将被评估为 整数。

正如其他人提到的,您应该对in_array使用严格:

bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] ( 使用松散比较在大海捞针中搜索针,除非 严格设置。

有人提到PHP_INT_MAX.这将在我的系统上2147483647。我不太确定这是否是手册中所说的问题:

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

但是浮点精度应该足够高...

无论此问题的"真正"来源是什么,只需使用严格的in_array来解决此问题。

如果这是你的问题,并且你真的想在数组中比较/查找,那么有一个技巧

$lead = "a418176000000069007";
$diff = array("a418176000000069003","a418176000000057001");
if (in_array($lead,$diff))
    echo "Found";
else
    echo "Not found";

即,您必须以某种方式在每个数字前面附加一个字符。它们在比较中将表现为字符串,因此给出正确的结果。