我有一个从MySQL Table获取的类别树数组。我想使用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
)
)
)
现在,我想使用PHP将这个数组树转换回面包屑列表,例如
“猫1>猫2>猫3”
“猫1>猫2>猫4”
“猫1>猫2>猫5”
“猫1>猫2>猫6”
任何帮助将不胜感激。
屏幕截图
答案 0 :(得分:0)
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);
希望这会有所帮助
答案 1 :(得分:0)
关键概念是将树转换为平面数组,其中每个类别均通过其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(' > ', $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;