解决了!最终答案位于此问题的底部
我正在尝试使用CodeIgniter创建一个菜单构建器,出于某种原因,我似乎无法理解这个概念,即使它看起来很简单(我是PHP和CI的新手).这应该与CodeIgniter本身关系不大,因为我实际上只将它用于查询和MVC模式.
我有两张桌子:
>菜单:
> id
>名字
> menu_pages:
> id
> page_id(与pages.id的关系)
> menu_id(与menus.id的关系)
> item_name(它在菜单中的显示方式)
> item_order(用于排序)
> item_parent(用于在子菜单中嵌套项目)
编辑:这是我想要实现的结构:
array( [0] => array( [menu_id] => 1,[menu_name] => 'Menu 1',[menu_pages] => array( [0] => array( [id] => 1,[page_id] => 1,[menu_id] => 1,[item_name] => 'Home',[item_order] => 0,[item_level] => 0,[parent_id] => '' ),[1] => array( [id] => 2,[page_id] => 2,[item_name] => 'About',[parent_id] => '' ) ) ),[1] => array( [menu_id] => 2,[menu_name] => 'Menu 2',[menu_pages] => array( [0] => array( [id] => 3,[page_id] => 3,[menu_id] => 2,[item_name] => 'Services',[1] => array( [id] => 4,[page_id] => 4,[item_name] => 'Contact',[parent_id] => '' ) ) ) )
这是我到目前为止所做的(更新):
function GetMenus() { $menus = $this->db->get('menus'); $menucols = $this->db->list_fields('menus'); $pages = $this->db->get('menu_pages'); $pagecols = $this->db->list_fields('menu_pages'); $arr = array(); $i = 0; foreach($menus->result() as $menu) { foreach($pages->result() as $page) { foreach($pagecols as $col) { $arr[$i][$col] = $page->$col; } foreach($menucols as $cols) { $this->menus[$i][$cols] = $menu->$cols; if($arr[$i]['menu_id'] === $menu->id) { $this->menus[$i]['menu_pages'] = $arr[$i]; } } } $i++; } return $this->menus; }
以上实际输出:
Array( [0] => Array( [id] => 1,[name] => default,[menu_pages] => Array( Array( /* missing #1,showing #2/2 */ [id] => 2 [page_id] => 1 [menu_id] => 1 [item_name] => About [item_order] => 0 [item_level] => 0 [parent_id] => ) ) ),[1] => Array( [id] => 2,[name] => menu2,[menu_pages] => Array( Array( /* missing #3,showing #4/4 */ [id] => 4 [page_id] => 3 [menu_id] => 2 [item_name] => Contact [item_order] => 0 [item_level] => 0 [parent_id] => ) ) ) )
正如你所看到的,这非常接近我需要的东西,但是有缺少的项目,因为它似乎被覆盖在数组中(它只显示每个菜单的最后一个菜单项 – 似乎它们可能有相同的键).
感谢您提供的任何帮助和建议!
编辑:这是最终的解决方案,松散地基于米沙的答案:
模型:
function GetMenus() { /* Yes,I know these can be chained,I unchained them to avoid horizontal scrolling on SO */ $this->db->select('menus.name,menu_pages.*,pages.slug'); $this->db->join('menu_pages','menu_pages.menu_id = menus.id'); $this->db->join('pages','pages.id = menu_pages.page_id'); $this->db->order_by('item_order','ASC'); $menus = $this->db->get('menus'); $result = array(); foreach($menus->result() as $menu) { $result[$menu->name][$menu->id] = array( 'page_id' => $menu->page_id,'menu_id' => $menu->menu_id,'item_name' => $menu->item_name,'item_slug' => $menu->slug,'item_order' => $menu->item_order,'item_level' => $menu->item_level,'parent_id' => $menu->parent_id ); } return $result; }
控制器:
$this->menu = $this->page->GetMenus();
视图:
<ul class="nav"> <?PHP foreach($this->menu['default'] as $item) { ?> <li> <a href="<?PHP echo $item['item_slug']; ?>"> <?PHP echo $item['item_name']; ?> </a> </li> <?PHP } ?> </ul>
你有两个查询,但我想我会选择一个带连接的查询.这使代码更短,更简单.我没有测试下面的代码,但这样的东西应该工作:
function GetMenus() { $this->db->select('menus.name,menu_pages.*'); $this->db->join('menu_pages','menu_pages.menu_id = menus.id'); $this->db->order_by('menus.id'); $q = $this->db->get('menus'); $result = array(); $current_menu_id = NULL; $i = -1; foreach($q->result() as $row) { if($current_menu_id !== $row->menu_id) { $i++; $result[] = array('menu_id' => $row->menu_id,'menu_name' => $row->name,'menu_pages' => array() ); } $result[$i]['menu_pages'][] = array('id' => $row->id,'page_id' => $row->page_id,'menu_id' => $row->menu_id,'item_name' => $row->item_name,'item_order' => $row->item_order,'item_level' => $row->item_level,'parent_id' => $row->parent_id ); $current_menu_id = $row->menu_id; } return $result; }