我正在用PHP和MySQL构建一个简单的博客平台。
和几乎每个博客一样,索引页基本上会从数据库中拉取所有帖子,并将它们循环到页面上。我已经想通了。
每个帖子都有未知数量的标签。我希望能够在每篇文章中呼出这些标签名。
我现在要做的是对每个帖子运行另一个查询,该查询使用帖子的id来查找该帖子的所有标记。我将这个查询包含在获取每篇文章的原始循环中。所以本质上,如果有100篇文章被返回,我将为这100篇文章中的每一篇运行一个额外的查询。。。很明显,这一页的内容太多了。我知道必须有更好的方法来处理这件事。
但是我如何在一个查询中获得未知数量的帖子,以及每个帖子的未知数量的标签。一旦我有了它们,我如何在PHP中循环它们。我猜是以某种嵌套数组返回它们???
以下是我目前正在做的事情:
function get_all_posts() {
global $pdo;
$query = $pdo->prepare('SELECT content, id FROM posts ORDER BY id DESC');
$query->execute();
$posts = $query->fetchAll(PDO::FETCH_ASSOC);
return $posts;
}
然后我重复这些结果如下:
<?php $posts = get_all_posts(); foreach ($posts as $post): ?>
<div class="post-box">
<p><?php echo $post['content']; ?></p>
<ul>
<?php $tags = get_all_tags_per_post($post['id']); foreach ($tags as $tag): ?>
<li><?php echo $tag['name']; ?></li>
<?php endforeach; ?>
</ul>
</div><!-- /.post-box -->
<?php endforeach; ?>
如您所见,在每个返回的帖子中,我正在运行另一个查询以获取标签:
function get_all_tags_per_post($pid) {
global $pdo;
$query = $pdo->prepare('SELECT t.name AS name, t.id AS tid FROM tags AS t JOIN posts_tags AS pt ON pt.tag_id = t.id WHERE pt.post_id = :pid ORDER BY tid ASC');
$query->bindValue(':pid', $pid);
$query->execute();
$tags = $query->fetchAll(PDO::FETCH_ASSOC);
return $tags;
}
基本上,我想将这两个查询结合起来,然后能够用PHP将输出打印到我的页面上。
为什么不加入Posts
与其他表?
SELECT t.name AS name,
t.id AS tid,
p.id as pid,
p.content
FROM tags AS t
INNER JOIN posts_tags AS pt
ON pt.tag_id = t.id
INNER JOIN posts AS p
ON p.id = pt.post_id
WHERE pt.post_id = :pid
ORDER BY p.id DESC, t.id ASC