繁体   English   中英

PHP SPL操作递归菜单

[英]PHP SPL to manipulate recursive menu

我在数据库中有一个表,其中包含类别数据:

id   title       parent 
1    category 1  0
2    category 2  2
3    category 3  3
4    category 4  0

每个父级可以具有父级行ID。

例如,类别3是类别2的子级,它是类别1的子级。

category 1
   category 2
      category 3

category 4

1-是否有更好的方法来操纵此技术? 2-我的实现是在一个SQL查询中获取所有行,然后使用递归函数构建多维数组,然后使用多级foreach遍历该数组以构建菜单或其他内容。 我需要使用PHP SPL的更好方法。

我想创建完整菜单或项目路径,例如:

category1 -> catgory 2 -> etc.

并创建一个在每一行中包含类别级别的网格。

如果您的数据严格地是分层的,并且看起来像是分层的,那么我建议您使用“修改的预序树遍历”方法来存储数据。

Sitepoint上有一篇很棒的文章讨论了这个确切的问题。 您似乎正在使用邻接表模型,该模型在第1页上进行了讨论,但是MPTT对于此类数据的大量读取存储效率更高。

请查看第2页以查看示例。 这确实是一个很棒的架构。

我最近使用一个查询和一个while循环为类似的东西做圆顶。 它使用引用通过一个平面(数组)来构建树数据结构(数组)。 没有涉及SPL,因为我认为没有必要。 GitHub上有一个更好的配色方案:)

/**
* Each element in the return array has a 'data' key, holding category data,
* like name, and a 'children' key holding its subcategories.
*
* @param resource $resource MySQL resource resulted from mysql_query
* @param string $id_key Name of the 'id' field
* @param string $parent_id_key Name of the 'parent_id' field
* @param boolean $use_cache Use cached result from previous calls. Defaults to TRUE
* @return array
*/
function categories($resource, $id_key, $parent_id_key, $use_cache = true) {
    // Cache the categories in a static local variable. This way, the query
    // will be executed just for the first function call. Subsequent calls
    // will return imediatelly, unless you tell it not to.
    static $tree = array();

    if ($tree && $use_cache) {
        return $tree;
    }

    // Flat representation of the categories for fast retrieval using array
    // keys. Each element will be referenced in the $tree array. This
    // allows to build a tree data structure using a flat one.
    $flat = array();

    // Reset the $tree, in case $use_cache=false in a subsequent call
    $tree = array();

    while ($row = mysql_fetch_object($resource)) {
        $flat[$row->$id_key] = array(
            'data' => $row,
            'children' => array(),
        );

        if (array_key_exists($row->$parent_id_key, $flat)) {
            // Assign children by reference so that possible subcategories of
            // this one will appear in the tree structure ($tree)
            $flat[$row->$parent_id_key]['children'][] =& $flat[$row->$id_key];
        }

        if ($row->$parent_id_key == 0) {
            // Assign by reference for synchronizing $flat with $tree;
            $tree[] =& $flat[$row->$id_key];
        }
    }

    return $tree;
}

同样,该功能与数据库的结构分离。 您需要向其传递mysql_query资源,代表id字段的字符串和代表parent_id字段的字符串。 缺点是它与PHP mysql扩展耦合,因为它使用对mysql_fetch_object的调用。 它可能会得到改善。

另一个好处是,它缓存随后的调用结果,除非您告诉它使缓存无效,这是第四个(布尔)参数。

看看它是否对您有帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM