请查看下面的代码,它在不同的机器上给出不同的结果:
$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"));
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,我们本地服务器上的所有4个案例的结果都是真的,而在第一个案例的生产服务器上,它给出了错误的结果
谁能帮我理解到底发生了什么?从配置的角度来看,我是否错过了?
它非常简单....让我猜你的开发系统是windows,你的生产服务器是linux?
你有整数溢出问题,因为大多数人喜欢你的Windows版本的PHP是32位,Linux是64位
那么会发生什么:
所以关键28000000000000003是有效integer的一个64bit,但一个String一个上32bits系统
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));
Run Code Online (Sandbox Code Playgroud)
bool(false) <----------------------- false instead of true
bool(true)
bool(true)
bool(true)
Run Code Online (Sandbox Code Playgroud)
这个问题与例子无关,in_array而是一个array_keys例子
echo "<pre>";
$data = array("28000000000000003" => 'ABC',"28000000000000001" => 'PQR');
$keys = array("28000000000000003","28000000000000001");
$keysDerived = array_keys($data);
var_dump($keys,$keysDerived);
Run Code Online (Sandbox Code Playgroud)
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)
}
Run Code Online (Sandbox Code Playgroud)
这意味着它们不是同一类型......
in_array bool in_array(混合$ needle,数组$ haystack [,bool $ strict = FALSE])
如果第三个参数strict设置为TRUE,那么in_array()函数也将检查haystack中针的类型.
foreach ( $keys as $key ) {
echo gettype($key) . "\n";
}
foreach ( $keysDerived as $key ) {
echo gettype($key) . "\n";
}
Run Code Online (Sandbox Code Playgroud)
输出 64位
string
string
integer
integer
Run Code Online (Sandbox Code Playgroud)
输出32位
string
string
string
string
Run Code Online (Sandbox Code Playgroud)
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));
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
使用的功能
function array_keys_string(array $input) {
$list = array();
foreach ( $input as $k => $v ) {
$list[] = (string)$k;
}
return $list;
}
Run Code Online (Sandbox Code Playgroud)
小智 6
您的本地服务器是32位,生产服务器是64位.
PHP文档说,在定义数组文字时,将转换键:
包含有效整数的字符串将强制转换为整数类型.例如,键"8"实际上将存储在8下.
所以,如果您尝试以下代码:
var_export(array("5" => "test"));
Run Code Online (Sandbox Code Playgroud)
您将看到结果是带有数字键的数组5,而不是字符串键"5".
在您的情况下,您有大型数字字符串作为键.在32位计算机上,数字28000000000000003超过了最大可能的整数值(PHP_INT_MAX),因此数组键将保持字符串,这就是本地服务器上发生的情况.另一方面,在64位计算机上,最大整数更大,并且"28000000000000003"被强制转换integer,这就是生产服务器上发生的情况.
因此,在64位生产服务器上运行时,array_keys($data)返回整数数组.在第一个测试用例中,您尝试使用严格比较在其中找到一个字符串FALSE.