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

I do not understand what is wrong with this code. It returns "Found," which does not follow.

$lead = "418176000000069007"; $diff = array("418176000000069003","418176000000057001"); if (in_array($lead,$diff)) echo "Found"; else echo "Not found"; 
+43
arrays php
May 2, '12 at 6:27
source share
9 answers

It was because of the limitations of storing the number in PHP that was a mistake and fixed and resolved in newer versions of PHP .

Values ​​exceed PHP_INT_MAX .

Try echo / print_r $lead and $diff without using quotes. This will cause

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

therefore, in this case, the result of in_array correct!

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

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

Try it. He will work.

+55
May 2 '12 at 6:32
source share
— -

Note. this behavior has been changed in PHP 5.4.

By default, in_array uses free comparison ( == ), which means that numeric strings are converted to numbers and compared as numbers. Prior to PHP 5.4, if you did not have sufficient accuracy in your platform floating form, the difference was lost and you received the wrong answer.

The solution is to enable 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 without numerical coercion. However, this means that you are losing the standard equivalence of strings such as "01234" and "1234".

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

+138
May 02 '12 at 6:34
source share

This is due to one defect in PHP. 418176000000069007 changed to 2147483647 (PHP integer limit). That is why you get Found .

try 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. 
+16
May 2 '12 at 6:31
source share

Values ​​exceed PHP_INT_MAX . Instead, try if(in_array($lead,$diff,true)) .

+6
May 2 '12 at 6:33
source share

in_array must be strictly defined.

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

This problem is because your numbers are exceeded from the given integer limit.

Note: The maximum value is system dependent. 32-bit systems have a maximum signed integer range from -2147483648 to 2147483647 . So, for example, in such a system, intval('1000000000000') will return 2147483647 . The maximum signed integer value for 64-bit systems is 9223372036854775807 .

+4
May 02 '12 at 6:38
source share

Try using parentheses and use strict mode:

 $lead = "418176000000069007"; $diff = array("418176000000069003","418176000000057001"); if(in_array($lead, $diff, true)) { echo "Found"; } else { echo "Not found"; } 
+3
May 02 '12 at 6:35
source share

If the third strict parameter is set to TRUE, the in_array() function in_array() also check the needle types in the haystack and because the limit exceeds the maximum integer value.

So, if PHP encounters a number outside the integer type, it will be interpreted as a float. In addition, an operation that results in a number outside the integer type returns a float instead. Check out the PHP manuals.

 if (in_array($lead,$diff,true)) 
+2
May 02 '12 at 11:47 a.m.
source share

From the PHP manual: converting strings to numbers :

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

A 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 already mentioned, you should use strict for in_array :

bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE]) Searches for a haystack for a needle using a free comparison if Strictly specified.

Some mentioned PHP_INT_MAX . This will be 2147483647 on my system. I am not quite sure if this is a problem, as it indicates manually :

If PHP encounters a number outside the integer type, it will instead be interpreted as a float. In addition, an operation that causes a number outside the integer type to return instead is a float.

But floating point accuracy should be high enough ...

Whatever the "real" source of this problem is, just use strict for in_array to fix this problem.

+2
May 09 '12 at 5:16 a.m.
source share

If this is your problem and you really want to compare / find in an 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. anyway, you need to give each character its own character. They will behave like strings in comparison and therefore give the correct result.

+2
May 24 '12 at 4:25
source share



All Articles