将PHP数组转换为Google Chart可用JS数组的排序问题求助
解决Google Chart数组格式的code顺序异常问题
我来帮你分析并解决这个问题:
问题根源
你的readPerMonth函数里最后一行的ksort($output[$year][$month]);是核心问题:
- 这行代码只会对最后一次循环处理的月份的code数组进行按键名排序(E、P、T、U),而其他月份的数组保持初始定义的顺序(P、T、U、E)
- 这种不一致的顺序会导致转换为Google Chart所需的JS数组时,每个月份的类别列对应混乱,最终图表显示错误
- 另外,函数里的空数组判断分支存在未定义变量
$year和$month的问题,会触发PHP警告
修复后的完整代码
$inputArray = [ ['date' => '2016-12-10', 'code' => 'P'], ['date' => '2016-12-15', 'code' => 'P'], ['date' => '2017-02-10', 'code' => 'P'], ['date' => '2017-02-14', 'code' => 'P'], ['date' => '2017-03-10', 'code' => 'P'], ['date' => '2017-03-05', 'code' => 'U'], ['date' => '2017-03-11', 'code' => 'U'], ['date' => '2017-03-12', 'code' => 'P'], ['date' => '2017-04-07', 'code' => 'T'], ['date' => '2017-04-18', 'code' => 'P'], ['date' => '2017-04-19', 'code' => 'T'], ['date' => '2017-07-10', 'code' => 'P'], ]; function readPerMonth($tmpArray) { $output = []; // 定义固定的code顺序,确保所有月份的数组顺序一致 $fixedCodeOrder = ['P', 'T', 'U', 'E']; if (empty($tmpArray)) { // 空数组时返回一个默认的月份统计(可根据需求调整) $currentYear = date('Y'); $currentMonth = date('M'); $defaultStats = array_fill_keys($fixedCodeOrder, 0); $output[$currentYear][$currentMonth] = $defaultStats; } else { foreach ($tmpArray as $value) { $year = date('Y', strtotime($value['date'])); $month = date('M', strtotime($value['date'])); // 初始化月份统计数组,严格遵循固定顺序 if (!isset($output[$year][$month])) { $output[$year][$month] = array_fill_keys($fixedCodeOrder, 0); } // 只处理预期内的code类型,避免非法键名干扰 if (in_array($value['code'], $fixedCodeOrder)) { $output[$year][$month][$value['code']] += 1; } } // 对年份按数字顺序排序 ksort($output); // 对每个年份下的月份按时间顺序排序(而非字母顺序) foreach ($output as &$yearData) { $monthOrder = array_map(function($m) { return date('M', strtotime("2000-$m-01")); }, range(1, 12)); uksort($yearData, function($a, $b) use ($monthOrder) { return array_search($a, $monthOrder) - array_search($b, $monthOrder); }); } } return $output; } function phpToJS($inputPHP) { $return = ''; // 和readPerMonth保持一致的固定code顺序 $fixedCodeOrder = ['P', 'T', 'U', 'E']; foreach ($inputPHP as $year => $months) { foreach ($months as $monthValue => $codeValues) { $sum = 0; $return .= "['" . $year . " - " . $monthValue . "', "; // 严格按固定顺序遍历,保证JS数组列顺序完全统一 foreach ($fixedCodeOrder as $code) { $value = $codeValues[$code]; $return .= $value . ','; $sum += $value; } // 移除最后一个多余逗号,添加总和 $return = rtrim($return, ',') . ",'" . $sum . "'],"; } } // 移除末尾多余的逗号,生成合法JS数组格式 return rtrim($return, ','); } $tmpArr = readPerMonth($inputArray); $output = phpToJS($tmpArr);
关键修复点说明
- 统一code顺序:
- 用
$fixedCodeOrder固定code的排列顺序,所有月份的统计数组都严格遵循这个顺序初始化和更新
- 用
- 移除错误排序:
- 删除了只处理最后一个月的
ksort代码,避免破坏统一的顺序规则
- 删除了只处理最后一个月的
- 月份时间排序:
- 新增月份排序逻辑,确保每个年份下的月份按1-12月的时间顺序排列,而非字母顺序(比如Feb不会排在Apr之后)
- JS转换优化:
- 按照固定顺序生成JS数组,彻底避免列顺序混乱
- 修复了原函数中的字符串拼接语法错误,自动处理多余逗号问题
- 空数组分支修复:
- 解决了空数组时未定义年份月份的问题,添加合理默认值
最终效果
修复后的代码会生成顺序完全一致的统计数组,转换后的JS数组可以直接用于Google Chart堆叠图,每个月份的code列对应准确,不会出现显示错误。
内容的提问来源于stack exchange,提问作者user9191816
相关产品推荐
相关产品推荐

