使用 PHP/MySQLi 是否有更好的显示标签的方法?

Is there a better way to display tags using PHP/MySQLi?

在我的网站中,我使用了标记系统。它有效,但我注意到它效率极低,如果我想显示标签列表,则需要对每个标签执行单独的 SQL 查询。

This is my tag table within the database

这是获取和显示标签的方式:

$tags = json_decode(json_encode(explode(',', $row["tags"])));

foreach($tags as $tag) {
    $fetchTags = $conn->prepare("SELECT id, name FROM tags WHERE id = ? AND type = 1");
    $fetchTags->bind_param("i", $tag);
    $fetchTags->execute();
    $fetchResult = $fetchTags->get_result();
    if($fetchResult->num_rows === 0) print('No rows');
    while($resultrow = $fetchResult->fetch_assoc()) {
      ?><span class="badge bg-primary me-2"><?php echo $resultrow["name"]; ?></span><?php
    }
    $fetchTags->close();
}

请注意,$tags 等同于它们的标签 ID,例如1,2,3。搜索1个标签可能没问题,但当你有5-10个标签需要搜索时,你就会发现问题。

我曾考虑在 1 个 SQL 查询中搜索标签,但 MySQLi 的工作方式和绑定参数很奇怪。我看到这里的一些人建议使用 PDO,但我不确定该实现将如何工作。如果需要,我可以改用 PDO,但理想情况下我想继续使用 MySQLi.

我认为最简单的方法是 运行 使用 WHERE IN 的单个查询以仅匹配您需要的标签。

$tags = explode(',', $row["tags"]);
$placeholders = implode(',', array_fill(0, count($tags), '?'));
$fetchTags = $conn->prepare('SELECT id, name FROM tags WHERE id IN ('.$placeholders.') AND type = 1 ORDER BY id');
$fetchTags->bind_param(str_repeat('s', count($tags)), ...$tags);
$fetchTags->execute();
$fetchResult = $fetchTags->get_result();
if($fetchResult->num_rows === 0) {
    print('No rows');
}
foreach($fetchResult as $row) {
    echo $row['name'];
}

在 PHP 8.1 上,您可以避开 bind_param() 行,只需将数组传递到 execute().

$fetchTags->execute($tags);