Please review following piece of code, it is giving different results on different machines:
$data = array(
"28000000000000003" => 'ABC',
"28000000000000001" => 'PQR'
);
echo "1.".in_array("28000000000000003",array_keys($data),true);
echo "2.".in_array("28000000000000003",array_keys($data));
echo "3.".in_array("28000000000000003",array("28000000000000003","28000000000000001"),true);
echo "4.".in_array("28000000000000003",array("28000000000000003","28000000000000001"));
As expected, results true for all 4 cases on our local server, while on production server in 1st case it is giving false result and true in rest of three
Can anybody help me to understand what exactly happening? Do I missed from configuration point of view?
Its very easy .... let me guess your Development system is windows and your production server is linux ?
You are having Integer overflow Issues because most likey your windows version of PHP is 32bit and linux is 64bit
See Condition for array key conversion
So what happens is that :
So the key 28000000000000003
is a valid integer
on a 64bit
but a String
on a 32bits
system
I was able to replicate your issue
echo "<pre>";
$data = array("28000000000000003" => 'ABC',"28000000000000001" => 'PQR');
$keys = array("28000000000000003","28000000000000001");
$keysDerived = array_keys($data);
var_dump(in_array("28000000000000003", $keysDerived, true));
var_dump(in_array("28000000000000003", $keysDerived));
var_dump(in_array("28000000000000003", $keys, true));
var_dump(in_array("28000000000000003", $keys));
Output
bool(false) <----------------------- false instead of true
bool(true)
bool(true)
bool(true)
This issues has nothing to do with in_array
but rather array_keys
example
Sample Code
echo "<pre>";
$data = array("28000000000000003" => 'ABC',"28000000000000001" => 'PQR');
$keys = array("28000000000000003","28000000000000001");
$keysDerived = array_keys($data);
var_dump($keys,$keysDerived);
Output
array(2) {
[0]=>
string(17) "28000000000000003" <------- Keys are String
[1]=>
string(17) "28000000000000001"
}
array(2) {
[0]=>
int(28000000000000003) <------- They are converted to int on 64bits
[1]=>
int(28000000000000001)
}
See Online Demo
This means that they are not the same type ...
in_array bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )
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.
If you run this code
foreach ( $keys as $key ) {
echo gettype($key) . "\n";
}
foreach ( $keysDerived as $key ) {
echo gettype($key) . "\n";
}
Output 64Bits
string
string
integer
integer
Output 32Bits
string
string
string
string
Simple Workaround
echo "<pre>";
$data = array("28000000000000003" => 'ABC',"28000000000000001" => 'PQR');
$keys = array("28000000000000003","28000000000000001");
$keysDerived = array_keys_string($data);
var_dump($keys,$keysDerived);
var_dump(in_array("28000000000000003", $keysDerived, true));
var_dump(in_array("28000000000000003", $keysDerived));
var_dump(in_array("28000000000000003", $keys, true));
var_dump(in_array("28000000000000003", $keys));
Output
array(2) {
[0]=>
string(17) "28000000000000003"
[1]=>
string(17) "28000000000000001"
}
array(2) {
[0]=>
string(17) "28000000000000003"
[1]=>
string(17) "28000000000000001"
}
bool(true)
bool(true)
bool(true)
bool(true)
See Original Code See Modified Code
Function Used
function array_keys_string(array $input) {
$list = array();
foreach ( $input as $k => $v ) {
$list[] = (string)$k;
}
return $list;
}
Your local server is 32-bit and your production server is 64-bit.
PHP documentation says that when defining array literals, keys will be cast:
Strings containing valid integers will be cast to the integer type. E.g. the key "8" will actually be stored under 8.
So, if you try the following piece of code:
var_export(array("5" => "test"));
You will see the result is an array with numerical key 5
, not string key "5"
.
In your case, you have large numerical strings as keys. On a 32-bit machine, number 28000000000000003
exceeds the maximum possible integer value (PHP_INT_MAX
), so the array key will stay string, and that is what happens on your local server. On a 64-bit machine, on the other hand, maximum integer is way greater, and "28000000000000003"
is cast to integer
, and that is what happens on your production server.
So, when run on the 64-bit production server, array_keys($data)
returns array of integers. When in your first test case you try to find a string in it using strict comparison, you get FALSE
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With