PHP递归数组循环和格式化


PHP Recursive array looping and formatting

我有一些PHP代码已经写了好几天了。我正在尝试从一个平面数组生成一个格式化的规则列表。我之前在这里得到了关于如何将平面数组转换为树数组的帮助,但我很难编写一个递归函数,该函数可以遍历它,并在我希望规则成为打印标记中无序列表的成员的深度处成功地将其分解。

<?php 
$data = array(
    '0'        => 'Introduction',
    '4'        => 'General',
    '4.1'      => 'Chat',
    '4.1.1'    => 'Do',
    '4.1.1.9'  => 'This',
    '4.1.1.10' => 'That',
    '4.1.1.11' => 'Other',
);
$struct = array(
    'children' => array()
);
foreach ($data as $ruleID => $content)
{
    $parent =& $struct;
    foreach (explode('.', $ruleID) as $val)
    {
        if (!isset($parent['children'][$val]))
        {
        $parent['children'][$val] = array(
                'content' => '',
                'children' => array()
            );
        }
        $parent =& $parent['children'][$val];
    }
    $parent['content'] = $content;
}

$out = '';
$rules = array_pop($struct);
format_rule($rules);
var_dump($rules);
echo $out;
function format_rule($arr, $depth=0)
{
    global $out;
    echo "depth: $depth'n";
    foreach($arr as $key => $val)
    {
        switch($depth)
        {
            case 0:
                $out .= '<h1>'.$val['content']."</h1><br />'n";
                break;
            case 1:
                $out .= '<h2>'.$val['content']."</h2><br />'n";
                break;
            case 2:
                $out .= '<h3>'.$val['content']."</h3><br />'n";
                break;
            default:
                $out .= '<li>'.$val['content']."</li>'n";
                break;
        }
        if(isset($val['children']) && count($val['children']) > 0)
        {
            if($depth > 2)
            {
                $out .= '<ul>';
                format_rule($val['children'], ++$depth);
                $out .= '</ul>';
            }
            else
            {
                format_rule($val['children'], ++$depth);
            }
        }
    }
}

目前的输出是:

<h1>Introduction</h1><br />
<h1>General</h1><br />
<h2>Chat</h2><br />
<h3>Do</h3><br />
<li>This</li><br />
<li>That</li><br />
<li>Other</li><br />

这很好,但从我的代码来看,我很确定"Do"下的部分应该有一个<ul>

将代码更改为:

if($depth >= 2)

注意:记住计数从0开始,而不是从1开始。

试试这个:

<?php 
$data = array(
    '0'        => 'Introduction',
    '4'        => 'General',
    '4.1'      => 'Chat',
    '4.1.1'    => 'Do',
    '4.1.1.9'  => 'This',
    '4.1.1.10' => 'That',
    '4.1.1.11' => 'Other',
);
function get_level($key){
    return count(explode(".",$key));
}
function set_tag(&$array,$key,$item,&$ul_started){
    $level = get_level($key);
    switch($level){
        case 1:
        case 2:
        case 3:
            if($ul_started){
                $array[$key] = "</ul><h".$level.">".$item."</h".$level."><br>";
                $ul_started=false;
            }else{
                $array[$key] = "<h".$level.">".$item."</h".$level."><br>";
            }
        break;
        default:
            if(!$ul_started){
                $array[$key] = "<ul><li><strong>".$item."</strong></li><br>";
                $ul_started=true;
            }else{
                $array[$key] = "<li><strong>".$item."</strong></li><br>";
            }
        break;
    }
}
$ul_started = false;
foreach($data as $key=>$item){
    set_tag($data,$key,$item,$ul_started);
}
if($ul_started){
    $keys = array_keys($data);
    $data[$keys[count($data)-1]] .= "</ul>";
}
echo implode("",$data);
?>