【问题标题】:Tagging and exploding in phpphp中的标记和爆炸
【发布时间】:2011-02-06 17:34:51
【问题描述】:

在我的索引文件中,我使用这个函数(在另一个文件中)从数据库中获取数据:

function get_all_threads($link, $start)
{
    $threads = select_Query("SELECT thread.title, thread.id as t_id,
                           thread.content, author.username, author.id as a_id,
                           GROUP_CONCAT(DISTINCT tags.name ORDER BY tags.name DESC SEPARATOR ',') AS tags
                           FROM thread JOIN thread_tags ON thread.id = thread_tags.thread_id
                           JOIN tags ON thread_tags.tag_id = tags.id
                           INNER JOIN author on author.id = thread.author_id
                           GROUP BY thread.id DESC
                           LIMIT $start, 30", $link);     

    return $threads;
}

我的索引文件中的代码如下:

    $threads = get_all_threads($link, $start);
    include FORUM_ROOT . 'html/main/threads.html.php';

在threads.html.php中

<?php foreach ($threads as $thread): ?>

<h1><?php echo $thread['title']; ?></h1>
<?php echo $thread['content']; ?>
<?php echo $thread['tags']; ?> <!-- All of these appear as one -->

<?php endforeach; ?>

如您所见,我得到了线程、它们的作者和它们的标签。但是我使用 GROUP_CONCAT 作为标签,所以当我想让每个单独的标签成为一个链接时,比如在threads.html.php中:

<a href="?tag=<?php echo $thread['tags']; ?>" > 
   <?php echo $thread['tags']; ?>  
</a>

所有标签都显示为一个链接,(例如,如果标签是苹果、橙子、香蕉,它们将显示为apple, orange, banana 而不是appleorangebanana):

我知道要拆分这些标签,我可以使用explode然后迭代每个标签,如下所示:

<?php $tags = array(); 
$tags = explode(',', $thread['tags']);
?>


(Tagged: 
<?php foreach ($tags as $tag): ?>
<a href="/tag?=<?php echo $tag;?>"><?php echo $tag; ?></a>
<?php endforeach; ?>)

但是,我必须在threads.html.php 中执行此操作,并且我想保持演示代码分开。

在 index.php 中有更简洁的方法吗?此外,对于超过 30 个线程,迭代每个线程并分解每个标签将花费太长时间。

编辑:

我的表结构如下:

thread、author_threads、author、tag、thread_tags、reply 和 author_replies

1:http://apple,橙子,香蕉

【问题讨论】:

  • 你能添加你的数据库表结构吗
  • 如果可能的话,我更愿意简化问题。
  • 我不认为GROUP_CONCAT 是 SQL 标准……您使用哪个 DBS?
  • 你为什么首先使用 group_concat?我看到您使用很多连接来获取线程的标签……哦,我想我现在明白了。您有一个可能带有多个标签的线程,并且在打印标签时要链接它们!?这很简单:不要在 1 个查询中执行此操作。在一个查询中获取线程,然后在另一个查询中获取线程的标签。
  • @Kissaki GROUP_CONCAT 是 MySQL 函数。

标签: php mysql


【解决方案1】:

get_all_threads 视为模型的一部分 - 黑盒 - 您不需要知道如何获取数据(是 SQL 查询、xml 文件还是外部 api 调用)。你对数据感兴趣,仅此而已。

目前无法通过 SQL 查询为一个线程获取多个标签。即使您删除GROUP_CONCAT,您也会为一个线程获得一堆记录,这也需要以某种方式解析。但是根据第一段,您应该在函数中解析数据。

function get_all_threads($link, $start)
{
    $threads = select_Query("SELECT thread.title, thread.id as t_id,..");

    //PHP 5.3   
    array_walk($threads, function(&$thread) {
        $thread['tags'] = explode(',', $thread['tags']);
    });

    //PHP < 5.3
    foreach ($threads as &$thread) {
        $thread['tags'] = explode(',', $thread['tags']);
    }


    return $threads;
}

当你这样做时,你的演示代码将是干净的。

【讨论】:

  • 该代码需要 PHP 5.3,因为它使用匿名函数。添加没有它的版本。但建议升级到 PHP 5.3 ;)
  • 我正在使用 ubuntu Karmic Koala,所以我必须先升级它才能获得 5.3
【解决方案2】:

您想为每个线程获取并打印多个标签。那么为什么要在一个查询中完成呢?而不是做一个大规模的查询,你会:

SELECT thread.title, thread.id as t_id, thread.content,
       author.username, author.id as a_id,
INNER JOIN author ON author.id = thread.author_id
ORDER BY thread.id DESC
LIMIT $start, 30

每个线程都有一个

SELECT tags.name
FROM thread_tags
WHERE thread_tags.thread_id == $id

将它们存储在数据结构中并将其传递给您的演示模板(就像您现在使用线程列表一样)。

(天哪,这是一个复杂的查询...... 现在看起来也好多了,对吧?而且更容易阅读和理解!)

顺便说一句,GROUP BY thread.id DESC 是怎么回事?我确实希望您的 ID 是唯一的,或者更好的是 PRIMARY KEY!那么就不需要 GROUP BY 了!

【讨论】:

  • 我其实不知道为什么 group by 在那里,我正在使用主键,现在删除它
  • 我的问题是我不会总是知道我将获得多少线程,看看限制。
  • 那有什么问题?获取您获得的所有主题的标签。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-26
  • 1970-01-01
  • 2013-02-13
  • 2022-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多