Отформатируйте мою строку JSON в упорядоченный список <ol> в PHP

Я работаю над простой CMS для проекта для домашних животных. В настоящее время у меня есть строка JSON, которая содержит список идентификаторов страниц и идентификаторов родительских страниц для структуры меню.

Я хочу преобразовать эту строку во вложенный или иерархический список (упорядоченный список).

Я пробовал просматривать петлю, но, похоже, закончил слишком сложный набор подклассов. Я изо всех сил стараюсь найти подходящее легкое решение на PHP.

Вот JSON:

**[{"id":3,"children":[{"id":4,"children":[{"id":5}]}]},{"id":6},{"id":2},{"id":4}]** 

Вот нужный результат:

 <ol> <li>3 <ol> <li>4</li> <ol> <li>5</li> </ol> </ol> </li> <li>6</li> <li>2</li> <li>4</li> </ol> 

Есть ли что-нибудь встроенное в PHP, которое может упростить этот процесс? У кого-нибудь был опыт этого раньше?

Я новичок в PHP и SE. С нетерпением жду Вашего ответа.

Вот мой текущий прогресс (он не работает слишком хорошо)

 <ol> <?php $json = '[{"id":3,"children":[{"id":4,"children":[{"id":5}]}]},{"id":6},{"id":2},{"id":4}]'; $decoded = json_decode($json); $pages = $decoded; foreach($pages as $page){ $subpages = $decoded->children; echo "<li>".$page->id."</li>"; foreach($subpages as $subpage){ echo "<li>".$subpage->id."</li>"; } } ?> </ol> 

Вы можете использовать рекурсию, чтобы проникать глубоко внутри данных. Если текущее значение является массивом, то рекурсия снова. Рассмотрим этот пример:

 $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); 

Используя функцию, которая может рекурсивно проходить через JSON, вы можете получить необходимую функциональность. Рассмотрим следующий код: (это учитывает только атрибут id как получаемый, как показывает ваш желаемый код)

 $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))); 

Это приведет к следующему выходу HTML.

 <ol> <li>3</li> <ol> <li>4</li> <ol> <li>5</li> </ol> </ol> <li>6</li> <li>2</li> <li>4</li> </ol> 

То, что вы ищете, называется рекурсией, что может выполняться функцией, вызывающей себя.

Если вы решили один раз перечислить все узлы списка в одной функции, вы можете применить одну и ту же функцию для всех дочерних списков. Как тогда эти детские списки будут делать то же самое на своих детях.

 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)); 

Как показано в этом примере, функция $ul называется рекурсивно над списком и всеми дочерними элементами. Существуют и другие решения, но чаще всего рекурсия – это простой метод, чтобы выполнить эту работу, как только вы обернули ее вокруг.

Демо: https://eval.in/153471 ; Выход (украшенный):

 <ul> <li>3 <ul> <li>4 <ul> <li>5</li> </ul> </li> </ul> </li> <li>6</li> <li>2</li> <li>4</li> </ul> 
 <?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>"; ?>