如何使用 PHP 格式化 JSON 数据

How to format a JSON data using PHP

我有以下方法计算每个月的收入和支出。

$query = Transaction::whereYear('date', $year)
                ->groupBy([DB::raw('MONTH(date)'),'type'])->get([DB::raw('MONTH(date) as month'), DB::raw('SUM(amount) as value'), 'type'])
                ->toJSON();

获得 JSON 数据后,我想将它们填充到莫里斯条形图中。

下面是JSON格式,

[{"month":11,"value":102.23,"type":"In"},{"month":11,"value":133.9,"type":"Out"}]

但是,它不适合 Morris 数据格式。我怎样才能将 JSON 扭曲到下面?

[{"month":11,"In":102.23,"Out":133.9}]

$(function() {
  var chart = Morris.Bar({
    element: 'morris-bar-chart',
    data: [0, 0], 
    xkey: 'Month',
    ykeys: ['In', 'Out'], 
    labels: ['In','Out'], 
    hideHover: 'auto',
    resize: true
  });
  $.ajax({
      type: "GET",
      dataType: 'json',
      url: "./getMonthlyOverview"
    })
    .done(function( data ) {
      chart.setData(data);
    })
    .fail(function() {
      alert( "error occured" );
    });
});

我尝试将查询更改为以下内容:

$stats = DB::select("select month,  SUM(IF( type = 'In', amount, 0)) as Income,  SUM(IF( type = 'Out', amount, 0)) as Expense from "
                . "(SELECT MONTH(date) as month, type, SUM(amount) as amount FROM Transactions WHERE YEAR(date) = " . $year . " group by MONTH(date), type) as c "
                . "group by month");

不确定这是不是一个好的解决方案。

使用 json_decode you can decode your JSON and if you pass true as the second parameter, you will have an associative array. Now, create a $result array which will be empty at the start and you will fill the result(s) there. Now, iterate through the decoded JSON, parse the results and fill $result with them. When this is finished, convert $result to JSON using json_encode 这应该可以解决问题。

如果只处理一个月的数据,那么你不需要调用任何巧妙的函数,因为你的数据结构是可预测的。只需手动重组。

代码:(Demo)

$json = '[{"month":11,"value":102.23,"type":"In"},{"month":11,"value":133.9,"type":"Out"}]';

$array = json_decode($json, true);

echo json_encode(['month' => $array[0]['month'], $array[0]['type'] => $array[0]['value'], $array[1]['type'] => $array[1]['value']]);

输出:

{"month":11,"In":102.23,"Out":133.9}

如果您在一个集合中处理多个月份,您只需要迭代结果集,将上面的硬编码 [0][1] 键替换成对变量:0 和 1 在一起, 2 & 3, 等等


更新:如果您愿意编写自定义 mysql 查询,那么应该这样做:

$stats = DB::select("
    SELECT `month`,
           SUM(IF(`type` = 'In', amount, 0)) AS Income,
           SUM(IF(`type` = 'Out', amount, 0)) AS Expense
    FROM Transactions
    WHERE YEAR(`date`) = " . (int)$year . "
    GROUP BY MONTH(`date`)
");