代码分离悖论:从多维数组创建HTML树并将HTML保留在递归函数之外

时间:2009-05-21 16:45:29

标签: php html tree multidimensional-array code-separation

这个工作代码似乎是这个问题的典型解决方案。

它需要一个包含类别及其子类别的多维数组(没有暗示它深入多少级别),并从中创建一个HTML无序列表,从递归函数内部回显到页面。

通过从名为_category_list()_的原始回调函数内部递归地将每个数组元素的'children'键的值传递给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标记内放置其他属性,甚至在输出文本周围包装新标记,例如span标记,这些标记通常用于导航以实现CSS的滑动门效果。所以我认为适当的解决方案至少需要支持这些案例场景。

使用array_walk()从模板中迭代数组仍然没问题,只要它可以以回调函数将所需的vars传递回模板以便与设计者的HTML一起使用的方式使用。 / p>

理想情况下,如果array_walk_recursive()知道它的迭代器实际有多深,我认为这个专长将更容易解决。但除非有人知道该问题的解决方法,否则解决方案可能完全不同。

我还想避免使用构建树的javascript方法。如果有办法避免使用开关,我也愿意接受建议。

1 个答案:

答案 0 :(得分:1)

您是否考虑过编写一个管理和存储您想要传回的信息的类。你的函数可以改变该类的实例,并在最后传回填充的对象。

您的内容将封装在类中,您可以编写用户操作和输出数据的所有方法和实用程序。实用方法也可以写在类中,以显示级别数等。

我自己没有尝试过,但这是我要开始的地方,因为Class允许我改进和扩展我的用户想要的东西,他们不需要知道发生了什么的内部细节。