树菜单数组的递归函数

时间:2016-12-23 08:30:05

标签: php arrays symfony recursion recursive-datastructures

请我有2级菜单的功能......但我不知道如何使用3级。你能帮我吗 ?示例数组

  [/c300112000-zvire] => Array
    (
        [/c300112001-pes] => Array
            (
                [0] => /c300112005-antiparazitni-pripravky
                [1] => /c300112002-granulovana-krmiva
                [2] => /c300112009-hracky-misky-a-ostatni
                [3] => /c300112003-konzervy-a-kapsicky
                [4] => /c300112004-pamlsky-a-doplnky-stravy
                [5] => /c300112008-psi-hygiena-a-zdravi
            )

        [/c300112010-kocka] => Array
            (
                [0] => /c300112015-antiparazitni-pripravky
                [1] => /c300112011-granulovana-krmiva
                [2] => /c300112017-hracky-a-misky
                [3] => /c300112016-kocici-hygiena-a-zdravi
                [4] => /c300112012-konzervy-a-kapsicky
                [5] => /c300112013-pamlsky-a-doplnky-stravy
                [6] => /c300112014-podestylky
            )

        [/c300112018-mala-zvirata] => Array
            (
                [0] => /c300112019-krmiva
                [1] => /c300112020-steliva
            )

        [/c300112021-ptactvo] => Array
            (
                [0] => /c300112022-krmiva
                [1] => /c300112023-steliva
            )

        [/c300112024-akvaristika-a-teraristika] => Array
            (
                [0] => /c300112025-krmiva
            )

    )

我的功能只有2级而不是3级

  public function saveCategoryTree($categoryTree, Eshop $eshop)
{

    $em = $this->getEntityManager();


    for ($i = 0; $i < sizeof($categoryTree); $i++) {
        $categoryParent = new Category();
        $parent = array_keys($categoryTree)[$i];
        $parentName = explode("/", $parent);
        $parentName = end($parentName);
        $categoryParent->setCreatedAt(new \DateTime());
        $categoryParent->setLastCheckAt(new \DateTime());
        $categoryParent->setLastHttpStatusCode(\Symfony\Component\HttpFoundation\Response::HTTP_OK);
        $categoryParent->setActive(true);
        $categoryParent->setLeaf(false);
        $categoryParent->setEshop($eshop);
        $categoryParent->setName($parentName);
        $categoryParent->setLink($parent);
        $em->persist($categoryParent);
        $em->flush();


        foreach ($categoryTree[array_keys($categoryTree)[$i]] as $childItem) {
            if (is_array($childItem)) {
             echo "Is array ! Recursive call";
            } else {
                $child = new Category();
                $child->setParentCategory($categoryParent);
                $child->setCreatedAt(new \DateTime());
                $child->setLastCheckAt(new \DateTime());
                $child->setLastHttpStatusCode(\Symfony\Component\HttpFoundation\Response::HTTP_OK);
                $child->setActive(true);
                $child->setLeaf(true);
                $child->setEshop($eshop);
                $child->setName($childItem);
                $child->setLink($childItem);
                $em->persist($child);
                $em->flush();
            }

        }

    }
    exit;
}

感谢您的帮助。抱歉我的英文。

1 个答案:

答案 0 :(得分:1)

将您的子迭代逻辑移动到一个新函数并递归调用它;

这种方式适用于2,3,4,...层树功能。

编辑:在我的匆忙中,我已经在PHP 7中构建了这个代码。请注意,这不适用于PHP&lt; 7.随意删除类型提示和返回类型声明。

我会尝试这些方法:

    /**
     * @var EntityManager $_em
     */
    private $_em;
    /**
     * @var Eshop $_eshop
     */
    private $_eshop;

    /**
     * @param array $categoryTree
     * @param Eshop $eshop
     */
    public function saveCategoryTree(array $categoryTree, Eshop $eshop)
    {
        $this->_em    = $this->getEntityManager();
        $this->_eshop = $eshop;
        foreach ($categoryTree as $categoryKey => $categoryChildren)
        {
            if (is_array($categoryChildren))
            {
                $parentCategory = $this->_processCategory($categoryKey, $categoryChildren);
                $this->_processRecursiveChildren($parentCategory, $categoryChildren);
            } else
            {
                $this->_processCategory($categoryKey);
            }
        }
        exit;
    }

    /**
     * @param string        $categoryKey
     * @param Category|null $parentCategory
     *
     * @return Category
     */
    private function _processCategory(string $categoryKey, Category $parentCategory=null): Category
    {
        $category   = new Category();
        $parentName = explode("/", $categoryKey);
        $parentName = end($parentName);
        if ($parentCategory !== null)
        {
            $category->setParentCategory($parentCategory);
        }
        $category
            ->setCreatedAt(new \DateTime())
            ->setLastCheckAt(new \DateTime())
            ->setLastHttpStatusCode(\Symfony\Component\HttpFoundation\Response::HTTP_OK)
            ->setActive(true)
            ->setLeaf(false)
            ->setEshop($this->_eshop)
            ->setName($parentName)
            ->setLink($categoryKey)
        ;
        $this->_em->persist($category);
        $this->_em->flush();

        return $category;
    }

    /**
     * @param Category $parentCategory
     * @param array    $children
     */
    private function _processRecursiveChildren(Category $parentCategory, array $children)
    {
        foreach ($children as $childKey => $childItems)
        {
            if (is_array($childItems))
            {
                $nextParentCategory = $this->_processCategory($childKey, $parentCategory);
                $this->_processRecursiveChildren($nextParentCategory, $childItems);
            } else
            {
                $this->_processCategory($childItems, $parentCategory);
            }
        }
    }