You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP访问JSON数组completed字段及筛选功能实现求助

解决JSON数据展示与布尔字段筛选的PHP问题

咱们一步步拆解你的问题并修复它——首先得明确你遇到的报错根源:"Trying to access array offset on value of type bool" 是因为你试图对布尔值($value->completed本身就是布尔类型)使用数组偏移['1'],这完全不符合语法逻辑。除此之外,你的代码还存在表格结构错误、筛选逻辑缺失等问题,下面是完整的解决方案:

核心问题梳理

  1. 布尔字段访问错误:completed是布尔类型字段,直接通过$item->completed(解析为对象时)或$item['completed'](解析为数组时)访问即可,不需要额外加数组下标。
  2. 筛选逻辑缺失:你没有根据按钮提交的请求过滤原始数据,只是直接遍历了未筛选的数组。
  3. 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>

关键修复点说明

  1. 正确访问布尔字段:

    • 解析JSON后,每个todo是对象,直接用$todo->completed获取布尔值,判断时用$todo->completed === true即可,不需要任何数组下标。
    • 如果偏好数组格式,将json_decode($jsonData)改为json_decode($jsonData, true),访问方式改为$todo['completed']。
  2. 完善筛选逻辑:

    • 使用array_filter结合匿名函数,根据按钮提交的筛选条件过滤原始数据,只保留符合要求的todo项。
    • 用use ($filterType)将外部变量传入匿名函数,确保筛选逻辑正常运行。
  3. 修复HTML结构:

    • 将表格的<table>和</table>标签放在foreach循环外部,保证所有数据行都在同一个表格内。
    • 用htmlspecialchars转义输出内容,避免XSS安全风险。
  4. 优化按钮交互:

    • 每个按钮单独对应一个表单,避免多按钮提交时的参数冲突,同时提升用户交互体验。

内容的提问来源于stack exchange,提问作者user12799906

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 13:48:12