Format my JSON string into an
    ordered list in PHP

后端 未结 5 888
抹茶落季
抹茶落季 2021-01-29 14:48

I\'m working on a simple CMS for a pet project. I currently have a JSON string that contains a list of page ID\'s and Parent page ID\'s for a menu structure.

I want to n

相关标签:
5条回答
  • 2021-01-29 15:04
    <?php
    
    $json_array = array();
    
    array_push($json_array, array(
        'id' => 3,
        'children' => array(
            'id'        =>  4,
            'children'  =>  array(
                    'id'    =>  5,
                )
            )
    ));
    
    array_push($json_array, array('id' => 6));
    array_push($json_array, array('id' => 2));
    array_push($json_array, array('id' => 4));
    
    //your json object
    $json_object = json_encode($json_array);
    //echo $json_object;
    
    //here is where you decode your json object
    $json_object_decoded = json_decode($json_object,true);
    
    //for debug to see how your decoded json object looks as an array
    /*
    echo "<pre>";
        print_r($json_object_decoded);
    echo "</pre>";
    */
    
    echo "<ol>";
    foreach($json_object_decoded as $node){
        if(isset($node['id'])){
            echo "<li>" . $node['id'];
            if(isset($node['children'])){
                    echo "<ol>";
                        echo "<li>" . $node['children']['id'] . "</li>";
                if(isset($node['children'])){
                    echo "<ol>";
                        echo "<li>" . $node['children']['children']['id'] . "</li>";
                    echo "</ol>";
                }
                echo "</ol>";
            }
            echo "</li>";
        }
    }
    echo "</ol>";
    
    
    ?>
    
    0 讨论(0)
  • 2021-01-29 15:09

    You can use recursion to get deep inside the data. If the current value is an array then recursion again. Consider this example:

    $json_string = '[{"id":3,"children":[{"id":4,"children":[{"id":5}]}]},{"id":6},{"id":2},{"id":4}]';
    $array = json_decode($json_string, true);
    
    function build_list($array) {
        $list = '<ol>';
        foreach($array as $key => $value) {
            foreach($value as $key => $index) {
                if(is_array($index)) {
                    $list .= build_list($index);
                } else {
                    $list .= "<li>$index</li>";
                }
            }
        }
    
        $list .= '</ol>';
        return $list;
    }
    
    echo build_list($array);
    
    0 讨论(0)
  • 2021-01-29 15:16

    Using a function that can recursively go through your JSON, you can get the functionality you wish. Consider the following code: (this only accounts for an attribute of id as getting listed, as your desired code shows)

    $json = '[{"id":3,"children":[{"id":4,"children":[{"id":5}]}]},{"id":6},{"id":2},{"id":4}]';
    
    function createOLList($group) {
        $output = (is_array($group)) ? "<ol>" : "";
        foreach($group as $attr => $item) {
            if(is_array($item) || is_object($item)) {
                $output .= createOLList($item);
            } else {
                if($attr == "id") {
                    $output .= "<li>$item</li>";
                }
            }
        }
        $output .= (is_array($group)) ? "</ol>" : "";
        return $output;
    }
    
    print(createOLList(json_decode($json)));
    

    This will produce the following HTML output.

    <ol>
        <li>3</li>
        <ol>
            <li>4</li>
            <ol>
                <li>5</li>
            </ol>
        </ol>
        <li>6</li>
        <li>2</li>
        <li>4</li>
    </ol>
    
    0 讨论(0)
  • 2021-01-29 15:25

    I have found that i have to fix or simplify almost every of the functions above. So here i came with something simple and working, still recursion.

    function build_list($array) {
        $list = '<ul>';
        foreach($array as $key => $value) {
            if (is_array($value)) {
                $list .= "<strong>$key</strong>: " . build_list($value);
            } else {
                $list .= "<li><strong>$key</strong>: $value</li>";
            }
        }
        $list .= '</ul>';
        return $list;
    } 
    build_list(json_encode($json_string),true);
    
    0 讨论(0)
  • 2021-01-29 15:30

    What you're looking for is called recursion, which can be done by a function calling itself.

    If you solved once to list all nodes of the list in one function, you can then apply the same function for all child-lists. As then those child-lists will do the same on their children, too.

    call_user_func(function ($array, $id = 'id', $list = 'children') {
        $ul = function ($array) use (&$ul, $id, $list) {
            echo '<ul>', !array_map(function ($child) use ($ul, $id, $list) {
                echo '<li>', $child[$id], isset($child[$list]) && $ul($child[$list])
                      , '</li>';
            }, $array), '</ul>';
        };
        $ul($array);
    }, json_decode('[{"id":3,"children":[{"id":4,"children":[{"id":5}]}]},{"id":6},
                    {"id":2},{"id":4}]', TRUE));
    

    As this example shows, the $ul function is called recursively over the list and all children. There are other solutions, but most often recursion is a simple method here to get the job done once you've wrapped your head around it.

    Demo: https://eval.in/153471 ; Output (beautified):

    <ul>
      <li>3
        <ul>
          <li>4
            <ul>
              <li>5</li>
            </ul>
          </li>
        </ul>
      </li>
      <li>6</li>
      <li>2</li>
      <li>4</li>
    </ul>
    
    0 讨论(0)
提交回复
热议问题