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

时间:2012-05-02 06:27:14

标签: php arrays

我没有弄清楚这段代码有什么问题。它正在返回“发现”,它不应该。

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

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

9 个答案:

答案 0 :(得分:139)

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

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

解决方案是通过将额外的strict参数传递给===来启用Boolean比较(in_array):

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

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

然后将字符串作为字符串进行比较,不进行数字强制。但是,这意味着您确实失去了字符串的默认等效项,如“01234”和“1234”。

此行为was reported as a bug并在PHP 5.4中修复。与==相比,数字字符串仍会转换为数字,但前提是字符串的值适合平台的数字类型。

答案 1 :(得分:56)

由于PHP中数字存储的限制,这是一个错误,并在较新版本的PHP中得到纠正和解决。

值超过PHP_INT_MAX

尝试echo / print_r $lead$diff而不使用引号。它将导致

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

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

所以在strict中使用in_array()进行比较,方法是将in_array()中的第三个参数设置为true     

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

试试这个。它会起作用。

答案 2 :(得分:16)

这是因为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. 

答案 3 :(得分:6)

值超过PHP_INT_MAX。请尝试改为if(in_array($lead,$diff,true))

答案 4 :(得分:5)

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

答案 5 :(得分:3)

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

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

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

答案 6 :(得分:2)

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

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

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

答案 7 :(得分:2)

来自PHP Manual: String conversion to numbers

  

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

     

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

正如其他人所提到的,你应该对in_array使用strict:

  

bool in_array ( mixed $needle , array $haystack [, bool $strict =   FALSE])使用松散比较搜索干草堆的针,除非   严格确定。

有人提到PHP_INT_MAX。这将是我系统上的2147483647。我不太确定这是manual states

这个问题
  

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

但是floating point precision应该足够高......

无论这个问题的“真正”来源是什么,只需使用strict in_array来解决这个问题。

答案 8 :(得分:2)

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

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

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

即。不知何故,你必须为每个数字添加一个特定的字符。它们将在比较中表现为字符串,从而得出正确的结果。