如何获取平面 JSON 文件并使用 PHP 构建分层菜单
How to take a flat JSON file and build a hierarchical menu using PHP
我有一个包含菜单列表 link 的数据库。每个菜单 link 在字段 'menu_pages_id' 中都有一个 ID。
在数据库中有一个字段“subPageOf”,说明它的父项是什么。还有三种不同的菜单link,定义在字段“menuType”
中
我已将此列表输出到一个平面 JSON 文件中,并希望重建层次结构。
$jsonMenu = json_decode($jsonMenu);
foreach ($jsonMenu as $pageInfo ) {
$pageUrl = $pageInfo->pageUrl;
$menuPageName = $pageInfo->pageName;
$menuType = $pageInfo->menuType;
$subPageOf = $pageInfo->subPageOf;
$menu_pages_id = $pageInfo->menu_pages_id;
if( $menuType == 'header' && $subPageOf == '0' ){
$headerMenu .= "<a href='$pageUrl'>$menuPageName</a>";
}
if( $menuType == 'category' && $subPageOf == '0'){
$categoryMenu .= "<li><a href='$pageUrl'>$menuPageName</a></li>";
}
if( $menuType == 'footer' && $subPageOf == '0' ){
$footerMenu .= "<a href='$pageUrl'>$menuPageName</a>";
}
}
$categoryMenu = '<ul>'.$categoryMenu.'</ul>';
echo $headerMenu
echo $categoryMenu
echo $footerMenu
这当然会输出第一级...但是如何将子页面嵌套到类别菜单的父级的
中。
我可以在
元素中放置另一个完整的 foreach 循环,然后 运行 它再次过滤父 ID。但这意味着我必须对要搜索的深度进行硬编码,而且看起来有很多额外的代码。我希望有一个更优雅的解决方案。
这是一个例子Json菜单
[{"menu_pages_id":"77","menu_id":"1","page_id":"1","listOrder":"0","subPageOf":"0","pageName":"Home","pageUrl":"home","pageType":"system","isProtected":"1","customerGroup":"1001","menuName":"Header Menu","menuType":"header","assignedGroup_id":"1","menuStatus":"Active"},{"menu_pages_id":"78","menu_id":"1","page_id":"14","listOrder":"0","subPageOf":"0","pageName":"About Us","pageUrl":"aboutus","pageType":"content","isProtected":"0","customerGroup":"1001","menuName":"Header Menu","menuType":"header","assignedGroup_id":"1","menuStatus":"Active"},{"menu_pages_id":"80","menu_id":"1","page_id":"6","listOrder":"0","subPageOf":"0","pageName":"Register","pageUrl":"register","pageType":"system","isProtected":"1","customerGroup":"1004","menuName":"Header Menu","menuType":"header","assignedGroup_id":"1","menuStatus":"Active"},{"menu_pages_id":"81","menu_id":"1","page_id":"7","listOrder":"0","subPageOf":"0","pageName":"Your Account","pageUrl":"account","pageType":"system","isProtected":"1","customerGroup":"1003","menuName":"Header Menu","menuType":"header","assignedGroup_id":"1","menuStatus":"Active"},{"menu_pages_id":"82","menu_id":"1","page_id":"9","listOrder":"0","subPageOf":"0","pageName":"Logout","pageUrl":"logout","pageType":"system","isProtected":"1","customerGroup":"1003","menuName":"Header Menu","menuType":"header","assignedGroup_id":"1","menuStatus":"Active"},{"menu_pages_id":"83","menu_id":"2","page_id":"15","listOrder":"0","subPageOf":"0","pageName":"Terms and Conditions","pageUrl":"terms-and-conditions","pageType":"content","isProtected":"0","customerGroup":"1001","menuName":"Footer","menuType":"footer","assignedGroup_id":"1","menuStatus":"Active"},{"menu_pages_id":"84","menu_id":"2","page_id":"44","listOrder":"0","subPageOf":"0","pageName":"Wholesale","pageUrl":"wholesale","pageType":"content","isProtected":"0","customerGroup":"1005, 1007","menuName":"Footer","menuType":"footer","assignedGroup_id":"1","menuStatus":"Active"},{"menu_pages_id":"97","menu_id":"24","page_id":"1","listOrder":"0","subPageOf":"0","pageName":"Home","pageUrl":"home","pageType":"system","isProtected":"1","customerGroup":"1001","menuName":"Test Menu","menuType":"category","assignedGroup_id":"3","menuStatus":"Active"},{"menu_pages_id":"98","menu_id":"24","page_id":"14","listOrder":"0","subPageOf":"0","pageName":"About Us","pageUrl":"aboutus","pageType":"content","isProtected":"0","customerGroup":"1001","menuName":"Test Menu","menuType":"category","assignedGroup_id":"3","menuStatus":"Active"},{"menu_pages_id":"99","menu_id":"24","page_id":"5","listOrder":"0","subPageOf":"97","pageName":"Login","pageUrl":"login","pageType":"system","isProtected":"1","customerGroup":"1004","menuName":"Test Menu","menuType":"category","assignedGroup_id":"3","menuStatus":"Active"},{"menu_pages_id":"100","menu_id":"24","page_id":"3","listOrder":"0","subPageOf":"99","pageName":"Support","pageUrl":"support","pageType":"system","isProtected":"1","customerGroup":"1001","menuName":"Test Menu","menuType":"category","assignedGroup_id":"3","menuStatus":"Active"},{"menu_pages_id":"101","menu_id":"24","page_id":"15","listOrder":"0","subPageOf":"0","pageName":"Terms and Conditions","pageUrl":"terms-and-conditions","pageType":"content","isProtected":"0","customerGroup":"1001","menuName":"Test Menu","menuType":"category","assignedGroup_id":"3","menuStatus":"Active"},{"menu_pages_id":"79","menu_id":"1","page_id":"5","listOrder":"3","subPageOf":"0","pageName":"Login","pageUrl":"login","pageType":"system","isProtected":"1","customerGroup":"1004","menuName":"Header Menu","menuType":"header","assignedGroup_id":"1","menuStatus":"Active"},{"menu_pages_id":"96","menu_id":"1","page_id":"44","listOrder":"8","subPageOf":"0","pageName":"Wholesale","pageUrl":"wholesale","pageType":"content","isProtected":"0","customerGroup":"1005, 1007","menuName":"Header Menu","menuType":"header","assignedGroup_id":"1","menuStatus":"Active"}]
我认为应该使用递归。基于下面粗略示例的一些代码应该可以工作:
$menus = "your flat menu array";
function getNestedMenu($menus,$subPageOf){
$nestedMenus = array();
foreach($menus as $menu){
if($menu['subPageOf'] = $subPageOf){
$nestedMenu = $menu;
$nestedMenu['subPages'] = getNestedMenu($menus,$menu['page_id']);
$nestedMenus[] = $nestedMenu;
}
}
return $nestedMenus;
}
$myNestedMenus = getNestedMenu($menu,"0");
使用上面的代码,您还可以调整它以制作基于 ul li
的嵌套菜单 html
代码
根据 Kewlashu 所说的,我能够使用以下方法使其工作。
$jsonMenu = json_decode($menus);
function makeMenu($jsonMenu,$parentId) {
$menu .= "<ul>";
foreach ($jsonMenu as $pageInfo ) {
$menuCustomerGroup = $pageInfo->customerGroup;
$pageUrl = $pageInfo->pageUrl;
$menuPageName = $pageInfo->pageName;
$menuType = $pageInfo->menuType;
$subPageOf = $pageInfo->subPageOf;
$menu_pages_id = $pageInfo->menu_pages_id;
if($menuType == 'category' && $subPageOf == $parentId){
$menu .= "<li><a href='$pageUrl'>$menuPageName</a>".makeMenu($jsonMenu,$menu_pages_id)."</li>";
}
}
$menu .= "</ul>";
return $menu;
}
$menu = makeMenu($jsonMenu,0);
$menu = str_replace("<ul></ul>",'', $menu);
echo $menu;
这个解决方案在每个子菜单的底部留下了空的
元素,所以我在输出之前使用字符串替换来删除它们。
我有一个包含菜单列表 link 的数据库。每个菜单 link 在字段 'menu_pages_id' 中都有一个 ID。
在数据库中有一个字段“subPageOf”,说明它的父项是什么。还有三种不同的菜单link,定义在字段“menuType”
中我已将此列表输出到一个平面 JSON 文件中,并希望重建层次结构。
$jsonMenu = json_decode($jsonMenu);
foreach ($jsonMenu as $pageInfo ) {
$pageUrl = $pageInfo->pageUrl;
$menuPageName = $pageInfo->pageName;
$menuType = $pageInfo->menuType;
$subPageOf = $pageInfo->subPageOf;
$menu_pages_id = $pageInfo->menu_pages_id;
if( $menuType == 'header' && $subPageOf == '0' ){
$headerMenu .= "<a href='$pageUrl'>$menuPageName</a>";
}
if( $menuType == 'category' && $subPageOf == '0'){
$categoryMenu .= "<li><a href='$pageUrl'>$menuPageName</a></li>";
}
if( $menuType == 'footer' && $subPageOf == '0' ){
$footerMenu .= "<a href='$pageUrl'>$menuPageName</a>";
}
}
$categoryMenu = '<ul>'.$categoryMenu.'</ul>';
echo $headerMenu
echo $categoryMenu
echo $footerMenu
这当然会输出第一级...但是如何将子页面嵌套到类别菜单的父级的
我可以在
这是一个例子Json菜单
[{"menu_pages_id":"77","menu_id":"1","page_id":"1","listOrder":"0","subPageOf":"0","pageName":"Home","pageUrl":"home","pageType":"system","isProtected":"1","customerGroup":"1001","menuName":"Header Menu","menuType":"header","assignedGroup_id":"1","menuStatus":"Active"},{"menu_pages_id":"78","menu_id":"1","page_id":"14","listOrder":"0","subPageOf":"0","pageName":"About Us","pageUrl":"aboutus","pageType":"content","isProtected":"0","customerGroup":"1001","menuName":"Header Menu","menuType":"header","assignedGroup_id":"1","menuStatus":"Active"},{"menu_pages_id":"80","menu_id":"1","page_id":"6","listOrder":"0","subPageOf":"0","pageName":"Register","pageUrl":"register","pageType":"system","isProtected":"1","customerGroup":"1004","menuName":"Header Menu","menuType":"header","assignedGroup_id":"1","menuStatus":"Active"},{"menu_pages_id":"81","menu_id":"1","page_id":"7","listOrder":"0","subPageOf":"0","pageName":"Your Account","pageUrl":"account","pageType":"system","isProtected":"1","customerGroup":"1003","menuName":"Header Menu","menuType":"header","assignedGroup_id":"1","menuStatus":"Active"},{"menu_pages_id":"82","menu_id":"1","page_id":"9","listOrder":"0","subPageOf":"0","pageName":"Logout","pageUrl":"logout","pageType":"system","isProtected":"1","customerGroup":"1003","menuName":"Header Menu","menuType":"header","assignedGroup_id":"1","menuStatus":"Active"},{"menu_pages_id":"83","menu_id":"2","page_id":"15","listOrder":"0","subPageOf":"0","pageName":"Terms and Conditions","pageUrl":"terms-and-conditions","pageType":"content","isProtected":"0","customerGroup":"1001","menuName":"Footer","menuType":"footer","assignedGroup_id":"1","menuStatus":"Active"},{"menu_pages_id":"84","menu_id":"2","page_id":"44","listOrder":"0","subPageOf":"0","pageName":"Wholesale","pageUrl":"wholesale","pageType":"content","isProtected":"0","customerGroup":"1005, 1007","menuName":"Footer","menuType":"footer","assignedGroup_id":"1","menuStatus":"Active"},{"menu_pages_id":"97","menu_id":"24","page_id":"1","listOrder":"0","subPageOf":"0","pageName":"Home","pageUrl":"home","pageType":"system","isProtected":"1","customerGroup":"1001","menuName":"Test Menu","menuType":"category","assignedGroup_id":"3","menuStatus":"Active"},{"menu_pages_id":"98","menu_id":"24","page_id":"14","listOrder":"0","subPageOf":"0","pageName":"About Us","pageUrl":"aboutus","pageType":"content","isProtected":"0","customerGroup":"1001","menuName":"Test Menu","menuType":"category","assignedGroup_id":"3","menuStatus":"Active"},{"menu_pages_id":"99","menu_id":"24","page_id":"5","listOrder":"0","subPageOf":"97","pageName":"Login","pageUrl":"login","pageType":"system","isProtected":"1","customerGroup":"1004","menuName":"Test Menu","menuType":"category","assignedGroup_id":"3","menuStatus":"Active"},{"menu_pages_id":"100","menu_id":"24","page_id":"3","listOrder":"0","subPageOf":"99","pageName":"Support","pageUrl":"support","pageType":"system","isProtected":"1","customerGroup":"1001","menuName":"Test Menu","menuType":"category","assignedGroup_id":"3","menuStatus":"Active"},{"menu_pages_id":"101","menu_id":"24","page_id":"15","listOrder":"0","subPageOf":"0","pageName":"Terms and Conditions","pageUrl":"terms-and-conditions","pageType":"content","isProtected":"0","customerGroup":"1001","menuName":"Test Menu","menuType":"category","assignedGroup_id":"3","menuStatus":"Active"},{"menu_pages_id":"79","menu_id":"1","page_id":"5","listOrder":"3","subPageOf":"0","pageName":"Login","pageUrl":"login","pageType":"system","isProtected":"1","customerGroup":"1004","menuName":"Header Menu","menuType":"header","assignedGroup_id":"1","menuStatus":"Active"},{"menu_pages_id":"96","menu_id":"1","page_id":"44","listOrder":"8","subPageOf":"0","pageName":"Wholesale","pageUrl":"wholesale","pageType":"content","isProtected":"0","customerGroup":"1005, 1007","menuName":"Header Menu","menuType":"header","assignedGroup_id":"1","menuStatus":"Active"}]
我认为应该使用递归。基于下面粗略示例的一些代码应该可以工作:
$menus = "your flat menu array";
function getNestedMenu($menus,$subPageOf){
$nestedMenus = array();
foreach($menus as $menu){
if($menu['subPageOf'] = $subPageOf){
$nestedMenu = $menu;
$nestedMenu['subPages'] = getNestedMenu($menus,$menu['page_id']);
$nestedMenus[] = $nestedMenu;
}
}
return $nestedMenus;
}
$myNestedMenus = getNestedMenu($menu,"0");
使用上面的代码,您还可以调整它以制作基于 ul li
的嵌套菜单 html
代码
根据 Kewlashu 所说的,我能够使用以下方法使其工作。
$jsonMenu = json_decode($menus);
function makeMenu($jsonMenu,$parentId) {
$menu .= "<ul>";
foreach ($jsonMenu as $pageInfo ) {
$menuCustomerGroup = $pageInfo->customerGroup;
$pageUrl = $pageInfo->pageUrl;
$menuPageName = $pageInfo->pageName;
$menuType = $pageInfo->menuType;
$subPageOf = $pageInfo->subPageOf;
$menu_pages_id = $pageInfo->menu_pages_id;
if($menuType == 'category' && $subPageOf == $parentId){
$menu .= "<li><a href='$pageUrl'>$menuPageName</a>".makeMenu($jsonMenu,$menu_pages_id)."</li>";
}
}
$menu .= "</ul>";
return $menu;
}
$menu = makeMenu($jsonMenu,0);
$menu = str_replace("<ul></ul>",'', $menu);
echo $menu;
这个解决方案在每个子菜单的底部留下了空的