【问题标题】:(drupal)a difficulty code to understand,get the same article's title under the same term(drupal)一个难懂的代码,得到同一篇文章同名同名
【发布时间】:2010-11-23 09:05:36
【问题描述】:
if ($node->taxonomy) {
 $query = 'SELECT DISTINCT(t.nid), n.nid, n.title FROM {node} n INNER JOIN {term_node}    t ON n.nid = t.nid WHERE n.nid != %d AND (';


 $args = array($node->nid);
   $tids = array();

  foreach ($node->taxonomy as $term) {
  $tids[] = 't.tid = %d';
  $args[] = $term->tid;
}

  $query .= implode(' OR ', $tids) .  ')';

 $result = db_query_range($query, $args, 0, 10);
while ($o = db_fetch_object($result)) {
echo l($o->title, 'node/' . $o->nid);
}

}

代码来自 Drupal 大师。 .曾经在node.tpl.php中获得相同术语的文章标题,我已经研究了两天,虽然知道它的一部分。代码的原理我还是不知道。希望有人可以为我解释更多细节。非常感谢。

【问题讨论】:

    标签: drupal module term


    【解决方案1】:

    短版:

    获取节点的标签数组检索前10个节点至少使用这些标签中的一个并为每个节点输出一个链接 这 10 个结果。


    详细版本:

    首先,变量“$node”是一个包含特定节点(例如页面或故事节点)数据的对象。 例如,“$node->title”将是该节点的标题。


    "$node->taxonomy" 测试该节点是否被标记(因为如果它没有标记,则无法检索使用相同标记的其他节点。 当有一个或多个标签与该节点/页面/故事相关联时,$node->taxonomy 是一个 array


    现在关于 SQL 查询: “node”是存储每个节点的基本字段(非CCK)的数据库表。 “term_node”是包含标签(称为“taxonomy term”)和节点组合的数据库表。


    在这两个表中,“nid”是“unique Node ID”(这是一个内部自动递增的数字)。因为此列在两个表中,所以这就是将表连接在一起的方式。

    在“term_node”中,“tid”是“unique Term ID”(也是一个内部自动递增的数字)。


    node”表别名为“n”,因此“n.nid”表示“the Node ID stored in table node”。 “term_node”表别名为“t”,因此“t.tid”表示“the Term ID stored in table term_node”。


    foreach”循环遍历标签数组以提取节点使用的每个标签的 TermID,以便将其添加到 SQL 查询中,并将 implode 转换为字符串.

    循环在变量$tids 中存储每个标签的一段SQL 查询,并将实际值存储在变量$args 中,因为当参数与SQL 查询分开传递时,Drupal 数据库调用更安全:“%d " 表示 "integer number"。


    db_query_range”是选择数据库中多行的函数:这​​里,“0 10”表示“retrieve the first 10 results”。


    while”循环中的“db_fetch_object”检索每个结果并将其存储在变量“$o”中,该变量是一个对象。

    因此,“$o->title”包含 SQL 查询检索到的“title”列的值。


    函数“l”是创建HTML链接代码的drupal函数:第一个参数是链接的名称,第二个参数是drupal路径:在Drupal中,任何节点都可以通过以下方式访问默认使用“www.yoursite.com/node/NodeID”, 这就是为什么它给出路径“node/123”(其中123 是“Node ID”)。

    此函数很有用,因为它透明地处理自定义路径,因此如果您的节点有自定义路径来使用“www.yoursite.com/my-great-page”访问它,它将自动创建指向该页面的链接而不是“www.yoursite.com/node/123”。

    【讨论】:

    • 你是我的英雄。非常感谢。但是有些部分我不能很好地遵循。 "n "term_node", "tid" 是“唯一的 Term ID”(也是一个内部自动递增的数字)。我看了一下表“term_node”,有相同的行具有相同的tid。
    • 我为什么要做这两行"$args = array($node->nid); $tids = array();"
    • 在 foreach 循环中,$term 来自哪里,我怎么知道它是一个对象。
    • "$args = array($node->nid); $tids = array()" 是用于构建 SQL 查询部分的两个变量的初始化,具体取决于 "术语 ID”。唯一需要注意的是 $args 已经包含一个值,因为在 SQL 语句的第 2 行,有“WHERE n.nid != %d”(从查询中排除当前节点),这就是它需要的原因Drupal 的“节点 ID”的值,以将其放置在 SQL 中,而不是“%d”。
    • TermID是唯一的,但它来自第三张表“term_data”,在SQL中没有使用,所以我没有提到它。在“term_node”中,“tid”引用了该唯一 ID,但是在“term_node”中,每个关联“tagnode”有一行,因此如果标签被使用,则有多行具有相同的“tid”几个节点;同理,如果一个节点有多个标签,就会有多行具有相同的“nid”。
    【解决方案2】:

    我不会把写这篇文章的人称为大师,你可以做得更漂亮。不管他做什么,它都会创建一个如下所示的查询:

     SELECT DISTINCT(t.nid), n.nid, n.title FROM {node} n
     INNER JOIN {term_node} t ON n.nid = t.nid
     WHERE n.nid != %d
     AND (t.tid = %d OR t.tid = %d OR ... t.tid = %d);
    

    最终结果是他选择了所有与所选节点共享至少一个术语但不是节点本身的节点 ID 和标题(仅一次)。

    【讨论】:

    • 谢谢你,你也是大师。但你的回答太抽象了。我不能很好地遵循它。我不知道这条线“(t.tid = %d OR t.tid = %d OR ... t.tid = %d);”来自。