解决了!最终答案位于此问题的底部
我正在尝试使用CodeIgniter创建一个菜单构建器,出于某种原因,我似乎无法理解这个概念,即使它看起来很简单(我是PHP和CI的新手)。这应该与CodeIgniter本身关系不大,因为我实际上只将它用于查询和MVC模式。
我有两张桌子:
菜单:
menu_pages:
编辑:这是我希望实现的结构:
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,
[menu_id] => 1,
[item_name] => 'About',
[item_order] => 0,
[item_level] => 0,
[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',
[item_order] => 0,
[item_level] => 0,
[parent_id] => ''
),
[1] => array(
[id] => 4,
[page_id] => 4,
[menu_id] => 2,
[item_name] => 'Contact',
[item_order] => 0,
[item_level] => 0,
[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] =>
)
)
)
)
正如你所看到的,这与我需要的非常接近,但是缺少了项目,因为它们似乎被覆盖在数组中(它只显示每个菜单的最后一个菜单项 - 似乎也许它们有相同的键。)
感谢您提供的所有帮助和建议!
编辑:这是最终解决方案,基于Mischa的答案:
型号:
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>
答案 0 :(得分:3)
试试这个:
function GetMenus() {
$menus = $this->db->get('menus');
$pages = $this->db->get('menu_pages');
$cols = $this->db->list_fields('menu_pages');
foreach($menus->result() as $menu) {
$this->menus[$menu->id] = $menu;
foreach($pages->result() as $page) {
if($page->menu_id === $menu->id) {
foreach($cols as $col) {
$this->menus[$menu->id][$col][] = $page->$col;
}
}
}
}
print_r($this->menus); // for debugging to see result
return $this->menus;
}
答案 1 :(得分:3)
您有两个查询,但我想我会选择一个带连接的查询。这使代码更短,更简单。我没有测试下面的代码,但这样的事情应该有效:
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;
}
答案 2 :(得分:0)
$sql = "
select
id ,
name ,
group_concat(page_id) as page_ids,
group_concat(item_name) as item_name,
group_concat(item_order ) as item_order ,
from menues
left join menu_pages on menu_pages.menu_id = menues .id";
$query = $this->db->query($sql);
return $query->result();
并且完成了对php结尾的单元格的分析
答案 3 :(得分:0)
您可以将$ this-&gt;菜单声明为:
$this->menus = array()
并像这样使用array_push()
函数:
array_push($this->menus,$page->$col);
我还建议在模型中进行连接操作,而不是在函数中循环,因为数据库可以快速完成,代码看起来很优雅。