ホームページ  >  に質問  >  本文

PHP无限级分类 代码问题

自己试着写了个无限级分类的,结果有些问题,想了很长时间了,感觉代码没问题呀,可就是结果不正确。现在整个人都懵了....

网上的栗子看了些,貌似写法跟我的不一样。


数组结构如下:

Array
(
    [0] => Array
        (
            [id] => 1
            [name] => 代码
            [parent] => 0
        )

    [1] => Array
        (
            [id] => 3
            [name] => 动漫
            [parent] => 0
        )

    [2] => Array
        (
            [id] => 4
            [name] => 治愈
            [parent] => 3
        )

    [3] => Array
        (
            [id] => 5
            [name] => 励志
            [parent] => 3
        )

    [4] => Array
        (
            [id] => 6
            [name] => 机战
            [parent] => 3
        )

    [5] => Array
        (
            [id] => 7
            [name] => 百合
            [parent] => 3
        )

    [6] => Array
        (
            [id] => 8
            [name] => 资源
            [parent] => 0
        )

    [7] => Array
        (
            [id] => 9
            [name] => app
            [parent] => 8
        )

    [8] => Array
        (
            [id] => 10
            [name] => 软件
            [parent] => 8
        )

    [9] => Array
        (
            [id] => 11
            [name] => 黑科技
            [parent] => 8
        )

)

其中 id 为分类唯一ID, parent 为父类ID
我写的代码 如下:


    function all($id=0){

            static $_class = null;

            if(is_null($_class))
                    $_class = select();  //这个得出来的就是以上的数组结构,然后赋值给了`$_class`变量

            $result = array();
            foreach($_class as $k => $v){
                    if($v['parent'] == $id){
                            unset($_class[$k]);
                            $v = array_merge($v, $this->all($v['id']));
                            $result['child'][] = $v;
                    }
            }

            return $result;

    }

    print_r(all(0));
PHP中文网PHP中文网2772日前422

全員に返信(3)返信します

  • 天蓬老师

    天蓬老师2017-04-10 18:10:15

    鉴于你这个还是用的递归来完成的,我这里提供2个方法,一个是递归的,一个是指针形态的。

    第二个可能您暂时无法理解,但是为帮助您学习,以及方便到他人,以下是代码:

    使用递归

    // 呃,我真不忍心写出这个循环那么多遍的代码,求神解救我。
    
    function _data_to_tree(&$items, $topid = 0, $with_id = TRUE)
    {
        $result = [];
        foreach($items as $v)
            if ($topid == $v['parent'])  {
                $r = $v + ['children' => _data_to_tree($items, $v['id'], $with_id)];
                if ($with_id)
                    $result[$v['id']] = $r;
                else
                    $result[] = $r;
            }
                
        return $result;
    }
    

    使用PHP的指针特性

    function _data_to_tree($items, $topid = 0, $with_id = TRUE)
    {
        if ($with_id)
            foreach ($items as $item)
                $items[ $item['parent'] ]['children'][ $item['id'] ] = &$items[ $item['id'] ];
        else
            foreach ($items as $item)
                    $items[ $item['parent'] ]['children'][] = &$items[ $item['id'] ];
    
             return isset($items[ $topid ]['children']) ? $items[ $topid ][ 'children' ] : [];
    }
    //注意本算法 不会输出 0 的根节点
    //并且数据必须有KEY,并且需要与id相等,也就是如下格式:
    // 1 => ['id' => 1]
    // 2 => ['id' => 2] 

    使用

    传入你的上述数组,比如最顶层的ID为0

    $data = [
      4 => ['id' => 4, 'parent' => 1 , 'text' => 'Parent1'], 
      1 => ['id' => 1, 'parent' => 0 , 'text' => 'Root'],
      2 => ['id' => 2, 'parent' => 1 , 'text' => 'Parent2'], 
      3 => ['id' => 3, 'parent' => 2 , 'text' => 'Sub1'], 
    ];
    print_r ( _data_to_tree($data, 0) );
    
    

    结果

    Array
    (
        [1] => Array
            (
                [id] => 1
                [parent] => 0
                [text] => Root
                [children] => Array
                    (
                        [4] => Array
                            (
                                [id] => 4
                                [parent] => 1
                                [text] => Parent1
                                [children] => Array
                                    (
                                    )
                            )
                        [2] => Array
                            (
                                [id] => 2
                                [parent] => 1
                                [text] => Parent2
                                [children] => Array
                                    (
                                        [3] => Array
                                            (
                                                [id] => 3
                                                [parent] => 2
                                                [text] => Sub1
                                                [children] => Array
                                                    (
                                                    )
                                            )
                                    )
                            )
                    )
            )
    )

    返事
    0
  • PHP中文网

    PHP中文网2017-04-10 18:10:15

    如果是分类的无限级,我一般会多用几个字段对数据组织有帮助。

    一般会有 parantId, child, parantArr, childArr 四个字段。

    parentId 是父级 ID
    child 是判断是否有子级
    parentArr 是父级链
    childArr 是子级群

    给个数据样本

    ID    Parent ID    Child    Parent Array    Child Array
    1     0            1        0               1,2,3,4
    2     1            1        0,1             2,3
    3     2            0        0,1,2           3
    4     1            0        0,1             4
    

    通常我用于地区,分类,菜单等数据。好处么,显而易见的。另外二叉树的无限级也一样。缺点也有,比如更改某个子级到另一个父级时所有相关的父级子级数据更新,开销不算小,不过一般不会频繁改动不是吗?。

    返事
    0
  • ringa_lee

    ringa_lee2017-04-10 18:10:15

    unset($_class[$k]);
    这一行去掉

    返事
    0
  • キャンセル返事