使用PHP递归获取子项

时间:2015-01-20 17:12:58

标签: php codeigniter oop

我在MySQL中有一个包含菜单项的表,每个都有一个父表,可以是0(顶层菜单)或另一个项的ID。

我在CodeIgniter中的一个控制器上工作,这个控制器是由另一个程序员启动的,这是他发现以递归方式扫描每个项目的项目的绝佳方式。

// I know there's a better way to do this, but as time is short we have to run
$data['aplicacoes_list'] = '';
$aplicacoes = $this->aplicacoes_model->get_aplicacoes_no_parent();
foreach($aplicacoes as $apl){                
    $data['aplicacoes_list'] .= '<li class="dd-item" data-id="3">
        <div class="dd-handle">'.$apl['nome'].'
            <div class="pull-right"><a href="#" id="'.$apl['nome'].'_'.$apl['id'].'" data-toggle="modal" data-target="#ModalEditarAplicacao" class="dd-nodrag editarAplicacao btn-xs btn-primary"><i class="fa fa-edit"></i><span class="hidden-block hidden-xs hidden-sm"> Editar</span></a>&nbsp;<a href="#" id="'.$apl['nome'].'_'.$apl['id'].'" data-toggle="modal" data-target="#ModalAdicionarSubaplicacao" class="dd-nodrag adicionarSubAplicacao btn-xs btn-success"><i class="fa fa-plus"></i> <span class="hidden-block hidden-xs hidden-sm">Adicionar subcategoria</span></a>&nbsp;<a href="#" data-toggle="modal" data-target="#ModalRemoverAplicacao" id="'.$apl['id'].'" class="dd-nodrag aplicacaoRemover btn-xs btn-danger"><i class="fa fa-trash-o"></i><span class="hidden-block hidden-xs hidden-sm"> Remover</span></a></div>
        </div>
    </li>';
    $sub_aplicacoes = $this->aplicacoes_model->get_aplicacoes_by_parent_id($apl['id']);
    foreach($sub_aplicacoes as $sub_apl){
        $data['aplicacoes_list'] .= '<ol class="dd-list">
        <li class="dd-item" data-id="4">
            <div class="dd-handle">'.$sub_apl['nome'].'
                <div class="pull-right"><a href="#" id="'.$sub_apl['nome'].'_'.$sub_apl['id'].'" data-toggle="modal" data-target="#ModalEditarAplicacao" class="dd-nodrag editarAplicacao btn-xs btn-primary"><i class="fa fa-edit"></i><span class="hidden-block hidden-xs hidden-sm"> Editar</span></a>&nbsp;<a href="#" id="'.$sub_apl['nome'].'_'.$sub_apl['id'].'" data-toggle="modal" data-target="#ModalAdicionarSubaplicacao" class="dd-nodrag adicionarSubAplicacao btn-xs btn-success"><i class="fa fa-plus"></i> <span class="hidden-block hidden-xs hidden-sm">Adicionar subcategoria</span></a>&nbsp;<a href="#" data-toggle="modal" data-target="#ModalRemoverAplicacao" id="'.$sub_apl['id'].'" class="dd-nodrag aplicacaoRemover btn-xs btn-danger"><i class="fa fa-trash-o"></i><span class="hidden-block hidden-xs hidden-sm"> Remover</span></a></div>
            </div>
        </li>';                        
        $sub_aplicacoes2 = $this->aplicacoes_model->get_aplicacoes_by_parent_id($sub_apl['id']);
        foreach($sub_aplicacoes2 as $sub_apl2){    
            $data['aplicacoes_list'] .= '<ol class="dd-list">
            <li class="dd-item" data-id="4">
                <div class="dd-handle">'.$sub_apl2['nome'].'
                    <div class="pull-right"><a href="#" id="'.$sub_apl2['nome'].'_'.$sub_apl2['id'].'" data-toggle="modal" data-target="#ModalEditarAplicacao" class="dd-nodrag editarAplicacao btn-xs btn-primary"><i class="fa fa-edit"></i><span class="hidden-block hidden-xs hidden-sm"> Editar</span></a>&nbsp;<a href="#" id="'.$sub_apl2['nome'].'_'.$sub_apl2['id'].'" data-toggle="modal" data-target="#ModalAdicionarSubaplicacao" class="dd-nodrag adicionarSubAplicacao btn-xs btn-success"><i class="fa fa-plus"></i> <span class="hidden-block hidden-xs hidden-sm">Adicionar subcategoria</span></a>&nbsp;<a href="#" data-toggle="modal" data-target="#ModalRemoverAplicacao" id="'.$sub_apl2['id'].'" class="dd-nodrag aplicacaoRemover btn-xs btn-danger"><i class="fa fa-trash-o"></i><span class="hidden-block hidden-xs hidden-sm"> Remover</span></a></div>
                </div>
            </li>';
        }
    }
}

所以,正如你所看到的,这个列表一直持续到$ sub_aplicacoes7,这只是愚蠢的。

你们能想出更好的方法吗?

Here's a screenshot of the database, as it is.

2 个答案:

答案 0 :(得分:2)

这是一个递归方法:

private function recursive_aplicacoes( $parent = 0 )
{
    $sub_aplicacoes = $this->aplicacoes_model->get_aplicacoes_by_parent_id($parent);

    if(!count($sub_aplicacoes)) return '';

    $s = '<ol class="dd-list">';
    foreach($sub_aplicacoes as $sub_apl)
    {
        $s .= '<li class="dd-item" data-id="4">
                    <div class="dd-handle">'.$sub_apl['nome'].'
                        <div class="pull-right"><a href="#" id="'.$sub_apl['nome'].'_'.$sub_apl['id'].'" data-toggle="modal" data-target="#ModalEditarAplicacao" class="dd-nodrag editarAplicacao btn-xs btn-primary"><i class="fa fa-edit"></i><span class="hidden-block hidden-xs hidden-sm"> Editar</span></a>&nbsp;<a href="#" id="'.$sub_apl['nome'].'_'.$sub_apl['id'].'" data-toggle="modal" data-target="#ModalAdicionarSubaplicacao" class="dd-nodrag adicionarSubAplicacao btn-xs btn-success"><i class="fa fa-plus"></i> <span class="hidden-block hidden-xs hidden-sm">Adicionar subcategoria</span></a>&nbsp;<a href="#" data-toggle="modal" data-target="#ModalRemoverAplicacao" id="'.$sub_apl['id'].'" class="dd-nodrag aplicacaoRemover btn-xs btn-danger"><i class="fa fa-trash-o"></i><span class="hidden-block hidden-xs hidden-sm"> Remover</span></a></div>
                    </div>
                </li>';
        $s .= $this->recursive_aplicacoes($sub_apl['id']);

    }
    $s .= '</ol>';
    return $s;
}

把它放在同一个班级 以下是使用方法:

$data['aplicacoes_list'] = $this->recursive_aplicacoes();

应该工作:)

答案 1 :(得分:0)

您可以将用于生成子菜单的代码移动到其自己的函数中并使用递归。虽然这可以解决您的问题,但我可以建议,一旦您为用户创建了一个缓存它的菜单,直到他/她退出,因为您的菜单系统很快会变得非常复杂并且加载更慢的嵌入式菜单(最终会出现递归N + 1问题)。

$data['aplicacoes_list'] = '';
$aplicacoes = $this->aplicacoes_model->get_aplicacoes_no_parent();

foreach($aplicacoes as $apl){                
    $data['aplicacoes_list'] .= '<li class="dd-item" data-id="3">
        <div class="dd-handle">'.$apl['nome'].'
            <div class="pull-right"><a href="#" id="'.$apl['nome'].'_'.$apl['id'].'" data-toggle="modal" data-target="#ModalEditarAplicacao" class="dd-nodrag editarAplicacao btn-xs btn-primary"><i class="fa fa-edit"></i><span class="hidden-block hidden-xs hidden-sm"> Editar</span></a>&nbsp;<a href="#" id="'.$apl['nome'].'_'.$apl['id'].'" data-toggle="modal" data-target="#ModalAdicionarSubaplicacao" class="dd-nodrag adicionarSubAplicacao btn-xs btn-success"><i class="fa fa-plus"></i> <span class="hidden-block hidden-xs hidden-sm">Adicionar subcategoria</span></a>&nbsp;<a href="#" data-toggle="modal" data-target="#ModalRemoverAplicacao" id="'.$apl['id'].'" class="dd-nodrag aplicacaoRemover btn-xs btn-danger"><i class="fa fa-trash-o"></i><span class="hidden-block hidden-xs hidden-sm"> Remover</span></a></div>
        </div>
    </li>' . build_submenu($this->aplicacoes_model, $apl['id']);
}


function build_submenu($model, $id) {
    $aplicacoes = $model->get_aplicacoes_by_parent_id($id);
    if (empty($aplicacoes)) {
        return '';
    }

    $submenu = '';
    foreach($aplicacoes as $sub){
        $submenu .= '<ol class="dd-list">
        <li class="dd-item" data-id="4">
            <div class="dd-handle">'.$sub['nome'].'
                <div class="pull-right"><a href="#" id="'.$sub['nome'].'_'.$sub['id'].'" data-toggle="modal" data-target="#ModalEditarAplicacao" class="dd-nodrag editarAplicacao btn-xs btn-primary"><i class="fa fa-edit"></i><span class="hidden-block hidden-xs hidden-sm"> Editar</span></a>&nbsp;<a href="#" id="'.$sub['nome'].'_'.$sub['id'].'" data-toggle="modal" data-target="#ModalAdicionarSubaplicacao" class="dd-nodrag adicionarSubAplicacao btn-xs btn-success"><i class="fa fa-plus"></i> <span class="hidden-block hidden-xs hidden-sm">Adicionar subcategoria</span></a>&nbsp;<a href="#" data-toggle="modal" data-target="#ModalRemoverAplicacao" id="'.$sub['id'].'" class="dd-nodrag aplicacaoRemover btn-xs btn-danger"><i class="fa fa-trash-o"></i><span class="hidden-block hidden-xs hidden-sm"> Remover</span></a></div>
            </div>
        </li>' . build_submenu($model, $sub['id']);
    }
    return $submenu;
}

您可能需要摆弄它以获得所需的正确HTML标记/ CSS。