Why does in_array() wrongly return true with these

2020-02-16 11:52发布

I am not getting what is wrong with this code. It's returning "Found", which it should not.

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

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

标签: php arrays
9条回答
啃猪蹄的小仙女
2楼-- · 2020-02-16 12:42

Note: this behavior was changed in PHP 5.4.

By default, in_array uses loose comparison (==), which means numeric strings are converted to numbers and compared as numbers. Before PHP 5.4, if you didn't have enough precision in your platform's floating-point type, the difference was lost and you got the wrong answer.

A solution is to turn on strict comparison (===) by passing an extra Boolean parameter to in_array:

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

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

Then the strings are compared as strings with no numeric coercion. However, this means you do lose the default equivalence of strings like "01234" and "1234".

This behavior was reported as a bug and fixed in PHP 5.4. Numeric strings are still converted to numbers when compared with ==, but only if the value of the string fits in the platform's numeric type.

查看更多
该账号已被封号
3楼-- · 2020-02-16 12:44

From PHP Manual: String conversion to numbers:

When a string is evaluated in a numeric context, the resulting value and type are determined as follows.

The string will be evaluated as a float if it contains any of the characters '.', 'e', or 'E'. Otherwise, it will be evaluated as an integer.

As some others mentioned, you should use strict for in_array:

bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] ) Searches haystack for needle using loose comparison unless strict is set.

Some mentioned PHP_INT_MAX. This would be 2147483647 on my system. I'm not quite sure if this is the problem as the manual states:

If PHP encounters a number beyond the bounds of the integer type, it will be interpreted as a float instead. Also, an operation which results in a number beyond the bounds of the integer type will return a float instead.

But floating point precision should be high enough...

Whatever might be the "real" source of this problem, simply use strict for in_array to fix this problem.

查看更多
爱情/是我丢掉的垃圾
4楼-- · 2020-02-16 12:44

If that is your problem and you really want to compare/find in array then there is a trick

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

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

i.e. somehow you have to prepend a perticular character to every number. They will behave as strings in comparison and hence give correct result.

查看更多
登录 后发表回答