迭代文件夹数组(类似文件系统)并返回HTML嵌套列表

时间:2013-10-16 01:28:32

标签: php html arrays recursion

我有以下数组

Array
(
    [0] => Homework2 (1).java
    [test2] => Array
    (
    )
    [1] => space-art-hd-473771.jpg
    [2] => Homework2.java
    [3] => factura_oct_2013.pdf
    [test] => Array
    (
        [0] => Homework2 (1).java
        [1] => space-art-hd-473771.jpg
        [2] => Homework2.java
    )
    [test3] => Array
    (
        [0] => Homework2 (1).java
        [testintest] => Array
        (
            [0] => Homework2 (1).java
            [1] => space-art-hd-473771.jpg
            [2] => Homework2.java
        )
        [1] => space-art-hd-473771.jpg
        [2] => Homework2.java
    )
)

我正在尝试显示HTML嵌套列表。因此,阵列中的每个子节点应该是父UL中的新UL。我试图让这个递归,但我只是设法得到了很多我已经拥有的值。

function map2ul($file_map,$html="") {
    var_dump($file_map);
    print "<br>";
    if ($html == "") $html = '<ul>';
    else $html .= '<ul>';
    foreach ($file_map as $df) :
        if (is_array($df)) :
            $html .= $this->map2ul($df,$html);
        else :
            $html .= '<li>';
            $html .= $df;
            $html .= '</li>';
        endif;
    endforeach;
    $html .= '</ul>';
    return $html;
}

这就是我所尝试过的,但似乎foreach语句的复发次数超过了它所需要的次数。

有人可以指出错误,以便我能更好地了解如何解决这个错误吗?

2 个答案:

答案 0 :(得分:2)

$html .= $this->map2ul($df,$html);

它不应该是串联,因为递归调用基于参数$html - 也就是说,连接已经在递归调用中完成。将其更改为:

$html = $this->map2ul($df,$html);

答案 1 :(得分:2)

错误如下:

if ($html == "") $html = '<ul>';
else $html .= '<ul>';

当您尝试递归调用此函数时,递归传递非空$html,导致内部循环粘合子文件夹内容。 @AgreeOrNot已经指出了一个解决方案。另一个不是将$html传递给递归调用的函数:

$html .= $this->map2ul($df);

但我认为你的方法引入了一些不必要的逻辑和处理。

通过分析数组,我们可以得出一个重要结论:如果数组值是数组,则相应的键是文件夹名称。在其他情况下,值是文件名:

function map2ul($file_map) {
    $html = '<ul>';
    foreach ($file_map as $file_id_or_folder_name => $file_name_or_folder_content) {
        // if the element is a file
        if ( ! is_array($file_name_or_folder_content)) {
            $html .= '<li>' . $file_name_or_folder_content . '</li>';
        } else { // if the element is a folder
            $html .= '<li>/ ' . $file_id_or_folder_name . '</li>';
        }
    }
    $html .= '</ul>';
    return $html;
}

现在足以在必要时注入子文件夹内容,即文件夹:

function map2ul($file_map) {
    $html = '<ul>';
    foreach ($file_map as $file_id_or_folder_name => $file_name_or_folder_content) {
        // if the element is a file
        if ( ! is_array($file_name_or_folder_content)) {
            $html .= '<li>' . $file_name_or_folder_content . '</li>';
        } else { // if the element is a folder
            $html .= '<li>/ ' . $file_id_or_folder_name . '</li>';
            // injecting sub-folder's contents
            $html .= map2ul($file_name_or_folder_content);
        }
    }
    $html .= '</ul>';
    return $html;
}

修改

  

如果我希望这段代码$html .= '<li>' . $file_name_or_folder_content . '</li>';附加data-filepath属性,这将是parent_folder / file_name路径,我需要做什么?

您必须传递函数的完整路径。并且需要在函数调用中构造完整路径:

function map2ul($file_map, $path = '') {
    $path = $path . '/';
    $html = '<ul>';
    foreach ($file_map as $file_id_or_folder_name => $file_name_or_folder_content) {
        // if the element is a file
        if ( ! is_array($file_name_or_folder_content)) {
            $html .= '<li data-filepath="' . $path . $file_name_or_folder_content . '">' . $file_name_or_folder_content . '</li>';
        } else { // if the element is a folder
            $html .= '<li>/ ' . $file_id_or_folder_name . '</li>';
            $html .= map2ul($file_name_or_folder_content, $path . $file_id_or_folder_name);
        }
    }
    $html .= '</ul>';
    return $html;
}

尝试不使用第二个参数,例如map2ul($file_map)和第二个参数,例如map2ul($file_map, 'c:/my_files')