PHP递归数组循环和格式化

时间:2012-03-14 21:48:03

标签: php recursion

我有一些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>

2 个答案:

答案 0 :(得分:2)

将您的代码更改为:

if($depth >= 2)

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

答案 1 :(得分:2)

试试这个:

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