php递归函数使用问题总结

 最近在使用递归函数时,遇到一个问题,先看代码效果再分析

先给一个数组

$arr = array(
    0=>array(
        'cid'=>1,
        'pid'=>0,
        'name'=>'亚洲',
    ),
    1=>array(
        'cid'=>2,
        'pid'=>0,
        'name'=>'北美洲',
    ),
    2=>array(
        'cid'=>3,
        'pid'=>1,
        'name'=>'中国',
    ),
    3=>array(
        'cid'=>4,
        'pid'=>2,
        'name'=>'美国',
    ),
    4=>array(
        'cid'=>5,
        'pid'=>3,
        'name'=>'北京',
    ),
    5=>array(
        'cid'=>6,
        'pid'=>3,
        'name'=>'河北',
    ),
    6=>array(
        'cid'=>7,
        'pid'=>5,
        'name'=>'东城区',
    ),
    7=>array(
        'cid'=>8,
        'pid'=>5,
        'name'=>'海淀区',
    ),
    8=>array(
        'cid'=>9,
        'pid'=>5,
        'name'=>'大兴区',
    ),
);

正确递归方法:

function tree($cate,$pid=0,$level=0,$html="└―"){
    global $list;
    foreach($cate as $v){
        if($v['pid']==$pid){
            $v['html'] = str_repeat($html,$level);
            $list[] = $v;
            tree($cate,$v['cid'],$level+1);
        }
    }
    return $list;
}

$lists = tree($arr);

foreach($lists as $v){
    echo $v['html'].$v['name'].'<br>';
}

显示结果:

亚洲
└―中国
└―└―北京
└―└―└―东城区
└―└―└―海淀区
└―└―└―大兴区
└―└―河北
北美洲
└―美国

 

错误递归方法:

function tree($cate,$pid=0,$level=0,$html="└―"){
    global $list;
    foreach($cate as $v){
        if($v['pid']==$pid){

            /* 问题出在下面两行 */
            $html = str_repeat($html,$level);
            $v['html'] = $html;

            $list[] = $v;
            tree($cate,$v['cid'],$level+1);
        }
    }
    return $list;
}

$lists = tree($arr);

foreach($lists as $v){
    echo $v['html'].$v['name'].'<br>';
}


显示结果:

亚洲
└―中国
└―└―北京
└―└―└―东城区
└―└―└―└―└―└―└―└―└―海淀区
└―└―└―└―└―└―└―└―└―└―└―└―└―└―└―└―└―└―└―└―└―└―└―└―└―└―└―大兴区
└―└―└―└―河北
北美洲
└―美国

个人分析:第二种错误情况是因为中间使用了一个$html中转赋值导致的。 在遍历$arr数组过程中,如果在一个if循环过程中,由于$html赋的值在当前作用域下是一直有效的,所以有多个数据满足$v['pid']==$pid条件时,此时$html是会被累计追加的。只有跳出一个if循环过程后,重新回到foreach循环中时,此时已跳出if中的$html的作用域,数据才被释放,将会重新从初始值开始。

最后做了一个验证:将if循环结构中的$html变量名换成另一个任意名称如$htmls,确保跟递归函数中的$html参数不一致,这样就不存在作用域的问题了,修改后显示结果显示正常。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值