数组中的年份作为键,然后填充当年的许多日期

Years in Array to key, then populate with many dates in that year

所以我从数据库中提取了一个这样的数组:

Array
(
 [0] => stdClass Object
    (
        [created] => 2012-08-22 00:00:00
    )

 [1] => stdClass Object
    (
        [created] => 2012-08-23 00:00:00
    )

 [2] => stdClass Object
    (
        [created] => 2012-08-24 00:00:00
    )

 [3] => stdClass Object
    (
        [created] => 2012-08-24 00:00:00
    )

 [4] => stdClass Object
    (
        [created] => 2012-08-24 00:00:00
    )
...

目前有几千条记录...

据此,我正在尝试构建如下所示的数组

Array (
  [2016] array (
      [01] array(), //Jan
      [02] array( //Feb
           [01] = 8  // number of occurances
           [02] = 6  // number of occurances
           .... etc
          ), 
      ... etc
      )
  [2015] array(
      [01] array(), //Jan
      [02] array(), //Feb
      ... etc
  )
  ... etc...
)

我不完全确定如何完全动态地执行此操作(IE:不对年份键进行硬编码)。

我愿意接受其他从数据库中提取信息的方法,也可以使用 MySQL 而不是 PHP/foreach 在数千条记录上循环。

这并不重要,我在 PHP 5.6 和 MySQL 5.6.28 上使用 Codeigniter 3,所以我标记了它们。

编辑:如果你没猜到,我正在创建图表...

编辑

根据@WEBjuju 的要求,下面是我的工作方法。在此过程中,我发现我还需要全年和每月的总计。我还没有测试过它的速度。

    // much of this function provided by Whosebug user @Webjuju 
    // http://whosebug.com/posts/41067942
    $all_dates = $this->db->select('created')->order_by('created', 'ASC')->get('jobs')->result(); // produces original array above

    foreach ($all_dates as $obj) 
    {
        $stt = strtotime($obj->created);

        list($year, $month, $day) = explode('-', date('Y-m-d', $stt));

        @$target[$year]['total']++;
        @$target[$year][$month]['total']++;

        // increment the string for each occurrence of that day/month/year
        @$target[$year][$month]['counts'][$day]++;

    }

    $minyear = 2012;  // TODO: get this dynamically
    $maxyear = date('Y');

    for ($y = $minyear; $y <= $maxyear; $y++) 
    {   

        for ($m = 1; $m < 13; $m++) 
        {
            $m01 = (strlen($m)<2) ? "0$m" : $m;

            $days_in_m = date('t', strtotime("$y-$m-01"));

            for ($d = 1; $d <= $days_in_m; $d++) 
            {
                // single digit?  add preceeding 0
                $d01 = (strlen($d)<2) ? "0$d" : $d;

                // if day isn't in array, add it with 0 as a value
                if (empty($target[$y][$m01]['counts'][$d01])) $target[$y][$m01]['counts'][$d01] = 0;

                // put in correct place but works for now
                ksort($target);
                ksort($target[$y]);
                ksort($target[$y][$m01]);
                ksort($target[$y][$m01]['counts']);
            }
        }
    }

    $data->trends = $target;

现在生成如下数组:

 Array
 (
   [2013] => Array
      (
        [total] => 1510  // total for year
        [01] => Array  // Jan
            (
                [counts] => Array 
                    (
                        [01] => 0 //Jan 1
                        [02] => 1 // Jan 2
                        [03] => 1 //...
                        [04] => 3
                        [05] => 0
                        [06] => 0
                        [07] => 2
                        [08] => 1
                        [09] => 2
                        [10] => 4
                        [11] => 5
                        [12] => 0
                        [13] => 0
                        [14] => 0
                        [15] => 5
                        [16] => 21
                        [17] => 0
                        [18] => 1
                        [19] => 0
                        [20] => 0
                        [21] => 0
                        [22] => 0
                        [23] => 3
                        [24] => 2
                        [25] => 13
                        [26] => 0
                        [27] => 0
                        [28] => 24
                        [29] => 4
                        [30] => 3
                        [31] => 6
                    )

                [total] => 101 // total for Jan
            )
             ...
             // repeats for all years found in db 
             // and all months and days for those years. 

我现在有了工作图...

对从数据库中提取的 $arr 进行一次循环即可:

foreach ($arr as $obj) {
  $stt = strtotime($obj->created);
  list($year, $month, $day) = explode('-', date('Y-m-d', $stt));

  // @$target[$year][$month] = array(); // original OP request

  // increment the string for each occurrence of that day/month/year
  @$target[$year][$month][$day]++;

}
die('<pre>'.print_r($target,true));

制作中

Array
(
  [2012] => Array
      (
        [08] => Array
            (
                [22] => 1
                [23] => 1
                [24] => 1
            )

        [09] => Array
            (
                [22] => 1
                [23] => 1
            )
      )

  [2013] => Array
      (
        [08] => Array
            (
                [24] => 2
            )
    )
)

(来自以下测试数据):

$_01 = new stdClass();
$_01->created = '2012-08-22 00:00:00';
$_02 = new stdClass();
$_02->created = '2012-08-23 00:00:00';
$_03 = new stdClass();
$_03->created = '2012-08-24 00:00:00';

$_04 = new stdClass();
$_04->created = '2012-09-22 00:00:00';
$_05 = new stdClass();
$_05->created = '2012-09-23 00:00:00';
$_06 = new stdClass();
$_06->created = '2013-08-24 00:00:00';
$_07 = new stdClass();
$_07->created = '2013-08-24 00:00:00';

$arr = [$_01, $_02, $_03, $_04, $_05, $_06, $_07];

编辑 - 填入零!

for ($y = $minyear; $y <= $maxyear; $y++) {
  for ($m = 1; $m < 13; $m++) {
    $m01 = (strlen($m)<2) ? "0$m" : $m;
    $days_in_m = date('t', strtotime("$y-$m-01"));
    for ($d = 1; $d <= $days_in_m; $d++) {
      $d01 = (strlen($d)<2) ? "0$d" : $d;
      if (empty($target[$y][$m01][$d01])) $target[$y][$m01][$d01] = 0;
    }
  }
}

然后是关键排序

foreach ($target as &$month) {
  uksort($month, zeroonesort);
  foreach ($month as $day) {
    uksort($day, zeroonesort);
  }
}

function zeroonesort($a, $b) {
  $ai = (integer) $a;
  $bi = (integer) $b;
  // in php 7 use the spaceship operator <=>
  // otherwise do it the old way
  switch (true) {
    case ($ai == $bi): return 0;
    case ($ai > $bi): return 1;
    case ($ai < $bi): return -1;
  }
}

生产

Array
(
  [2012] => Array
      (
        [01] => Array
            (
                [01] => 0
                [02] => 0
                [03] => 0
                [04] => 0
                [05] => 0
                [06] => 0
                [07] => 0
                [08] => 0
                [09] => 0
                [10] => 0
                [11] => 0
                [12] => 0
                [13] => 0
                [14] => 0
                [15] => 0
                [16] => 0
                [17] => 0
                [18] => 0
                [19] => 0
                [20] => 0
                [21] => 0
                [22] => 0
                [23] => 0
                [24] => 0
                [25] => 0
                [26] => 0
                [27] => 0
                [28] => 0
                [29] => 0
                [30] => 0
                [31] => 0
            )

        [02] => Array
            (
                [01] => 0
                [02] => 0
                [03] => 0
                [04] => 0
                [05] => 0
                [06] => 0
                [07] => 0
                [08] => 0
                [09] => 0
                [10] => 0
                [11] => 0
                [12] => 0
                [13] => 0
                [14] => 0
                [15] => 0
                [16] => 0
                [17] => 0
                [18] => 0
                [19] => 0
                [20] => 0
                [21] => 0
                [22] => 0
                [23] => 0
                [24] => 0
                [25] => 0
                [26] => 0
                [27] => 0
                [28] => 0
                [29] => 0
            )

        [03] => Array
            (

等...