简体   繁体   English

php嵌套集,在导航菜单中建立链接

[英]php nested set, building links in navigation menu

I have a few categories in my database which I am retrieving using nested set model something like this(number in brackets represent depth): 我的数据库中有一些类别,我正在使用类似这样的嵌套集模型来检索(括号中的数字代表深度):

New(1) 新增(1)
-General(2) -一般(2)
-Console(2) -控制台(2)

Games(1) 游戏(1)
-pc(2) -个(2)
--emulator(3) -模拟器(3)
-ps3(2) -ps3(2)

I then have a function to handle the multidimensional array and generate the navigation menu 然后,我有一个函数来处理多维数组并生成导航菜单

--the model - 该模型
this returns the following array from database 这将从数据库返回以下数组

Array (
    [0] => Array ( [name] => News [depth] => 1 ) 
    [1] => Array ( [name] => General [depth] => 2 ) 
    [2] => Array ( [name] => Console [depth] => 2 ) 
    [4] => Array ( [name] => Games [depth] => 1 ) 
    [5] => Array ( [name] => PC [depth] => 2 ) 
    [6] => Array ( [name] => emulator [depth] => 3 ) 
    [8] => Array ( [name] => ps3 [depth] => 2 ) 
) 

--the controller -控制器

public function index()
{
$navTree = $this->getNavTree(); //gets array from model
$createNavTree = $this->_renderTree($navTree); //pass array to function
$this->load->view('testnavigation.php', $createNavTree);
}


function _renderTree($tree){    
    $current_depth = 0;
    $counter = 0;

    $result = '';

    foreach($tree as $node){
        $node_depth = $node['depth'];
        $node_name = $node['name'];
        $node_id = $node['categoryid'];

        if($node_depth == $current_depth){
            if($counter > 0) $result .= '</li>';            
        }
        elseif($node_depth > $current_depth){

            $result .= $counter == 0 ? '<ul id="nav">' : '<ul>';
            $current_depth = $current_depth + ($node_depth - $current_depth);
        }
        elseif($node_depth < $current_depth){
            $result .= str_repeat('</li></ul>',$current_depth - $node_depth).'</li>';
            $current_depth = $current_depth - ($current_depth - $node_depth);
        }
        $result .= '<li><a href="#">'.$node_name.'</a>';
        ++$counter;
    }
    $result .= str_repeat('</li></ul>',$node_depth).'</li>';
    $result .= '</ul>';     
    return $result;
}

--view - 视图

echo $createNavTree;

The list is created in the correct indented order, the issue I am having however is generating the links for each item for instance the link for emulator should be mysite.com/games/pc/emulator 该列表以正确的缩进顺序创建,但是我遇到的问题是为每个项目生成链接,例如,仿真器的链接应为mysite.com/games/pc/emulator

How would I go about achieving this, any help be appreciated thanks? 我将如何实现这一目标,感谢您的帮助?

I would take the easy-route and build an array of cache-levels and previously-computed paths for each level. 我会选择简单的方法,并为每个级别构建一个缓存级别数组和先前计算的路径。 When the "base-level" of 1 is seen again, clear the cache so that you don't have any invalid entries: 当再次看到“基本级别” 1时,请清除缓存,以使您没有任何无效的条目:

This sample code should work with what you currently have (just place this code in above your current layout-rendering code and use $path as the URL): 此示例代码应能与您当前使用的代码一起工作(只需将此代码放在当前的布局渲染代码上方,并使用$path作为URL):

function _renderTree($tree) {
    $depths = array();
    foreach ($tree as $node) {
        // build the current path
        $path = (($node['depth'] > 1) ? $depths[$node['depth'] - 1] : '') . $node['name'];

        // set the current path as the current depth's path (to be used for any deeper-nodes)
        $depths[$node['depth']] = $path . '/';

        ... layout rendering code ...
    }
}

What it does is, if the current path's depth is higher than 1 (which means that there is a parent depth), it will take the computed path for the parent (which should be full path for the parent, not just the parent's name), and then adds the current name to it - this will give you the full nested path. 它的作用是,如果当前路径的depth大于1(这意味着存在父级深度),它将采用父级的计算路径(该路径应该是父级的完整路径,而不仅仅是父级的名称) ,然后在其中添加当前名称-这将为您提供完整的嵌套路径。 Then, it stores that generated path into the $depths array (indexed with the current depth) for any children to use. 然后,它将生成的路径存储到$depths数组(以当前深度索引)中,以供任何子代使用。

In your sample, you specify you want the path for Emulator to be mysite.com/games/pc/emulator , emphasis on the lower-case and the domain name. 在示例中,您指定希望Emulator的路径为mysite.com/games/pc/emulator ,重点是小写字母和域名。 Since we're using the $node['name'] in our path, you'll want to use strtolower() : 由于我们在路径中使用$node['name'] ,因此您需要使用strtolower()

$path = (($node['depth'] > 1) ? $depths[$node['depth'] - 1] : '') . strtolower($node['name']);

I would suggest adding the domain-name in the actual line for the <a></a> tags: 我建议在<a></a>标签的实际行中添加域名:

$result .= '<li><a href="http://mysite.com/' . $path . '">'.$node_name.'</a>';

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

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