PHP内存优化生成无限极分类(生成树结构)

PHP大部分人用递归来写生成树,不过PHP默认最多递归次数为100,并不是理论上的无限,其次递归的内存占有过大,php的内存分配是除了对象,其余的为直接copy内存,所以有时候会导致内存占用过大

如以下做法

$items = array(
    array('id' => 1, 'pid' => 0, 'name' => 'a'),
    array('id' => 3, 'pid' => 1, 'name' => 'b'),
    array('id' => 4, 'pid' => 3, 'name' => 'c'),
    array('id' => 5, 'pid' => 1, 'name' => 'd'),
);
function generateTree($items , $pId)
{
    $tree = '';
    foreach($items as $k => $v)
    {
      if($v['pid'] == $pId)
      {     
           $v['pid'] = generateTree($items , $v['id']);
           $tree[] = $v;
      }
    }
    return $tree;
}
$tree = generateTree($items , 0);
  • 改善思路是这样子的,先把每一个人的位置指针,赋值给父亲的son下面,但是他原有的位置依然不变以此类推,结束后只返回pid等于0的,pid等于0的下面的son就存着他子分类的id的指针,指向的区域位置依然不变,内存大小不变。

  • 打个比方,假设每一个人都有一座房子,每个房子的位置铁打不变的(不动产,所以房价那么贵),这些房子是存着上下级的,例如房子1的主人是房子2的主人的爸爸,房子3的主人是房子2的儿子,房子4房子5的主人是房子3的儿子,这样子看上去好像无序一样,但是假设,房子1的主人手上有个族谱($item['son']),上面写着:我有一个儿子,他的房子的门牌号是:×××(&$items_key [$item['id']]),那我们只要找到他,把他return出来,其他的人以此类推都可以找到,而房子是没有发生位置上的变化的,房子的数量也是不变的。

    $items = array(
        array('id' => 1, 'pid' => 0, 'name' => 'a'),
        array('id' => 3, 'pid' => 1, 'name' => 'b'),
        array('id' => 4, 'pid' => 3, 'name' => 'c'),
        array('id' => 5, 'pid' => 1, 'name' => 'd'),
    );
    //先为在数据库查到的数据做索引,实际上取出的数据不可能是key与id对应,这里需要一个for先遍历取id作为key
    foreach($items as &$item_key){
        $items_key[$item_key['id']] = &$item_key;
    }
    function generateTree( &$items_key ){
        //输入变量用引用的方式,减少内存开支
        foreach($items_key as &$item){
            //foreach复制给$item如果下面的等于没有用【&】,内存依然会双倍,无法做到节省内存
            $items_key [$item['pid']]['son'][$item['id']] = &$items_key [$item['id']];
        }
        return isset($items_key [0]['son']) ? $items_key [0]['son'] : array();  
    }
    //假设$items的大小为1M,到最后内存的大小只是略大于1M(增加了指针大小)。
    var_dump(generateTree($items));
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值