PHP数组的问题,其中键是大整数 [英] Issue with PHP array where keys are large integers

查看:65
本文介绍了PHP数组的问题,其中键是大整数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我打算在这里执行的操作基本上是从 $ stats 开始,并获得一个包含四个数组的数组 $ counts ,其中每个数组都是一对:键是一个以毫秒为单位的时间戳,而值是计数.我在Windows 7 x64上使用PHP版本5.3.14.

What i'm tring to do here is basically start from $stats and get an array $counts containing four arrays, where each array is a pair: key is a timestamp in milliseconds while values are counts. Im using PHP Version 5.3.14 on Windows 7 x64.

问题是:为什么我要得到底片数组键值,如何避免这种情况?请参见下面的 var_dump():

Question is: why i'm getting negatives array keys values and how can avoid this? See var_dump() below:

$stats = array();
$stats[] = array(
    'subtype' => 'small_text_message_user',
    'count'   => '6',
    'date'    => '2012-06-03'
);

$stats[] = array(
    'subtype' => 'small_text_message_auto',
    'count'   => '3',
    'date'    => '2012-07-03',
);

$stats = array(
    'subtype' => 'newsletter_auto',
    'count' => '11',
    'date' => '2012-07-16',
);

$counts = array();
$counts['small_text_message_user'] = array();
$counts['small_text_message_auto'] = array();
$counts['newsletter_user']         = array();
$counts['newsletter_auto']         = array();

foreach($data as $stat) :
    $millisecs = 1000 * strtotime($stat['date']);
    $count     = intval($stat['count']);
    $counts[$stat['subtype']][$millisecs] = $count;
    var_dump($millisecs, $count);
endforeach;

var_dump($counts);

结果是错误的:

float 1338674400000

int 6

float 1341266400000

int 3

float 1342389600000

int 11

array (size=4)
  'small_text_message_user' => 
    array (size=1)
      -1355396352 => int 6
  'small_text_message_auto' => 
    array (size=1)
      1236603648 => int 3
  'newsletter_user' => 
    array (size=0)
      empty
  'newsletter_auto' => 
    array (size=1)
      -1935163648 => int 11

一个示例(实际上有效)是一小段代码,其中我生成了一个虚拟"对象.数组:

An example (which works, actually) is a short piece of code where i'm generating a "dummy" array:

public function createTimestampRangeFromDates(\DateTime $from,
    \DateTime $to = null)
{
    $start = strtotime($from->format('Y-m-d 00:00:00'));
    $limit = strtotime(sprintf('%s 00:00:00', $to ? $to->format('Y-m-d')
        : date('Y-m-d') . ' 00:00:00'));

    return range($start, $limit, 86400);
}

// Test
$start = new \DateTime('2012-06-27');
$end   = new \DateTime('2012-07-07'); // 10 days

$timestamps = createTimestampRangeFromDates($start, $end);
$millisecs  = array_combine($timestamps, array_fill(0, count($timestamps), 0));

var_dump($millisecs);

工作正常,并且我得到大整数作为键:

array (size=11)
  '1340748000000' => int 0
  '1340834400000' => int 0
  '1340920800000' => int 0
  '1341007200000' => int 0
  '1341093600000' => int 0
  '1341180000000' => int 0
  '1341266400000' => int 0
  '1341352800000' => int 0
  '1341439200000' => int 0
  '1341525600000' => int 0
  '1341612000000' => int 0

哦,如果这很重要,那么这段代码的目的就是要做类似的事情:

Oh, if this matters, purpose of this code is to do something like:

$values = array_merge($millisecs, $counts['newsletter_auto']);

那是用真实值覆盖虚拟数组.

That is overriding the dummy array with real values.

$result1 = array();
$result2 = array();
$test    = array('2012-06-03', '2012-07-03', '2012-07-16');

foreach($test as $date) :
    $result1[1000 * strtotime($date)] = 0;
    $result2[] = 1000 * strtotime($date);
endforeach;

var_dump($result1); // Not working
var_dump($result2); // Works

结果显示 $ result1 的否定键.问题仅在于键,而不是值(因为将值转换为 float ):

Result shows negative keys for $result1. Issue is only with keys, not for values (as value is converted to float):

array (size=3)
  -1355396352 => int 0
  1236603648 => int 0
  -1935163648 => int 0

array (size=3)
  0 => float 1338674400000
  1 => float 1341266400000
  2 => float 1342389600000

推荐答案

PHP将数字(因此,浮点数或整数)数组索引转换为整数:

PHP converts nummeric (so, float or integer) array indexes to integer:

ckruse@lin ~ $ php -r 'var_dump(array(1.2 => "a"));'
array(1) {
  [1]=>
  string(1) "a"
}

因此,如果您有非常大的数组索引,则在计算时会被PHP转换为float,然后在用作索引时返回为整数.这意味着您将获得一个带有大索引的整数溢出.

So if you have a very large array index, it will get converted to float by PHP when calculated and then back to integer when used as an index. This means that you get an integer overflow with to large indexes.

一种解决方案可以是使用字符串索引:

A solution can be to use string indexes:

ckruse@lin ~ $ php -r 'var_dump(array(((string)1.2) => "a"));'
array(1) {
  ["1.2"]=>
  string(1) "a"
}

http://php.net/manual/zh/上的手册language.types.array.php 说:

浮点数也转换为整数,这意味着小数部分将被截断.例如.密钥8.7实际上将存储在8下.

Floats are also cast to integers, which means that the fractional part will be truncated. E.g. the key 8.7 will actually be stored under 8.

这篇关于PHP数组的问题,其中键是大整数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆