PHP/CodeIgniter关系数据库阵列构建

解决了!最终答案位于此问题的底部

我正在尝试使用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;
}

相关文章

Hessian开源的远程通讯,采用二进制 RPC的协议,基于 HTTP 传输。可以实现PHP调用Java,Python,C#等多语...
初识Mongodb的一些总结,在Mac Os X下真实搭建mongodb环境,以及分享个Mongodb管理工具,学习期间一些总结...
边看边操作,这样才能记得牢,实践是检验真理的唯一标准.光看不练假把式,光练不看傻把式,边看边练真把式....
在php中,结果输出一共有两种方式:echo和print,下面将对两种方式做一个比较。 echo与print的区别: (...
在安装好wampServer后,一直没有使用phpMyAdmin,今天用了一下,phpMyAdmin显示错误:The mbstring exte...
变量是用于存储数据的容器,与代数相似,可以给变量赋予某个确定的值(例如:$x=3)或者是赋予其它的变...