簡體   English   中英

PHP反向類別樹數組到面包屑列表

[英]PHP Reverse Category Tree array to Breadcrumb List

我有一個從MySQL表獲取的類別樹數組。 我想使用PHP將這個Category數組樹還原回面包屑列表。

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
                                    )

                            )

                    )

現在,我想使用PHP將這個數組樹轉換回面包屑列表,例如

“貓1>貓2>貓3”

“貓1>貓2>貓4”

“貓1>貓2>貓5”

“貓1>貓2>貓6”

任何幫助將非常感激。

截圖

屏幕截圖參考

function treeToArray($data, &$return_data, $index = '', $sub = 'sub')
{
    if (is_array($data)) {
        foreach ($data as $value) {
            if (isset($value[$sub])) {
                $tmp = $value[$sub];
                unset($value[$sub]);
                if ($index) {
                    $return_data[$value[$index]] = $value;
                } else {
                    $return_data[] = $value;
                }
                treeToArray($tmp, $return_data, $index, $sub);
            } else {
                if ($index) {
                    $return_data[$value[$index]] = $value;
                } else {
                    $return_data[] = $value;
                }
            }
        }
    }
    return $return_data;
}

$tree[48] =  Array
    (
    "category_id" => '48',
    "category_name" => 'Cat 1',
    "parent_category_id" => '0',
    "children" => Array
        (
            '957' => Array
                (
                    "category_id" => "957",
                    "category_name" =>  "Cat",
                    "parent_category_id" => "48",
                    "children" => Array
                        (
                            '1528' => Array
                                (
                                    "category_id" => "1528",
                                    "category_name" =>  "Cat3",
                                    "parent_category_id" => "957",
                                )

                        )

                )
            )
    );

$data = [];
treeToArray($tree, $data, 'category_id', 'children');
print_r($data);

希望對您有所幫助

關鍵概念是將樹轉換為平面數組,其中每個類別均通過其ID進行索引。 從該平面結構中,您可以遍歷層次結構,直到到達每個類別的根,創建一系列級別。 我創建了一個幫助器類來封裝面包屑可能需要的基本功能。 遞歸發生在_unwindTree方法中。 _buildBreadcrumbs方法調用此函數,並使用生成的平面數組為每個類別構建面包屑“行”。 這是要了解如何將樹轉換為類別路徑數組的兩個功能。

有一些公共功能以不同的方式提供對面包屑數據的訪問。

<?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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM