如何统计snowDepth年度总量并修复PHP的int+array类型错误
实现snowDepth年度总量统计并修复类型错误
问题背景
现有SQL查询可获取月度snowDepth总量并生成HTML表格,需要扩展统计年度总量,但修改PHP代码时出现错误:
Fatal error: Uncaught TypeError: Unsupported operand types: int + array
错误原因分析
问题代码存在两个核心问题:
- 嵌套了不必要的外层
$years循环,导致重复处理所有年份数据,逻辑混乱 $thisMonthCount = $months[$monthShort] ?? 0获取到的是数组(原代码$years[$year][$month][] = $row将月度数据存为数组),而非数值,强制转int时触发类型错误
解决方案
方案一:修改SQL直接获取年度总量(更高效)
直接通过SQL分组求和,无需PHP额外计算,性能更优。
仅获取年度总量的SQL
SELECT strftime('%Y', Timestamp) AS year, SUM(snowDepth) AS annual_total FROM DiaryData GROUP BY year ORDER BY year DESC
同时获取月度+年度总量的SQL(用ROLLUP汇总)
SELECT strftime('%Y', Timestamp) AS year, substr('JanFebMarAprMayJunJulAugSepOctNovDec', 1 + 3*strftime('%m', Timestamp), -3) AS month, SUM(snowDepth) AS depth FROM DiaryData GROUP BY year, month WITH ROLLUP ORDER BY year DESC, month
注:结果中
month为NULL的行,对应该年份的年度总量
方案二:修复现有PHP代码计算年度总量
调整数据存储结构与循环逻辑,避免类型错误:
修改后的完整PHP代码
<?php // 读取查询结果并整理数据 $years = []; while ($row = $result->fetch(PDO::FETCH_ASSOC)) { $year = $row['year']; $month = $row['month']; // 直接存储月度深度数值,避免不必要的数组嵌套 $years[$year][$month] = (int)$row['depth']; } $totalSQLtime = (microtime(true) - $startSQLtime); $monthx = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; // 输出表格头部 echo '<table><thead><tr><th>年份</th>'; foreach ($monthx as $month) { echo "<th>$month</th>"; } echo '<th>年度总量</th></tr></thead><tbody>'; // 循环输出每年数据及年度总量 foreach ($years as $year => $months) { echo "<tr><td>$year</td>"; $annualTotal = 0; foreach ($monthx as $month) { // 读取月度数据,无数据则设为0 $monthDepth = $months[$month] ?? 0; $annualTotal += $monthDepth; echo "<td>$monthDepth</td>"; } // 输出年度总量 echo "<td>$annualTotal</td></tr>"; } echo '</tbody></table></div>'; // 输出耗时统计 echo '<p style="font-size:0.9em; padding: 10px 0 0 0;">'; echo 'Queries took: ' . number_format($totalSQLtime, 6) . ' secs<br>' . PHP_EOL; $totaltime = (microtime(true) - $starttime); echo 'Total gen time: ' . number_format($totaltime, 6) . ' secs'; echo '</p>'; ?>
修复关键点
- 调整数据存储:将
$years[$year][$month][] = $row改为$years[$year][$month] = (int)$row['depth'],直接存储月度数值而非数组 - 移除嵌套的外层
$years循环,在当前年份的循环内计算年度总量 - 统一处理月度数据默认值为0,避免未定义变量问题
内容的提问来源于stack exchange,提问作者surban21
相关产品推荐
相关产品推荐

