PHP数字数组键的限制是多少


What is the PHP numeric array key limit

我遇到了一个数组更改我身上键值的问题。在下面的例子中,它一开始还可以,但在某个时候php会将我的字符串变成一个整数,并在将其作为键插入另一个数组时更改该整数。

Code
-----------------
$fund = '01';
$division = '1';
$gl_transactions[$fund] = array();
$glint = array($division=>array('gl_cash_account'=>'1800001040000000')); 
print chr(10).'1:'.chr(10); 
print_r($glint); 
$gl = $glint[$division]['gl_cash_account']; 
print chr(10).'2:'.chr(10); 
print $gl;
$gl_transactions[$fund][$gl]['description'] = 'MTS DISBURSEMENTS'; 
print chr(10).'3:'.chr(10);
print_r($gl_transactions);
Expected output 
--------------- 
1:Array([1] => Array([gl_cash_account] => 1800001040000000 ))
2:1800001040000000  
3:Array([01] => Array([1800001040000000] => Array([description] => MTS DISBURSEMENTS))) 
Actual output 
--------------- 
1:Array([1] => Array([gl_cash_account] => 1800001040000000 ))
2:1800001040000000  
3:Array([01] => Array([1721082880] => Array([description] => MTS DISBURSEMENTS))) 

请注意,指数从1800010400000变为1721082880

产科

这些大数字是G/L帐号,不能更改为较小的数字。我们的产品中有数以万计的代码,超过一百万行的代码,我们无法仔细查看其中的每一点,找出可能存在的问题并进行重写。这只是我们在许多地方所做的事情的一个通用示例,即使用数据库中的数据构建多维数组。在插入数组时,我可以简单地将变量强制转换为字符串来修复上面的示例,但回填1M行以上的代码不是一个可行的选择。

在我的开发机器上,我运行php5.3MSSQL、Windows和IIS。我在上面的代码中没有得到这个错误,但当我简单地将变量设置为整数,然后将其作为键插入数组时,我确实得到了这个错误。即$gl=1800001040000000$ar[$gl]=1;print_r($ar);现在,我们的软件中没有将变量强制转换为整数,但在第一个示例中,php在构建最后一个数组时,在一些客户端系统上运行时,会自行转换变量。

所以我的问题是:

  1. 数字数组键的确切限制是多少
  2. 有没有办法增加这一点
  3. 在5.2之后的php版本中,这一问题是否得到了修复或增加

其他注意事项

我们的软件可以与几个数据库、几个浏览器、windows和linux、apache和IIS配合使用。我们有数百名客户使用该软件,他们都有自己独特的设置。我们的大多数客户目前都使用php5.2,由于我们的软件中使用了不推荐使用的功能,目前无法升级它们。

我的猜测是,您受到整数最大值的限制,因为PHP会自动将有效整数值用作整数数组键的字符串强制转换为整数。PHP手册指出,整数的限制会因系统而异,但最大的问题是在确定上限时,32位系统与64位系统的区别。

http://php.net/manual/en/language.types.integer.php

系统上的最大整数值可以从PHP_INT_MAX常量中读取。

我看到这里没有公认的答案,当然OP已经从这个问题开始了。我在这样的阵列中丢失了钥匙(来自Snowmed CT):

static function getNemsisProcedures() {
  $nemsis[445828009] = 'Assessment  Advanced Spinal Assessment (i.e.,  spinal clearance)';
  $nemsis[425058005] = 'Assessment  Orthostatic Vital Signs';
  // etc....
  $nemsis[89666000] = 'Cardiac  CPR, Manual';
  $nemsis[450661000124102] = 'Cardiac  Defibrillation, AED'; // TAKE NOTE
  $nemsis[426220008] = 'Cardiac  Defibrillation, Manual';
  // a lot more etc...

问题是"心脏除颤,AED",因为整数450661000124102的密钥大于PHP_MAX_INT(在我的情况下为2147483647)。

解决方案:在适用的情况下使用字符串键。

在我的情况下,我不要求密钥是整数,为了防止在git中进行大规模提交,我只需引用受影响的Snowmed CT Procedure值的密钥类型string

static function getNemsisProcedures() {
  $nemsis[445828009] = 'Assessment  Advanced Spinal Assessment (i.e.,  spinal clearance)';
  $nemsis[425058005] = 'Assessment  Orthostatic Vital Signs';
  // etc....
  $nemsis[89666000] = 'Cardiac  CPR, Manual';
  // KEY IS GREATER THAN PHP_MAX_INT - USE QUOTES:
  $nemsis['450661000124102'] = 'Cardiac  Defibrillation, AED';
  $nemsis[426220008] = 'Cardiac  Defibrillation, Manual';
  // a lot more etc...