PHP访问JSON数组completed字段及筛选功能实现求助
解决JSON数据展示与布尔字段筛选的PHP问题
咱们一步步拆解你的问题并修复它——首先得明确你遇到的报错根源:"Trying to access array offset on value of type bool" 是因为你试图对布尔值($value->completed本身就是布尔类型)使用数组偏移['1'],这完全不符合语法逻辑。除此之外,你的代码还存在表格结构错误、筛选逻辑缺失等问题,下面是完整的解决方案:
核心问题梳理
- 布尔字段访问错误:
completed是布尔类型字段,直接通过$item->completed(解析为对象时)或$item['completed'](解析为数组时)访问即可,不需要额外加数组下标。 - 筛选逻辑缺失:你没有根据按钮提交的请求过滤原始数据,只是直接遍历了未筛选的数组。
- HTML结构错误:
</table>标签放在foreach循环内部,会导致每循环一次生成一个新表格,而非在同一个表格里生成多行数据。
修复后的完整代码
下面是包含数据获取、按钮筛选、表格展示的完整可运行代码:
<?php // 1. 获取并解析JSON接口数据 $jsonUrl = 'https://jsonplaceholder.typicode.com/todos/'; // 优先使用curl(避免file_get_contents被服务器禁用的情况) $ch = curl_init($jsonUrl); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $jsonData = curl_exec($ch); curl_close($ch); // 解析为对象数组(想转成关联数组就加第二个参数true:json_decode($jsonData, true)) $todos = json_decode($jsonData); // 2. 处理按钮筛选逻辑 $filteredTodos = $todos; if ($_SERVER['REQUEST_METHOD'] === 'POST') { if (isset($_POST['filter'])) { $filterType = $_POST['filter']; // 根据筛选条件过滤数据 $filteredTodos = array_filter($todos, function($todo) use ($filterType) { if ($filterType === 'completed') { return $todo->completed === true; } elseif ($filterType === 'incomplete') { return $todo->completed === false; } return true; // 默认返回全部数据 }); } } ?> <!DOCTYPE html> <html> <head> <title>Todos 列表</title> <style> .table { border-collapse: collapse; width: 80%; margin: 20px auto; } .table th, .table td { border: 1px solid #ddd; padding: 8px; text-align: left; } .table th { background-color: #f2f2f2; } .btn-group { text-align: center; margin: 20px 0; } .btn { padding: 8px 16px; margin: 0 5px; cursor: pointer; border: none; border-radius: 4px; } .btn.completed { background-color: #4CAF50; color: white; } .btn.incomplete { background-color: #f44336; color: white; } .btn.all { background-color: #e7e7e7; color: black; } </style> </head> <body> <div class="btn-group"> <!-- 筛选按钮表单 --> <form method="post" style="display: inline;"> <button type="submit" name="filter" value="completed" class="btn completed">仅显示已完成</button> </form> <form method="post" style="display: inline;"> <button type="submit" name="filter" value="incomplete" class="btn incomplete">仅显示未完成</button> </form> <form method="post" style="display: inline;"> <button type="submit" name="filter" value="all" class="btn all">显示全部</button> </form> </div> <!-- 数据展示表格 --> <table class="table"> <tr> <th>User ID</th> <th>ID</th> <th>Title</th> <th>Completed</th> </tr> <?php foreach ($filteredTodos as $todo): ?> <tr> <td><?php echo htmlspecialchars($todo->userId); ?></td> <td><?php echo htmlspecialchars($todo->id); ?></td> <td><?php echo htmlspecialchars($todo->title); ?></td> <td><?php echo $todo->completed ? '✅ 已完成' : '❌ 未完成'; ?></td> </tr> <?php endforeach; ?> </table> </body> </html>
关键修复点说明
正确访问布尔字段:
- 解析JSON后,每个todo是对象,直接用
$todo->completed获取布尔值,判断时用$todo->completed === true即可,不需要任何数组下标。 - 如果偏好数组格式,将
json_decode($jsonData)改为json_decode($jsonData, true),访问方式改为$todo['completed']。
- 解析JSON后,每个todo是对象,直接用
完善筛选逻辑:
- 使用
array_filter结合匿名函数,根据按钮提交的筛选条件过滤原始数据,只保留符合要求的todo项。 - 用
use ($filterType)将外部变量传入匿名函数,确保筛选逻辑正常运行。
- 使用
修复HTML结构:
- 将表格的
<table>和</table>标签放在foreach循环外部,保证所有数据行都在同一个表格内。 - 用
htmlspecialchars转义输出内容,避免XSS安全风险。
- 将表格的
优化按钮交互:
- 每个按钮单独对应一个表单,避免多按钮提交时的参数冲突,同时提升用户交互体验。
内容的提问来源于stack exchange,提问作者user12799906
相关产品推荐
相关产品推荐

