PHP反向类别树数组到面包屑列表 [英] PHP Reverse Category Tree array to Breadcrumb List
问题描述
我有一个从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(' > ', $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屋!