【问题标题】:Why are large array indices not stored properly?为什么大数组索引没有正确存储?
【发布时间】:2012-04-29 01:38:11
【问题描述】:

我正在处理涉及非常大的主键(12 位)的数据。当我尝试将数据以id => value 的形式放入数组时,索引未正确分配。

$test = array(190337172011 => 'Apple');
print_r($test);

结果:

Array ( [1358610987] => Apple ) 

有时它甚至会产生负数。为什么会这样?它是一个错误吗?

我在 IIS 上运行 PHP 5.3.10。

【问题讨论】:

  • 这是 32 位还是 64 位版本的 PHP?如果它是 32 位平台,那么存储这些密钥的空间将用完:php.net/manual/en/language.types.integer.php
  • this question,好像是内存问题。
  • @bfavaretto: 如果内存太大,脚本会被终止;不会返回错误的结果。
  • 感谢@BillyONEal,它是 PHP 的 32 位版本,但我还是有点困惑。如果我反转键和值:Array ( [Apple] => 190337172011 ) 工作正常。它不是仍然以整数形式存储吗?
  • @Billy 我的意思是 PHP 可用的内存量(通过 memory_limit php.ini 设置)决定了数组键可以拥有的最大值——根据我链接的问题的接受答案到。

标签: php windows


【解决方案1】:

整数的大小取决于平台,尽管通常值约为 20 亿的最大值(即 32 位有符号)。 64 位平台的最大值通常约为 9E18。 PHP 不支持无符号整数。自 PHP 4.4.0 和 PHP 5.0.5 起,可以使用常量 PHP_INT_SIZE 确定整数大小,使用常量 PHP_INT_MAX 确定最大值。

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

【讨论】:

    【解决方案2】:

    您在可能是 32 位 Windows 操作系统(例如 Windows XP)上使用 32 位 PHP 版本。

    对于数值数组索引,PHP 使用整数变量类型来存储键。这些是有限的。如果您选择的值大于限制,则此限制将变得可见,这将根据 PHP 版本和操作系统触发最大值或周转。

    190337172011 的值对于您的系统上的整数类型来说太大了,这就是为什么您通过往返得到一个上限,结果为1358610987。往返意味着,在可能的最大正数之后,下一个数字是可能的最小数,即可以表示的“最大”负数。这就是为什么你也会得到负数。

    您可以通过将值存储为需要一些前缀的字符串键来解决此问题:

    $test = array('ID' . 190337172011 => 'Apple');
    print_r($test);
    

    这通常足以使您的代码更具可移植性。您可以选择任意字符串前缀,ID 只是示例,但您至少需要一个非数字字符。

    【讨论】:

    • 感谢您的解释。我注意到它也可以在构建数组时简单地将 id 转换为字符串。
    • 转换为字符串并不总是有效 - 可能它确实适用于那些太大的数字(这是一个漂亮的技巧)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    相关资源
    最近更新 更多