简体   繁体   English

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

[英]PHP Menu - How To Recursively Delete Parent and Child

I am working on a data driven menu system in PHP /MySQL.我正在使用 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.所有顶级菜单项都有一个零 (0) 父 ID 值,表示它们是顶级菜单项。 My gridview displays all menus, top level and sub menu items and it allows multiple selection for delete.我的 gridview 显示所有菜单、顶级和子菜单项,它允许多选删除。

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.问题是,如果在 gridview 中选择删除的项目之一是顶级菜单项,则其下的所有子菜单都将成为孤立的。

What is the general logic I need to implement?我需要实现的一般逻辑是什么?

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.如果您只有 2 个级别的深度,这应该不是什么大问题。 If you can have X levels, then you'll have to recursively delete every child element for every element you delete.如果您可以有 X 个级别,那么您将必须为您删除的每个元素递归删除每个子元素。

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.下面的类将与您可以创建的尽可能多的孩子一起使用(infinit)...所以考虑到您的 mysql 表结构为(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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM