Search code examples
phprecursion

How to implement multi-level category recursion function in php?


I'm doing show tree structure like

Level1    level2    level3 ..... level n
   1
   +------1_1
   |         +------1_1_1
   +------1_2
   2 

My data
$data =

Array
(
    [0] => Array
        (
            [IDCategory] => 1
            [IDCategoryParent] => 4
            [Name] => Thị trường trong nước
            [Slug] => thi-truong-trong-nuoc
            [OrderCategory] => 1
            [Description] => Tin tức Thị trường trong nước
            [Status] => 1
        )

    [1] => Array
        (
            [IDCategory] => 3
            [IDCategoryParent] => 3
            [Name] => Thị trường quốc tế
            [Slug] => thi-truong-quoc-te
            [OrderCategory] => 2
            [Description] => Tin tức Thị trường quốc tế
            [Status] => 1
        )

    [2] => Array
        (
            [IDCategory] => 4
            [IDCategoryParent] => 4
            [Name] => Tin tức công ty
            [Slug] => tin-tuc-cong-ty
            [OrderCategory] => 3
            [Description] => Tin tức công ty Tràng An
            [Status] => 1
        )

    [3] => Array
        (
            [IDCategory] => 5
            [IDCategoryParent] => 1
            [Name] => Thực phẩm
            [Slug] => thuc-pham
            [OrderCategory] => 1
            [Description] => Tin tức thực phẩm
            [Status] => 1
        )

)

And this was function that i did.

 public function recursive($parentid = 1, $data = NULL, $char = '') {
        if (isset($data) && is_array($data)) {
            foreach ($data as $key => $item) {
                if ($item['IDCategoryParent'] == $parentid) {
                    $this->recursiveData[$item['IDCategory']] = $item['Name'];
                    $this->recursive($item['IDCategory'], $data, $char);
                    echo $item['IDCategory'];
                }
            }
        }
        return $this->recursiveData;
    }


public function category() {
        $category = new Category();
        $data = $category->selectByStatus(1); // select data from database.

        $recursiveData = $this->recursive(1, $data); // call function 
        return $recursiveData;
    }

But the result just only return 1 value is "Thực Phẩm". I mean my recursive function wrong and I don't know why that is incorrect. Please help me.

[UPDATE]: Now i try again with still this code but

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 65488 bytes)


Solution

  • The problem is that some of your categories have their IDCategoryParent set to their own IDCategory which will cause issues.

    I've changed the ones that reference their own IDCategory as IDCategoryParent to have value 0. Which means they are on level 1.

    Please note that I've just used a simple function in the example code but you can convert it to a class method if you like.

    $data = [
        [
            'IDCategory' => 1,
            'IDCategoryParent' => 4,
            'Name' => 'Thị trường trong nước',
            'Slug' => 'thi-truong-trong-nuoc',
            'OrderCategory' => 1,
            'Description' => 'Tin tức Thị trường trong nước',
            'Status' => 1,
        ],
        [
            'IDCategory' => 3,
            'IDCategoryParent' => 0,
            'Name' => 'Thị trường quốc tế',
            'Slug' => 'thi-truong-quoc-te',
            'OrderCategory' => 2,
            'Description' => 'Tin tức Thị trường quốc tế',
            'Status' => 1,
        ],
        [
            'IDCategory' => 4,
            'IDCategoryParent' => 0,
            'Name' => 'Tin tức công ty',
            'Slug' => 'tin-tuc-cong-ty',
            'OrderCategory' => 3,
            'Description' => 'Tin tức công ty Tràng An',
            'Status' => 1,
        ],
        [
            'IDCategory' => 5,
            'IDCategoryParent' => 1,
            'Name' => 'Thực phẩm',
            'Slug' => 'thuc-pham',
            'OrderCategory' => 1,
            'Description' => 'Tin tức thực phẩm',
            'Status' => 1,
        ]
    ];
    
    function createNested($categories, $parentId = 0)
    {
        $results = [];
        foreach($categories as $category) {
            if ($parentId == $category['IDCategoryParent']) {
                $nextParentId = $category['IDCategory'];
    
                $category['children'] = createNested($categories, $nextParentId);
    
                $results[] = $category;
            }
        }
    
        return $results;
    }
    
    $result = createNested($data);