Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

arrays

php

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";
like image 786
www.amitpatil.me Avatar asked May 02 '12 06:05

www.amitpatil.me


2 Answers

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.

like image 128
Mark Reed Avatar answered Oct 20 '22 00:10

Mark Reed


Note: This was a bug in PHP old versions and is corrected in PHP 5.4 and newer versions.

It is because of the limitations of the number storage in PHP

The real problem here is because of the PHP_INT_MAX - the value exceeded in our case.

Try to echo/print_r $lead and $diff without using the quotes. It will result

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

so, in this case, the in_array result is true!

so use strict comparison in in_array() by setting third argument in in_array() as true

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

Try this. It will work.

like image 56
arun Avatar answered Oct 20 '22 00:10

arun