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

发布于 2024-10-07 16:00:03 字数 222 浏览 5 评论 0原文

我正在 PHP /MySQL 中开发数据驱动的菜单系统。我不知道如何删除菜单项而不让其中一些菜单项成为孤立的。

所有顶级菜单项都有零 (0) 父 ID 值,表明它们是顶级菜单项。我的网格视图显示所有菜单、顶级菜单项和子菜单项,并且允许多项选择删除。

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

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

I am working on a data driven menu system in PHP /MySQL. I can't figure out how to delete menu items without leaving some of them orphaned.

All top level menu items have a zero (0) parent id value indicating that they are top level. My gridview displays all menus, top level and sub menu items and it allows multiple selection for delete.

The problem is that if one of the items selected in the gridview for delete is a top level menu item, all sub menus under it will become orphaned.

What is the general logic I need to implement?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

流殇 2024-10-14 16:00:03

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

Simply delete the child items when you delete some item. If you only have a 2 levels of depth this shouldn't be too much of a problem. If you can have X levels, then you'll have to recursively delete every child element for every element you delete.

伤痕我心 2024-10-14 16:00:03

下面的类将与您可以创建的尽可能多的子级一起工作(无限)...所以考虑到您的 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

The below class will work with as many childs as you can create(infinit)... so considering your mysql tabel is structered as(id,parent,name), all you need is a function that gets all items from current level, loop through each item and call recursively the function again to get child items for current loop id, each time keeping the ids found in an array to delete later, below is the full code in which I accomplished it using a class, but it can be done with a global array and function also.

//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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文