Как отформатировать данные JSON с помощью 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"}]
Однако, это не соответствует формату данных Морриса. Как я могу повернуть JSON ниже?
[{ "Месяц": 11, "В":102.23,"Выход":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");
Не уверен, что это хорошее решение.
2 ответа
Если вы имеете дело только с данными за один месяц, вам не нужно вызывать какие-либо умные функции, потому что ваша структура данных предсказуема. Просто вручную перестроить.
Код: ( Демо)
$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`)
");
Используя json_decode, вы можете декодировать свой JSON, и если вы передадите true
в качестве второго параметра у вас будет ассоциативный массив. Теперь создайте $result
array
который будет пустым в начале, и вы будете заполнять результат (ы) там. Теперь, переберите декодированный JSON, проанализируйте результаты и заполните $result
с ними. Когда это закончится, конвертировать $result
в JSON, используя json_encode, и это должно решить проблему.