如何使用Drupal的node_load()防止无限递归?

我正在使用Ubercart产品和product_kit模块。这非常适用于从相关产品套件到包含的产品的链接,但我也希望从单个产品链接到它可能属于的任何套件。 我想我可以在SKU /型号上进行数据库搜索(轻松完成该部分),然后使用node_load($ nid)获取相关工具包。 到目前为止我有这个:
function amh_shop_nodeapi(&$node, $op, $a3 = null, $a4 = null)
{
    if ($node->type == 'product') {
        if ($op == 'load') {
            error_log("product::load");

            $bundles = array();
            $results = db_query('SELECT DISTINCT n.nid FROM {node} n RIGHT JOIN {uc_products} up ON up.nid = n.nid WHERE up.model LIKE "%s /%" OR up.model LIKE "%/ %s /%" OR up.model LIKE "%/ %s"', $node->model, $node->model, $node->model);

            while ($bundle = db_fetch_object($results)) {
                error_log("bundle::load");
                $bundles[] = node_load($bundle->nid);
            }
        }
    }
}
但是,由于产品套件也在加载产品,我最终会进行递归循环。 我想我的问题实际上分为两部分: 问题是这篇文章的标题:我该如何防止这种递归? 可能会回答第一个问题的略有不同的问题:我应该在加载节点时执行此操作,还是稍后在此过程中执行此操作(例如,在查看或更改时)?     
已邀请:
嘿,有一个名为http://drupal.org/project/contemplate的模块。他们在该模块中有类似的递归问题,但他们通过设置recursion_limit找到了解决方法。 我不确定它是否能解决你的问题,但是肯定值得通过他们的模块并搜索代码来找到contemplate_max_recursion_depth。这可能会给你一些指示。 希望能帮助到你..     
解决方案之一,只是不要为product_kit调用node_load,因此它不会为子产品调用node_load,通过db_query手动查询需要数据:
function amh_shop_nodeapi(&$node, $op, $a3 = null, $a4 = null)
{
    if ($node->type == 'product') {
        if ($op == 'load') {
            $bundles = array();
            $results = db_query('SELECT n.nid, n.title FROM {node} n INNER JOIN {uc_product_kits} k ON n.nid=k.nid WHERE n.product_id=%d ORDER BY n.title', $node->nid);
            while ($bundle = db_fetch_object($results)) {
                $bundles[] = l($bundle->title, 'node/'.$bundle->nid);
            }
        }
    }
    $node->amh_bundles = $bundles; // Here's array of links to product_kits
}
    
怎么样:它引入了一个递归变量检查。
function amh_shop_nodeapi(&$node, $op, $a3 = null, $a4 = null)
{
  static $recursion_nid = NULL;
    if ($node->type == 'product') {
        if ($op == 'load') {
            error_log("product::load");

            $bundles = array();
            $results = db_query('SELECT DISTINCT n.nid FROM {node} n RIGHT JOIN {uc_products} up ON up.nid = n.nid WHERE up.model LIKE "%s /%" OR up.model LIKE "%/ %s /%" OR up.model LIKE "%/ %s"', $node->model, $node->model, $node->model);

            while ($bundle = db_fetch_object($results)) {
                error_log("bundle::load");
                if (isset($recursion_nid) && $recursion_nid == $nid) {
                   // recursion detected
                }
                else {
                  $recursion_nid = $node->nid;
                  $bundles[] = node_load($bundle->nid);
                  unset($recursion_nid);
                }
            }
        }
    }
}
    
你应该考虑像这样缓存数据。如果你一直在加载它真的会耗尽资源。我会考虑一个自定义模块,可以存储各个项目和相关工具包之间的关系。     

要回复问题请先登录注册