繁体   English   中英

使用递归PHP函数解析JSON字符串,如何将数据从一项传递到下一项?

[英]Using a recursive PHP function to parse a JSON string, how can I pass data from one item to the next?

更具体地说,我希望将父母的ID传递给孩子,而且,如果孩子有孙子,我需要将孩子的ID传递给孙子……以此类推等等。无限数量的嵌套项(因此使用了递归函数)。

注意:该帖子看起来很长,但主要只是输出数据! 我很确定对此有一个简单的解决方案,但经过数小时的尝试,我无法弄清楚。

到目前为止,我有这个:

<?php
session_start();
$data = '[{"id":13,"content":"This is some content"},{"id":14,"content":"This is some content"},{"id":15,"content":"This is some content","children":[{"id":16,"content":"This is some content"},{"id":17,"content":"This is some content"},{"id":18,"content":"This is some content","children":[{"id":19,"content":"This is some content","children":[{"id":20,"content":"This is some content","children":[{"id":21,"content":"This is some content"},{"id":22,"content":"This is some content"},{"id":23,"content":"This is some content"}]}]}]}]},{"id":24,"content":"This is some content"},{"id":25,"content":"This is some content"}]';
$menu = json_decode($data, true); 
$depth = 0;


function getData($array, $key, $depth) {

    if (!is_array($array)) {
        $depth = $depth/2;
        $depthHolder = $depth;

        if ($key == "id") {
            //I thought maybe I could write something in here to this effect, but was unsuccessful :(   
        }

        while ($depth != 1) {
            echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";            
            $depth--;
        }


        echo $depthHolder . ' - ' . $key . ' : ' . $array . '<br/> ';

    } else {
        $depth++;   
    }


    foreach($array as $key => $v) { 
        getData($v, $key, $depth);
    }


}

getData($menu, '', $depth);
?>

输出以下内容(当前前面的数字仅显示嵌套项目的深度):

1 - id : 13
1 - content : This is some content
1 - id : 14
1 - content : This is some content
1 - id : 15
1 - content : This is some content
        2 - id : 16
        2 - content : This is some content
        2 - id : 17
        2 - content : This is some content
        2 - id : 18
        2 - content : This is some content
                3 - id : 19
                3 - content : This is some content
                        4 - id : 20
                        4 - content : This is some content
                                5 - id : 21
                                5 - content : This is some content
                                5 - id : 22
                                5 - content : This is some content
                                5 - id : 23
                                5 - content : This is some content
1 - id : 24
1 - content : This is some content
1 - id : 25
1 - content : This is some content

我尝试使用会话,但仍然无法弄清楚。 我在寻找什么显示在下面的示例输出中。 您会注意到,这些行前面的ID已更改为显示先前的父ID,并保留它直到显示下一个嵌套项(0代表“无父”)。

0 - id : 13
0 - content : This is some content
0  - id : 14
0 - content : This is some content
0 - id : 15
0 - content : This is some content
        15 - id : 16
        15 - content : This is some content
        15 - id : 17
        15 - content : This is some content
        15 - id : 18
        15 - content : This is some content
                18 - id : 19
                18 - content : This is some content
                        19 - id : 20
                        19 - content : This is some content
                                20 - id : 21
                                20 - content : This is some content
                                20 - id : 22
                                20 - content : This is some content
                                20 - id : 23
                                20 - content : This is some content
0 - id : 24
0 - content : This is some content
0 - id : 25
0 - content : This is some content

抱歉,冗长的帖子! 感谢您的阅读,希望你们中的一位天才能帮助我。 我已经尝试了6个小时来弄清楚这个小问题,我将不胜感激。

也许这种方法会更清晰:

function getData($parentkey,$array,$depth) {
  foreach ($array as $v) {
    print "$depth $parentkey id: {$v['id']}<br>$depth $parentkey content:{$v['content']}<br>";
    if (isset($v['children']))
      getData($v['id'],$v['children'],$depth."&nbsp;&nbsp;");
  }
}
getData(0,$menu,'');

一种方法是:

function print_menu($menu, $key, $depth) {
    $indent_string = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
    foreach ($menu as $value) {
        $this_key = $value['id'];
        echo str_repeat ($indent_string, $depth).$key." - id : ".$value['id']."</br>";
        echo str_repeat ($indent_string, $depth).$key." - content : ".$value['content']."</br>";
        if (is_array($value['children'])) {
            print_menu ($value['children'],$this_key,$depth+1);
        }
    }
}

print_menu ($menu, 0, 0);

如果要生成菜单的HTML,可以使用:

function print_menu_1 ($menu, $key, $depth) {
    $indent_string = "    ";
    echo str_repeat($indent_string,$depth).'<ol class="dd-list">'."\n";
    foreach ($menu as $value) {
        $this_key = $value['id'];
        echo str_repeat($indent_string,$depth+1).'<li class="dd-item" data-id="'.$value['id'].'">'."\n";
        echo str_repeat($indent_string,$depth+2).'<div class="dd-handle">'.$value['content'].' for id #'.$value['id'].'</div>'."\n";
        if (is_array($value['children'])) {
           print_menu_1 ($value['children'],$this_key,$depth+1);
        }
        echo str_repeat($indent_string,$depth+1).'</li>'."\n";
    }
    echo str_repeat($indent_string,$depth).'</ol>'."\n";
}

print_menu_1 ($menu, 0, 0);

请注意,在这种情况下,换行符和$ indent_string仅用于使HTML代码看起来不错。

您可以使用以下代码添加父ID:

function getData($arr, $parent=null) {
    if (is_array($arr)) {
        if (!isset($arr['id'])) {
            foreach ($arr as $key => $item) {
                $arr[$key] = getData($item, $parent);
            }
        } else {
            $id = $arr['id'];
            if ($parent) {
                $arr['parent'] = $parent;
            }
            if (isset($arr['children'])) {
                $arr['children'] = getData($arr['children'], $id);
            }
        }

    }
    return $arr;
}



print_r(getData($menu)); 

也许这可以帮助您前进。

如果您尝试以这种方式构建菜单,则需要修改要返回的数据结构。 例如...

class item {
    public $id;
    public $content;
    public $subsections;
}

然后,只需检查它们在解析函数中是否有任何小节,就可以简单地将它们创建为嵌套的无序列表。

function parse_items($items) {
    $html = '<ul>';

    foreach ($items as &$item) {
        $html .= '<li>' . $item->content . '</li>';

        if (count($item->subsections) > 0) {
            $html .= parse_items($item->subsections);
        }
    }

    $html .= '</ul>'
    return $html;
}

echo parse_items($items);

之后,您可以根据<ul>元素的深度,使用CSS设置菜单的外观样式。 从技术上讲,我知道这是“欺骗”,因为我在整个数据结构的下一个添加了元素数组,但是如果您可以控制元素的返回方式,为什么不让自己变得更轻松呢?

暂无
暂无

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

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