使用 PHP 过滤 JSON 输出并按月份统计数据

使用 PHP 过滤 JSON 输出并按月份统计数据

本文旨在指导读者如何使用 PHP 处理复杂的 JSON 数据,特别是如何从嵌套结构中提取日期信息(如 ‘Start_Date’ 字段),并根据这些日期信息进行按月份的数据统计。通过一个具体的示例,我们将演示 JSON 解码、数据遍历、日期格式转换以及使用关联数组进行高效计数的方法,最终实现对特定月份数据量的汇总。

在现代 web 开发中,处理和分析 json 格式的数据是常见的任务。本教程将聚焦于一个具体场景:给定一个包含日期字段的 json 数据,如何使用 php 解析该数据,并统计特定日期字段(例如 start_date)在每个月份出现的次数。

1. JSON 数据结构解析

假设我们接收到一个如下所示的 JSON 响应:

{     "response": {         "datainfo": {             "foundCount": 494,             "returnedCount": 4         },         "data": [             {                 "fieldData": {                     "Closed_Date": "10/03/2021",                     "Start_Date": "10/03/2021"                 },                 "portalData": {},                 "recordId": "152962",                 "modId": "3"             },             {                 "fieldData": {                     "Closed_Date": "11/14/2021",                     "Start_Date": "11/06/2021"                 },                 "portalData": {},                 "recordId": "153228",                 "modId": "22"             }             // ... 更多数据项         ]     },     "messages": [         {             "code": "0",             "message": "OK"         }     ] }

我们的目标是从 response.data 数组中的每个对象里,访问 fieldData.Start_Date 字段,并根据此日期统计每个月份的数据量。

2. PHP 实现步骤

要实现按月份统计,我们需要经过以下几个关键步骤:

  1. 解码 JSON 数据:将 JSON 字符串转换为 PHP 关联数组。
  2. 遍历数据记录:访问 response.data 数组中的每个数据项。
  3. 提取并转换日期:从每个数据项中获取 Start_Date 字段,并将其转换为可识别的月份格式。
  4. 按月份计数:使用一个关联数组来存储每个月份的计数。

2.1 JSON 解码

首先,使用 json_decode() 函数将 JSON 字符串解码为 PHP 关联数组。第二个参数设置为 true 确保解码为关联数组而非对象。

立即学习PHP免费学习笔记(深入)”;

// 假设 $jsonString 是您获取到的 JSON 字符串 $jsonString = '{ "response": { "dataInfo": { "foundCount": 494, "returnedCount": 4 }, "data": [ { "fieldData": { "Closed_Date": "10/03/2021", "Start_Date": "10/03/2021" }, "portalData": {}, "recordId": "152962", "modId": "3" }, { "fieldData": { "Closed_Date": "11/14/2021", "Start_Date": "11/06/2021" }, "portalData": {}, "recordId": "153228", "modId": "22" }, { "fieldData": { "Closed_Date": "11/07/2021", "Start_Date": "11/06/2021" }, "portalData": {}, "recordId": "153329", "modId": "7" }, { "fieldData": { "Closed_Date": "11/08/2021", "Start_Date": "11/08/2021" }, "portalData": {}, "recordId": "153513", "modId": "3" } ] }, "messages": [ { "code": "0", "message": "OK" } ] }';  $decodedData = json_decode($jsonString, true);  // 检查解码是否成功以及数据结构是否存在 if (json_last_error() !== JSON_ERROR_NONE) {     die("JSON 解码失败: " . json_last_error_msg()); } if (!isset($decodedData['response']['data']) || !is_array($decodedData['response']['data'])) {     die("JSON 数据结构不符合预期。"); }

2.2 遍历数据并统计

接下来,我们将初始化一个空数组 $months 用于存储按月份统计的结果。然后,遍历 $decodedData[‘response’][‘data’] 数组中的每一个数据项。

在每次迭代中:

使用 PHP 过滤 JSON 输出并按月份统计数据

Find JSON Path Online

Easily find JSON paths within JSON objects using our intuitive Json Path Finder

使用 PHP 过滤 JSON 输出并按月份统计数据30

查看详情 使用 PHP 过滤 JSON 输出并按月份统计数据

  1. 提取 fieldData.Start_Date 的值。
  2. 使用 strtotime() 将日期字符串转换为 Unix 时间戳。
  3. 使用 date(“m”, …) 函数从时间戳中提取两位数的月份(例如 “10” 或 “11”)。
  4. 检查 $months 数组中是否已存在该月份的键。如果不存在,则初始化为 0。
  5. 递增该月份的计数。
// 假设 $decodedData 已经包含了解码后的 JSON 数据 $months = []; // 用于存储最终统计结果的数组 $items = $decodedData["response"]["data"];  foreach ($items as $item) {     // 确保 Start_Date 字段存在     if (isset($item["fieldData"]["Start_Date"])) {         $startDateString = $item["fieldData"]["Start_Date"];          // 将日期字符串转换为 Unix 时间戳,然后提取月份         $timestamp = strtotime($startDateString);          // 检查 strtotime 是否成功,避免无效日期导致的问题         if ($timestamp !== false) {             $month = date("m", $timestamp);              // 如果该月份在 $months 数组中不存在,则初始化为 0             if (!isset($months[$month])) {                 $months[$month] = 0;             }              // 增加该月份的计数             $months[$month]++;         } else {             // 可以选择记录或处理无效的日期字符串             error_log("无效的 Start_Date 格式: " . $startDateString);         }     } }  // 输出统计结果 print_r($months);

2.3 完整代码示例

将上述步骤整合起来,形成一个完整的 PHP 脚本:

<?php  // 模拟从 API 获取的 JSON 字符串 $jsonString = '{     "response": {         "dataInfo": {             "foundCount": 494,             "returnedCount": 4         },         "data": [             {                 "fieldData": {                     "Closed_Date": "10/03/2021",                     "Start_Date": "10/03/2021"                 },                 "portalData": {},                 "recordId": "152962",                 "modId": "3"             },             {                 "fieldData": {                     "Closed_Date": "11/14/2021",                     "Start_Date": "11/06/2021"                 },                 "portalData": {},                 "recordId": "153228",                 "modId": "22"             },             {                 "fieldData": {                     "Closed_Date": "11/07/2021",                     "Start_Date": "11/06/2021"                 },                 "portalData": {},                 "recordId": "153329",                 "modId": "7"             },             {                 "fieldData": {                     "Closed_Date": "11/08/2021",                     "Start_Date": "11/08/2021"                 },                 "portalData": {},                 "recordId": "153513",                 "modId": "3"             }         ]     },     "messages": [         {             "code": "0",             "message": "OK"         }     ] }';  // 1. 解码 JSON 数据 $decodedData = json_decode($jsonString, true);  // 错误处理:检查 JSON 解码是否成功 if (json_last_error() !== JSON_ERROR_NONE) {     die("JSON 解码失败: " . json_last_error_msg()); }  // 错误处理:检查关键数据路径是否存在 if (!isset($decodedData['response']['data']) || !is_array($decodedData['response']['data'])) {     die("JSON 数据结构不符合预期,缺少 'response.data' 路径。"); }  // 初始化一个空数组,用于存储按月份统计的结果 $months = [];   // 获取所有数据项 $items = $decodedData["response"]["data"];  // 2. 遍历数据记录并进行统计 foreach ($items as $item) {     // 确保 'fieldData' 和 'Start_Date' 字段存在     if (isset($item["fieldData"]["Start_Date"])) {         $startDateString = $item["fieldData"]["Start_Date"];          // 将日期字符串转换为 Unix 时间戳         // strtotime() 可以识别多种日期格式,例如 "MM/DD/YYYY"         $timestamp = strtotime($startDateString);          // 检查日期转换是否成功         if ($timestamp !== false) {             // 使用 date("m", ...) 从时间戳中提取两位数的月份 (例如 "01" 到 "12")             $month = date("m", $timestamp);              // 如果该月份在 $months 数组中不存在,则初始化其计数为 0             if (!isset($months[$month])) {                 $months[$month] = 0;             }              // 增加该月份的计数             $months[$month]++;         } else {             // 记录或处理无效的日期字符串,例如:             error_log("警告: 发现无效的 Start_Date 格式,跳过此项: " . $startDateString);         }     } else {         // 记录或处理缺少 Start_Date 字段的数据项         error_log("警告: 发现缺少 'Start_Date' 字段的数据项,跳过。");     } }  // 3. 输出统计结果 echo "按月份统计的结果:n"; print_r($months);  ?>

运行上述 PHP 代码,您将得到如下输出:

按月份统计的结果: Array (     [10] => 1     [11] => 3 )

这表明在原始 JSON 数据中,有 1 条记录的 Start_Date 发生在 10 月份,有 3 条记录的 Start_Date 发生在 11 月份。

3. 注意事项

  • 日期格式的健壮性:strtotime() 函数虽然强大,但并非万能。如果 Start_Date 字段的格式不固定或包含不常见的格式,strtotime() 可能会失败并返回 false。在生产环境中,建议对日期格式进行更严格的验证或使用 DateTime::createFromFormat() 来处理已知但非标准化的日期格式。
  • 错误处理:在实际应用中,应加入更多的错误处理机制,例如检查 json_decode() 的返回值、isset() 检查关键数组键是否存在,以及 strtotime() 是否成功转换日期。这有助于提高代码的健壮性。
  • 性能考虑:对于非常大的 JSON 数据集,循环遍历可能会消耗较多资源。如果数据量巨大,可以考虑分批处理或在数据库层面进行聚合(如果数据存储在数据库中)。
  • 月份键的格式:本例中使用 date(“m”, …) 获取两位数的月份(例如 “01”, “02”, …, “12”)。如果需要单数字月份(例如 “1”, “2”),可以使用 date(“n”, …)。

总结

通过本教程,我们学习了如何使用 PHP 有效地解析复杂的 JSON 数据,并从中提取特定信息进行聚合统计。核心步骤包括 JSON 解码、数据遍历、日期格式转换以及使用关联数组进行计数。这种方法不仅适用于日期统计,也为处理其他基于字段的分类和聚合任务提供了通用思路。在实际开发中,结合适当的错误处理和性能优化,可以构建出健壮高效的数据处理解决方案。

以上就是使用 PHP 过滤 JSON 输出并按月份统计数据的详细内容,更多请关注php js json ai unix yy php json 关联数组 date 字符串 循环 数据结构 对象 数据库 性能优化 unix

大家都在看:

php js json ai unix yy php json 关联数组 date 字符串 循环 数据结构 对象 数据库 性能优化 unix

ai
上一篇
下一篇