这个工作代码似乎是这个问题的典型解决方案。
它采用一个包含类别及其子类别的多维数组(对它的深度没有隐含限制),并从中创建一个 HTML 无序列表,从递归函数内部将其回显到页面上。
通过将每个数组元素的 'children' 键的值从名为 _category_list()_ 的原始回调函数内部递归地传递给 array_walk() 来遍历子级别。
如何修改这种输出方法,以使所有 HTML 代码都存在于模板中、函数之外?
这是代码的概要:
这个多维数组保存了多级类别树。
在 HTML 中使用的重要键是“category_id”、“name”和“children”。为简单起见,其他键已从下面的数组中清除,但如果它们有用,它们是:'parent_id' 和 'level'(从级别 1 开始)。
<?php
// the array containing the tree
$categories = array (
'category_id' => '2',
'name' => 'Top Category Name',
'children' => array (
0 => array (
'category_id' => '188',
'name' => 'Category Name',
'children' => array (
0 => array (
'category_id' => '159',
'name' => 'Category Name',
'children' => array (),
),
1 => array (
'category_id' => '160',
'name' => 'Category Name',
'children' => array (),
),
2 => array (
'category_id' => '166',
'name' => 'Category Name',
'children' => array (),
),
),
),
1 => array (
'category_id' => '4',
'name' => 'Category Name',
'children' => array (
0 => array (
'category_id' => '141',
'name' => 'Category Name',
'children' => array (),
),
1 => array (
'category_id' => '142',
'name' => 'Category Name',
'children' => array (),
),
),
),
),
)
?>
.
下一个函数产生大部分 HTML 输出,但它会将 HTML 锁定在自身内部。
但是,我不是直接从函数中呼应它,而是寻找一种方法以一种对设计人员自定义友好的方式将此数据传递回视图模板。
<?php
// separate the HTML from this function,
// passing $v to the view template for handling
function category_list($v, $k){
switch ($k) {
case 'category_id':
echo "<li id="$v">";
break;
case 'name':
echo "$v";
break;
case 'children':
if(count($v) > 0){
echo "<ul>";
foreach($v as $k=>$v)
array_walk($v, 'category_list');
echo "</ul>";
}
echo "</li>";
break;
}
}
?>
.
下一个代码块是当前模板 html/php,其中调用通过 array_walk() 遍历数组的第一级并引用上面的递归函数。然后,该函数本身处理具有 1 个或多个子级的更深类别的递归和迭代。当然,这是典型的做法。
此代码应具有所有 HTML 标记,而不仅仅是外部标记。
<ul>
<?php array_walk($tree,'category_list'); ?>
</ul>
.
理想的解决方案:
这里的最终目标是为模板设计者找到一种方法来创建他们理想的导航结构,而无需创建或修改递归函数(不可访问),也不需要为多维的每个级别使用 foreach 循环大批。该解决方案不应与任何特定的深度限制相关联。
HTML 自定义的示例可以包括在 ul/li 标签内放置额外的属性,甚至在输出文本周围包裹新标签,例如跨度标签,这些标签通常用于导航中,以通过 CSS 实现滑动门效果。所以我认为适当的解决方案至少需要支持这些案例场景。
使用 array_walk() 遍历模板中的数组仍然可以,只要它可以以这样的方式使用,即回调函数将所需的变量传递回模板以与设计器的 HTML 一起使用。
理想情况下,如果 array_walk_recursive() 知道它的迭代器实际上有多少层,我认为这个壮举会更容易解决。但除非有人知道该问题的解决方法,否则解决方案可能会完全不同。
我还想避免使用构建树的 javascript 方法。如果有办法避免使用开关,我也愿意接受那里的建议。