【问题标题】:Store Dynamic Menu data into a json from MySQL Database using PHP使用 PHP 将动态菜单数据从 MySQL 数据库存储到 json 中
【发布时间】:2019-09-14 12:17:56
【问题描述】:

已编辑

我有一个存储动态菜单数据的自引用表,如下所示。

|----|----------------|---------------------|------------| 
|id  |  name          | link                | parent_id  |
|----|----------------|---------------------|------------| 
|1   |  Setup         | NULL                | 0          |
|----|----------------|---------------------|------------| 
|2   |  Common_Setup  | NULL                | 1          |
|----|----------------|---------------------|------------| 
|3   |  Management    | NULL                | 0          |
|----|----------------|---------------------|------------| 
|4   |  Gender        | setup/gender        | 2          |
|----|----------------|---------------------|------------| 
|5   |  Approval      | management/approval | 3          |
|----|----------------|---------------------|------------| 
|6   |  EEE           | eee                 | 0          |
|----|----------------|---------------------|------------|

现在我想将它们作为 json 存储在 PHP(Laravel) 变量中,如下面的结构,

[
   {
       id       : 1,
       title    : 'Setup',
       children : [
           {
               id       : 2,
               title    : 'Common_Setup',
               children : [
                   {
                   }
               ]

           }
       ]
   }
] 

由于子级层没有限制,我认为最好调用递归方法或类似的方法。

function hierarchy($allPage, $parent = 0) {
    foreach ($allPage as $page) {
        if ($page->parent_id === NULL) $page->parent_id = 0;
        if ($page->parent_id === $parent) {
            $children = hierarchy($allPage, $page->id);
        }
    }
}


function getPages()
{
    $allPage = Page::all():
    $dynamicMenu = hierarchy($allPage, 0);
    echo "last: ".$dynamicMenu;
}

在 $dynamicMenu 中,我想存储最终的 JSON 结构。谁能告诉我怎样才能得到这个理想的结构?

【问题讨论】:

  • 您已经提供了一些示例代码:它有什么作用?你被困在哪里了?

标签: php mysql laravel-5


【解决方案1】:

假设您像这样从数据库中获取数据:

$data = Model::all();

$data = DB::table('model')->get();

改成

$data = Model::all()->keyBy('id');

$data = DB::table('model')->get()->keyBy('id');

这样 $data 集合将被数据库中的 id 列索引。

现在您不需要递归函数来构造递归结构。只需要一些简单的循环:

foreach ($data as $item) {
    $item->children = [];
}

$tree = [];

foreach ($data as $item) {
    if ($item->parent_id === 0) {
        $tree[] = $item;
    } else {
        $data[$item->parent_id]->children[] = $item;
    }
}

foreach ($data as $item) {
    unset($item->link, $item->parent_id);
}

echo json_encode($tree, JSON_PRETTY_PRINT);

结果:

[
    {
        "id": 1,
        "name": "Setup",
        "children": [
            {
                "id": 2,
                "name": "Common_Setup",
                "children": [
                    {
                        "id": 4,
                        "name": "Gender",
                        "children": []
                    }
                ]
            }
        ]
    },
    {
        "id": 3,
        "name": "Management",
        "children": [
            {
                "id": 5,
                "name": "Approval",
                "children": []
            }
        ]
    },
    {
        "id": 6,
        "name": "EEE",
        "children": []
    }
]

【讨论】:

  • 返回错误:“ErrorException (E_NOTICE) Undefined offset: 0”
  • @NazemMahmud - 这是因为我使用NULL 而不是0 来确定根节点(if ($item->parent_id === NULL))。现在已经解决了。
  • 我想知道这是怎么发生的,因为我已经使用您问题中的示例数据测试了我的代码。原来,你已经改变了问题。在已经发布了工作答案之后,请不要再这样做了。您应该能够根据答案调整代码。
  • 起初我尝试使用您的代码,但没有更改任何允许 NULL 的内容。收到错误后,我尝试更改字段和新流程。也感谢您的想法:)
【解决方案2】:

你可以试试这个

function hierarchy($parent=NULL) {
    $return=array();
    $return=(array)DB::table('Page')->where('parent_id',$parent)->get();
    for($i=0;$i<count($return);$i++){
        if($return[$i]['parent_id']!=null){
            $return[$i]['childrens']=hierarchy($return[$i]['parent_id']);
        }else{
            $return[$i]['childrens']=array();
        }
    }
    return $return;
}

【讨论】:

  • 它在以下行返回错误:“ErrorException (E_NOTICE) Undefined offset: 0”:if($return[$i]['parent_id']!=null){
  • parent_id 在您的表中是 nullempty 值。我认为 parent_id 值在表中存储为空。 function hierarchy($parent="") { $return=array(); $return=(array)DB::table('Page')-&gt;where('parent_id',$parent)-&gt;get(); for($i=0;$i&lt;count($return);$i++){ if($return[$i]['parent_id']!=null){ $return[$i]['childrens']=hierarchy($return[$i]['parent_id']); }else{ $return[$i]['childrens']=array(); } } return $return; }
  • 我已经更新了 parent_id 列并将 NULL 替换为 0。我已经为此编辑了问题。我也已经解决了它,并在此处提供了答案。您也可以查看该解决方案。谢谢:)
【解决方案3】:

已解决: 我通过以下方式解决了它:

function getMenuTreee($arrayForPages, $parent = 0)
{
    $menuTree = [];
    foreach ($arrayForPages[$parent] as $page) {

        $newMenu = new \stdClass();
        $newMenu->id = $page['id'];
        $newMenu->title = $page['name'];
        $newMenu->url = $page['link'];
        // check if there are children for this item
        if (isset($arrayForPages[$page['id']])) {
            $newMenu->children = $this->getMenuTreee($arrayForPages, $page['id']); // and here we use this nested function recursively
        }
        $menuTree[] = $newMenu;
    }
    return $menuTree;
}



function getPagess(Request $request)
{
    $arrayForPages = [];
    $allPage = Page::all();

    foreach ($allPage as $page)
        $arrayForPages [$page->parent_id][] = $page;

    $dynamicMenu = $this->getMenuTreee($arrayForPages);
    return $dynamicMenu;

}

感谢谁发布了自己的答案 :) 这些帮助我找到了这个解决方案

【讨论】:

    猜你喜欢
    • 2023-03-05
    • 2018-02-16
    • 2013-03-11
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 2015-06-23
    • 2013-06-03
    • 1970-01-01
    相关资源
    最近更新 更多