请查看下面的代码,它会在不同的机器上显示不同的结果:
$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"));
正如预期的那样,我们本地服务器上的所有4个案例的结果都是真的,而在第一个案例中的生产服务器上,它给出了错误的结果,而在其余的三个案例中是真的
有人能帮助我理解究竟发生了什么吗?从配置的角度来看,我是否错过了?
答案 0 :(得分:9)
非常简单....让我猜你的开发系统是windows,你的生产服务器是linux?
你有整数溢出问题,因为大多数人喜欢你的Windows版本的PHP是32位而linux是64位
See Condition for array key conversion
所以会发生什么:
因此,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));
I was able to replicate your issue
bool(false) <----------------------- false instead of true
bool(true)
bool(true)
bool(true)
in_array
此问题与array_keys
无关,而是与echo "<pre>";
$data = array("28000000000000003" => 'ABC',"28000000000000001" => 'PQR');
$keys = array("28000000000000003","28000000000000001");
$keysDerived = array_keys($data);
var_dump($keys,$keysDerived);
示例
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)
}
foreach ( $keys as $key ) {
echo gettype($key) . "\n";
}
foreach ( $keysDerived as $key ) {
echo gettype($key) . "\n";
}
这意味着它们的类型不同......
in_array bool in_array(混合$ needle,数组$ haystack [,bool $ strict = FALSE])
如果第三个参数严格设置为 TRUE ,则in_array()函数还会检查大海捞针中的类型
string
string
integer
integer
Output 64位
string
string
string
string
输出32位
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));
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)
function array_keys_string(array $input) {
$list = array();
foreach ( $input as $k => $v ) {
$list[] = (string)$k;
}
return $list;
}
See Original Code See Modified Code
使用的功能
{{1}}
答案 1 :(得分:6)
您的本地服务器是32位,生产服务器是64位。
PHP documentation表示在定义数组文字时,键将被转换为:
包含有效整数的字符串将强制转换为整数类型。例如。键“8”实际上将存储在8下。
所以,如果您尝试以下代码:
var_export(array("5" => "test"));
您会看到结果是一个数字键5
的数组,而不是字符串键"5"
。
在您的情况下,您有大型数字字符串作为键。在32位计算机上,数字28000000000000003
超过了最大可能的整数值(PHP_INT_MAX
),因此数组键将保持字符串,这就是本地服务器上发生的情况。另一方面,在64位计算机上,最大整数更大,"28000000000000003"
转换为integer
,这就是生产服务器上发生的情况。
因此,当在64位生产服务器上运行时,array_keys($data)
将返回整数数组。在第一个测试用例中,您尝试使用严格比较在其中查找字符串,得到FALSE
。
答案 2 :(得分:2)
您可以尝试使用array_key_exists()
。关联数组键的长度有一些限制。请参阅链接了解详情帮助PHP associative array's keys (indexes) limitations?
您可以增加密钥记忆限制。使用ini_set('memory_limit', '1024M');
答案 3 :(得分:2)
问题:如果你有长整数的键,例如'329462291595',它们在64位系统上将被视为本身,但它将是类型32位系统上的字符串。
因此函数array_keys($data)
将在64位系统中返回int,在32位系统中返回字符串
解决方案:将所有array_keys($data)
转换为字符串。
然后in_array("28000000000000003",array_keys($data),true);
使用第三个参数true
(严格检查)
function array_keys_string($arr){
$arr_keys = array_keys($arr);
$res_arry = array();
foreach($arr_keys as $val){
$res_arry[] = (string)$val;
}
return $res_arry;
}
echo "1.".in_array("28000000000000003",array_keys_string($data),true);
这将在两个服务器中提供相同的结果。
请参阅以下链接:
参考:http://www.php.net/manual/en/function.array-keys.php#105578
来自php.net:http://www.php.net/manual/en/function.in-array.php
<?php
$a = array('1.10', 12.4, 1.13);
if (in_array('12.4', $a, true)) {
echo "'12.4' found with strict check\n";
}
if (in_array(1.13, $a, true)) {
echo "1.13 found with strict check\n";
}
?>
以上示例将输出:1.13严格检查