PHP - 删除空菜单

PHP - Remove empty menus

大家下午好,我很难找到这个简单问题的解决方案,希望有人能帮助我。

我有一个源码自动生成的递归数组,我用这个数组作为系统的菜单树,但是,它经过了一个权限系统,排除了一些子菜单,让某些菜单留空,看例子在 JSON:

{
    "1": {
        "id": 1,
        "idFather": null,
        "nome": "test 1",
        "sub": {
            "4": {
                "id": 4,
                "idFather": 1,
                "nome": "test 1.1",
                "sub": {}
            },
            "5": {
                "id": 5,
                "idFather": 1,
                "nome": "test 1.2",
                "sub": {
                    "7": {
                        "id": 7,
                        "idFather": 5,
                        "nome": "test 1.3.1",
                        "sub": {}
                    },
                    "8": {
                        "id": 8,
                        "idFather": 5,
                        "nome": "test 1.3.2",
                        "sub": {}
                    }
                }
            },
            "6": {
                "id": 6,
                "idFather": 1,
                "nome": "test 1.3"
            }
        }
    },
    "2": {
        "id": 2,
        "idFather": null,
        "nome": "test 2"
    },
    "3": {
        "id": 3,
        "idFather": null,
        "nome": "test 3",
        "sub": {
            "10": {
                "id": 10,
                "idFather": 3,
                "nome": "test 3.2"
            }
        }
    }
}

在密钥 1 中,我有密钥 4,没有其他项目,我有密钥 5,有两个密钥(7 和 8),但是,这 2 个密钥也不包含项目,所以我需要删除密钥 4, 7、8,因此,键 5 也是,因为在删除结束时它将为空! 注意key 1里面的key 6,key 3里面的key 10,key 2里面没有“sub”元素,一定不能去掉!

我是巴西人,所以我的英语可能有点生疏。

一个简单的 recursive function 就可以解决这个问题。

  • 检查当前级别的每个条目。
  • 如果有子菜单,调用子菜单上的函数。如果没有,请继续。
  • 如果子菜单现在是空的,请将其删除

实现如下所示:

$jsonString = "{...}"; // Your data listed above, omitted here for clarity

$menus = json_decode($jsonString);

// Pass a menu into the function. 
// PHP passes objects by reference, so we're operating directly
// on the original object, hence no need for a return value.

function clearMenu(object $menu):void {

    foreach($menu as $id=>$entry) {
        if (isset($entry->sub)) {              // If we have a submenu, handle it
            clearMenu($entry->sub);
            if (empty((array)$entry->sub)) {  // Cast object to array to test for emptiness
                unset($menu->$id);            // Unset the item in the menu using the key. Unsetting the item directly doesn't work
            }
        }
    }
}

clearMenu($menus);

$newMenus = json_encode($menus, JSON_PRETTY_PRINT);
echo "<pre>$newMenus</pre>";

输出:

{
    "1": {
        "id": 1,
        "idFather": null,
        "nome": "test 1",
        "sub": {
            "6": {
                "id": 6,
                "idFather": 1,
                "nome": "test 1.3"
            }
        }
    },
    "2": {
        "id": 2,
        "idFather": null,
        "nome": "test 2"
    },
    "3": {
        "id": 3,
        "idFather": null,
        "nome": "test 3",
        "sub": {
            "10": {
                "id": 10,
                "idFather": 3,
                "nome": "test 3.2"
            }
        }
    }
}