PHP反向类别树数组到面包屑列表 [英] PHP Reverse Category Tree array to Breadcrumb List

查看:92
本文介绍了PHP反向类别树数组到面包屑列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个从MySQL Table获取的类别树数组。我想使用PHP将类别数组树还原到面包屑列表中。

I have a category tree array fetched from MySQL Table. I want to revert this Category array tree back into Breadcrumb list using PHP.

PHP类别树构建功能

function buildTree(array &$elements, $parentId = 0) 
{
    $branch = array();

    foreach ($elements as $element) {
        if ($element['parent_category_id'] == $parentId) {
            $children = buildTree($elements, $element['category_id']);
            if ($children) {
                $element['children'] = $children;
            }
            $branch[$element['category_id']] = $element;
            unset($elements[$element['category_id']]);
        }
    }
    return $branch;
}

结果数组

[48] => Array
    (
        [category_id] => 48
        [category_name] => Cat 1 
        [parent_category_id] => 0
        [children] => Array
            (
                [957] => Array
                    (
                        [category_id] => 957
                        [category_name] =>  Cat 2
                        [parent_category_id] => 48
                        [children] => Array
                            (
                                [1528] => Array
                                    (
                                        [category_id] => 1528
                                        [category_name] =>  Cat 3
                                        [parent_category_id] => 957
                                    )

                                [1890] => Array
                                    (
                                        [category_id] => 1890
                                        [category_name] =>  Cat 4
                                        [parent_category_id] => 957
                                    )

                                [1570] => Array
                                    (
                                        [category_id] => 1570
                                        [category_name] =>  Cat 5
                                        [parent_category_id] => 957
                                    )

                                [958] => Array
                                    (
                                        [category_id] => 958
                                        [category_name] =>  Cat 6
                                        [parent_category_id] => 957
                                    )

                            )

                    )

现在我要转换此数组树


Cat 1> Cat 2> Cat 3

"Cat 1 > Cat 2 > Cat 3"

猫1>猫2>猫4

猫1>猫2>猫5

Cat 1> Cat 2> Cat 6

"Cat 1 > Cat 2 > Cat 6"

任何帮助将不胜感激。

截屏

屏幕快照参考

推荐答案

关键概念将您的树转换为平面数组,其中每个类别均通过其ID进行索引。从该平面结构中,您可以遍历层次结构,直到到达每个类别的根,创建一系列级别。我创建了一个帮助程序类来封装面包屑可能需要的基本功能。递归发生在 _unwindTree 方法中。 _buildBreadcrumbs 方法调用此函数,并使用生成的平面数组为每个类别构建面包屑行。这是要了解如何将树转换为类别路径数组的两个函数。

The key concept is converting your tree into a flat array where each category is indexed by it's ID. From that flat structure, you can walk up the hierarchy until you reach the root for each category, creating an array of the levels. I've created a helper class to encapsulate the basic functionality you might want for breadcrumbs. The recursion happens in the _unwindTree method. The _buildBreadcrumbs method calls this function and uses the resulting flat array to build the breadcrumb "lines" for each category. These are the two functions to look at to understand how you convert a tree into an array of category paths.

有一些公共函数可提供对面包屑数据的访问。

There are some public functions that provide access to the breadcrumb data in different ways.

<?php

$tree = [
    48 => [
        'category_id' => 48,
        'category_name' => 'Cat 1',
        'parent_category_id' => 0,
        'children' =>
            [
                957 =>
                    [
                        'category_id' => 957,
                        'category_name' => 'Cat 2',
                        'parent_category_id' => 48,
                        'children' =>
                            [
                                1528 =>
                                    [
                                        'category_id' => 1528,
                                        'category_name' => 'Cat 3',
                                        'parent_category_id' => 957
                                    ],
                                1890 =>
                                    [
                                        'category_id' => 1890,
                                        'category_name' => 'Cat 4',
                                        'parent_category_id' => 957
                                    ],
                                1570 =>
                                    [
                                        'category_id' => 1570,
                                        'category_name' => 'Cat 5',
                                        'parent_category_id' => 957
                                    ],
                                958 =>
                                    [
                                        'category_id' => 958,
                                        'category_name' => 'Cat 6',
                                        'parent_category_id' => 957
                                    ]

                            ]

                    ]
            ]
    ]
];

class BreadcrumbHelper
{

    private $_leafOnly = true;
    private $_defaultBaseUrlPath = '/category/';

    private $_tree        = [];
    private $_idMap       = [];
    private $_leafIds     = [];
    private $_breadcrumbs = [];

    /**
     * BreadcrumbHelper constructor.
     * @param array $tree The tree of category data
     */
    public function __construct($tree)
    {
        $this->_tree = $tree;

        //Build the breadcrumb data structure
        $this->_buildBreadcrumbs();
    }

    /**
     * Return breadcrumbs as an array
     * @param mixed $categoryIds optional, only specified categories will be returned
     * @return array
     */
    public function getBreadcrumbArray($categoryIds = [])
    {
        //If a bare ID is passed, wrap it in an array so we can treat all input the same way
        if (!is_array($categoryIds))
        {
            $categoryIds = [$categoryIds];
        }

        //If we have category input, return a filtered array of the breadcrumbs
        if (!empty($categoryIds))
        {
            return array_intersect_key($this->_breadcrumbs, array_flip($categoryIds));
        }

        //If no input, return the fill array
        return $this->_breadcrumbs;
    }

    /**
     * Return breadcrumbs as an array containing HTML markup
     * You may want to modify this to echo HTML directly, or return markup only instead of an array
     * @param mixed $categoryIds optional, only specified categories will be returned
     * @return array
     */
    public function getBreadcrumbHtml($categoryIds = [], $baseUrlPath = null)
    {
        //If a bare ID is passed, wrap it in an array so we can treat all input the same way
        if (!is_array($categoryIds))
        {
            $categoryIds = [$categoryIds];
        }

        //If a base URL path is provided, use it, otherwise use default
        $baseUrlPath = (empty($baseUrlPath)) ? $this->_defaultBaseUrlPath : $baseUrlPath;

        //Filter breadcrumbs if IDs provided
        $breadcrumbs = (empty($categoryIds)) ? $this->_breadcrumbs : array_intersect_key($this->_breadcrumbs, array_flip($categoryIds));

        $output = [];
        foreach ($breadcrumbs as $currCategoryId => $currLine)
        {
            $currLinkBuffer = [];
            foreach ($currLine as $currCategory)
            {
                //Build the markup - customize the URL for your application
                $currLinkBuffer[] = '<a href="' . $baseUrlPath . $currCategory['category_id'] . '">' . $currCategory['category_name'] . '</a>';
            }

            $output[$currCategoryId] = implode(' &gt; ', $currLinkBuffer);
        }

        return $output;
    }

    /**
     * Print the breadcrumbs
     * @param array $categoryIds optional, only specified categories will be printed
     */
    public function printBreadcrumbs($categoryIds = [])
    {
        //If a bare ID is passed, wrap it in an array so we can treat all input the same way
        if (!is_array($categoryIds))
        {
            $categoryIds = [$categoryIds];
        }

        //Filter breadcrumbs if IDs provided
        $breadcrumbs = (empty($categoryIds)) ? $this->_breadcrumbs : array_intersect_key($this->_breadcrumbs, array_flip($categoryIds));

        foreach ($breadcrumbs as $currLine)
        {
            //Build a buffer of the category names
            $currNameBuffer = [];
            foreach ($currLine as $currCategory)
            {
                $currNameBuffer[] = $currCategory['category_name'];
            }

            //Join the name buffer with a separator and echo the result
            echo implode(' > ', $currNameBuffer) . PHP_EOL;
        }
    }

    /**
     * Create the breadcrumb data structure from the provided tree
     */
    private function _buildBreadcrumbs()
    {
        //Unwind the tree into a flat array
        $this->_unwindTree($this->_tree);

        //Traverse the flat array and build the breadcrumb lines
        $categoryIds = ($this->_leafOnly) ? $this->_leafIds:array_keys($this->_idMap);
        foreach ($categoryIds as $currLeafId)
        {
            $currCategoryId = $currLeafId;

            $currLine = [];

            do
            {
                $currLine[]     = $this->_idMap[$currCategoryId];
                $currCategoryId = $this->_idMap[$currCategoryId]['parent_category_id'];
            } while ($currCategoryId != 0);

            $this->_breadcrumbs[$currLeafId] = array_reverse($currLine);
        }
    }

    /**
     * Recursive function that traverses the tree and builds an associative array of all categories
     * indexed by ID. Categories saved in this structure do not include children.
     * @param $branch
     */
    private function _unwindTree($branch)
    {
        foreach ($branch as $currId => $currData)
        {
            //Set the current category in the ID map, remove the children if present
            $this->_idMap[$currId] = array_diff_key($currData, array_flip(['children']));

            if (!empty($currData['children']))
            {
                //Recursion
                $this->_unwindTree($currData['children']);
            }
            else
            {
                $this->_leafIds[] = $currId;
            }
        }
    }
}

//Instantiate our helper with the tree data
$breadcrumbHelper = new BreadcrumbHelper($tree);

echo 'All breadcrumbs: ' . PHP_EOL;
$breadcrumbHelper->printBreadcrumbs();
echo PHP_EOL;

echo 'Single breadcrumb line by category ID: ' . PHP_EOL;
$breadcrumbHelper->printBreadcrumbs(1570);
echo PHP_EOL;

echo 'Multiple categories: ' . PHP_EOL;
$breadcrumbHelper->printBreadcrumbs([957, 1570]);
echo PHP_EOL;

echo 'Breadcrumb HTML: ' . PHP_EOL;
$breadcrumbMarkup = $breadcrumbHelper->getBreadcrumbHtml();
echo $breadcrumbMarkup[1570] . PHP_EOL;
echo PHP_EOL;

echo 'Breadcrumb HTML with custom base URL: ' . PHP_EOL;
$breadcrumbMarkup = $breadcrumbHelper->getBreadcrumbHtml(1570, '/category.php?id=');
echo $breadcrumbMarkup[1570] . PHP_EOL;
echo PHP_EOL;

这篇关于PHP反向类别树数组到面包屑列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆