PHP菜单 - 如何递归删除父和子

时间:2010-12-15 22:51:23

标签: php menu data-driven

我正在研究PHP / MySQL中的数据驱动菜单系统。我无法弄清楚如何删除菜单项而不留下一些孤儿。

所有顶级菜单项都有一个零(0)父ID值,表示它们是顶级。我的gridview显示所有菜单,顶级和子菜单项,并允许多次选择删除。

问题是,如果在gridview中选择要删除的项目之一是顶级菜单项,则其下的所有子菜单都将变为孤立。

我需要实施的一般逻辑是什么?

2 个答案:

答案 0 :(得分:1)

删除某个项目时,只需删除子项目即可。如果你只有2级深度,这不应该是一个太大的问题。如果你可以有X级别,那么你必须递归删除你删除的每个元素的每个子元素。

答案 1 :(得分:0)

下面的类将与您创建(infinit)的子类一起使用...因此,考虑到您的mysql tabel被构造为(id,parent,name),您所需要的只是一个从当前获取所有项的函数级别,遍历每个项目,然后再次递归调用该函数以获取当前循环ID的子项目,每次保留在数组中找到的ID以便以后删除,下面是我使用类完成的完整代码,但这可以使用全局数组和函数来完成。

//full class below comprising of 2 methods(functions)  
class menu_manager{

    //this is the function called with id, to initiate the recursive function below
    private function remove_menu_item($id){
        $ids_to_delete ="";
        //Zero global arrays for more than one call for this function get child menus id first in a an array
        $this->child_items_ids = array(0 => $id);
        $this->incrementby_one=0;
        //call recursive function with $id provided
        $this->get_array_of_child_ids($id); 
        //then createw ids for mysql IN Statment, foreach will create - 1,10,25,65,32,45,
        foreach($this->child_items_ids as $k=>$v ) $ids_to_delete.=$v.",";
        //Then we wrap it in around "(" and ")" and remove last coma to provide - (1,10,25,65,32,45)
        $ids_to_delete="(".substr($ids_to_delete, 0, -1).")";
        //then we Delete all id in one query only
        $remove = $this->db->query("DELETE FROM menu WHERE id IN $ids_to_delete ");
        if(!$remove) return false;
        else return true;
    } 

    /*this is the function that will be called as many times as a child is found,
this function is called inside of itself in the query loop*/ 

    private function get_array_of_child_ids($id){
        $query = $this->db->query("SELECT id,label,parent FROM menu WHERE parent='".$id."' ");
        if($query){
            if($query->num_rows > 0) { // if found any items
                while($list = $query->fetch_assoc()){ // we loop through each item
                    //increments array index by 1
                    $this->incrementby_one += 1;
                    //place current id in the array
                    $this->child_items_ids[$this->incrementby_one] = intval($list["id"]);
                    //and we call this function again for the current id
                    $this->get_array_of_child_ids($list["id"]);
                } // while closing
            } // second if closing
        }  //first if closing  
    }   // recursive function closing
}   // class closing

//to call the class you need:
$delete_items = new menu_manager;
$delete_items->remove_menu_item($id); //$id is the id for the item to be removed