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

如何通过PHP+PDO+MySQL生成多层嵌套JSON输出

嘿,我懂你现在的处境——已经搞定了PDO的基础连接和表操作,结果卡在了生成想要的多层嵌套JSON这一步,对吧?别慌,我给你拿一个常见的「文章-评论」嵌套场景举例,一步步教你怎么实现,你可以根据自己的表结构直接套用。

第一步:先明确你的目标嵌套结构

假设你想要的JSON是这样的(每篇文章下包含它的所有评论):

[
    {
        "post_id": 1,
        "title": "我的第一篇文章",
        "content": "这是文章内容",
        "created_at": "2024-05-20 10:00:00",
        "comments": [
            {
                "comment_id": 1,
                "author": "张三",
                "text": "写得真好!",
                "created_at": "2024-05-20 10:30:00"
            }
        ]
    }
]

第二步:用PDO构建嵌套数组

这里有两种常用的实现方式,你可以根据数据量和需求选择:

方式一:先查顶层数据,再循环查子数据(适合小数据量)

这种方式逻辑简单,容易理解,适合数据量不大的场景:

// 1. 基础PDO连接(你已经会,这里再贴一遍确保完整)
$dsn = 'mysql:host=localhost;dbname=你的数据库名;charset=utf8mb4';
$username = '你的用户名';
$password = '你的密码';

try {
    $pdo = new PDO($dsn, $username, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
    die("数据库连接失败: " . $e->getMessage());
}

// 2. 查询所有文章
$postsStmt = $pdo->prepare("SELECT post_id, title, content, created_at FROM posts");
$postsStmt->execute();
$posts = $postsStmt->fetchAll(PDO::FETCH_ASSOC);

// 3. 遍历每篇文章,查询对应的评论并嵌套进去
foreach ($posts as &$post) {
    $commentsStmt = $pdo->prepare("SELECT comment_id, author, text, created_at FROM comments WHERE post_id = ?");
    $commentsStmt->execute([$post['post_id']]);
    // 把评论数组赋值给当前文章的comments字段
    $post['comments'] = $commentsStmt->fetchAll(PDO::FETCH_ASSOC);
}
unset($post); // 解除引用,避免后续操作污染数组

// 4. 转换为JSON并输出
header('Content-Type: application/json'); // 一定要设置正确的响应头
echo json_encode($posts, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);

方式二:一次关联查询,再重组数组(适合大数据量)

如果你的数据量比较大,多次查询数据库会影响性能,这时候可以用LEFT JOIN一次性取出所有数据,再在PHP里重组嵌套结构:

// 1. 同样先做PDO连接(省略,和上面一样)

// 2. 一次查询文章和对应的评论
$stmt = $pdo->prepare("
    SELECT 
        p.post_id, p.title, p.content, p.created_at AS post_created,
        c.comment_id, c.author, c.text, c.created_at AS comment_created
    FROM posts p
    LEFT JOIN comments c ON p.post_id = c.post_id
");
$stmt->execute();
$allData = $stmt->fetchAll(PDO::FETCH_ASSOC);

// 3. 重组数据为嵌套结构
$posts = [];
foreach ($allData as $row) {
    $postId = $row['post_id'];
    // 如果当前文章还没加入数组,先添加文章的基础信息
    if (!isset($posts[$postId])) {
        $posts[$postId] = [
            'post_id' => $row['post_id'],
            'title' => $row['title'],
            'content' => $row['content'],
            'created_at' => $row['post_created'],
            'comments' => []
        ];
    }
    // 如果这条数据有评论(LEFT JOIN可能返回null),就添加到评论数组
    if ($row['comment_id'] !== null) {
        $posts[$postId]['comments'][] = [
            'comment_id' => $row['comment_id'],
            'author' => $row['author'],
            'text' => $row['text'],
            'created_at' => $row['comment_created']
        ];
    }
}

// 把关联数组转成索引数组(可选,看你的需求)
$posts = array_values($posts);

// 4. 输出JSON
header('Content-Type: application/json');
echo json_encode($posts, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);

关键注意点

  • 用PDO::FETCH_ASSOC获取关联数组,这样键名和数据库字段对应,方便构建结构;
  • json_encode的两个参数很重要:JSON_PRETTY_PRINT让JSON格式更易读,JSON_UNESCAPED_UNICODE避免中文被转义;
  • 输出前一定要设置Content-Type: application/json,这样客户端(比如前端)才能正确识别这是JSON数据;
  • 如果你的嵌套层级更多(比如「分类-文章-评论」),只需要在现有逻辑上再加一层循环或数据重组即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:02:11