【问题标题】:PHP recursive directory menu (different approaches)PHP递归目录菜单(不同的方法)
【发布时间】:2013-11-09 02:11:28
【问题描述】:

我正在尝试创建一个 PHP 菜单,该菜单在列表中显示每个目录中的目录和文件,并带有指向这些目录中每个文件的链接(但不是指向目录本身的链接)。目录的数字为“2013”​​、“2014”等,这些目录中的文件是PDF。

本质上:

--- 2013(未链接)

--------------- 01.pdf(链接)

--------------- 02.pdf(链接)

--------------- 03.pdf(链接)

--- 2014(未链接)

--------------- 04.pdf(链接)

--------------- 05.pdf(链接)

--------------- 06.pdf(链接)

目前,我的代码如下所示:

<?php
function read_dir_content($parent_dir, $depth = 0){
    if ($handle = opendir($parent_dir)) 
    {
        while (false !== ($file = readdir($handle)))
        {
            if(in_array($file, array('.', '..'))) continue;
            if( is_dir($parent_dir . "/" . $file) ){
                $str_result .= "<li>" . read_dir_content($parent_dir . "/" . $file, $depth++) . "</li>";
            }
            $str_result .= "<li><a href='prs/{$file}'>{$file}</a></li>";
        }
        closedir($handle);
    }
    $str_result .= "</ul>";
    return $str_result;
}
echo "<ul>".read_dir_content("prs/")."</ul>";
?>

但是,这在处理时会造成一团糟。 (可惜我是新用户,不能发图片,不过如果不是太忌讳的话,我会提供一个偷偷摸摸的链接:http://i.stack.imgur.com/gmIFz.png

我的问题/请求帮助:

1.为什么顺序颠倒了字母数字,即为什么2013在列表的底部而2014在顶部?

2.如何在保留 PDF 链接的同时删除目录链接?

3. 我很困惑为什么每个目录列表的末尾都有空列表项,以及为什么它们没有逻辑/一致地间隔,即为什么 01、02、03 PDF不从属于 2013 年(参见上面的“本质”间距)?

注意我是编程和 PHP 新手,所以请记住,我明显的错误可能非常简单。如果是,请提前道歉。

edit大量的好处是去掉文件名末尾的“.pdf”,但这可能是一个完全不同的问题/问题。

【问题讨论】:

  • 检查一下:stackoverflow.com/questions/2183486/… 并使用 php.net 上有关 basename()、pathinfo() 和 glob() 的示例。
  • 谢谢,Ryan - Tivie 好心地解决了这个额外的问题,但很高兴有这个文档的链接。干杯。

标签: php recursion menu directory


【解决方案1】:

PHP5 有一个名为 RecursiveDirectoryIterator 的类

这段代码:

  1. 根据需要对列表进行排序(首先是 2013 年,然后是 2014 年)
  2. 不显示目录链接
  3. 解决格式化问题
  4. 奖励:删除 pdf 扩展名

..

$myLinks = array();
$dirIterator = new RecursiveDirectoryIterator($parent_dir);

//iterates main prs directory
foreach ($dirIterator as $file) {

    // If its a directory, it will iterate it's children (except if it's . or ..)
    if ($file->isDir() && $file->getFilename() != '.' && $file->getFilename() != '..') {
        $dir = new RecursiveDirectoryIterator($file->getRealPath());
        $myLinks[$file->getFilename()] = array();
        foreach ($dir as $subFile) {
            //If it finds a file whose extension is pdf
            if ($subFile->isFile() && $subFile->getExtension() == 'pdf') {
                // Gets its filename and removes extension
                $fname = str_replace('.pdf', '', $subFile->getFilename());
                // adds the file information to an array
                $myLinks[$file->getFilename()][$fname] = "prs/{$file->getFilename()}/{$subFile->getFilename()}";
            }
        }
    }
}

//Sort our array alphabetically (and numerically) and recursively
ksort_recursive($myLinks);

function ksort_recursive(&$array)
{
    if (!is_array($array)) return;
    ksort($array);
    foreach ($array as $k=>$v) {
        ksort_recursive($array[$k]);
    }
}



// now we print our links as a unordered list
print '<ul>';
foreach ($myLinks as $year => $val) {
    print "<li>$year";
    foreach ($val as $name => $link) {
        print "<li><a href='$link'>$name</a></li>";
    }
    print '</li>';
}
print '</ul>';

【讨论】:

  • 这是我添加行 "$parent_dir = "prs/";" 时的结果在顶部(因为我得到一个错误,否则):i.imgur.com/Ea7CxHH.png 1)代码排序为 2013,然后是 2014,但数字没有排序。我是否必须分别在每个组上重新运行 ksort ? 2)这很好,这会迭代孩子而不是导演(只要不制作目录链接),但我怎样才能让它们出现但不作为链接出现(就像我试图在我的问题的第一个块引用中说明的那样)。
  • @Tom 检查我编辑的答案。另外,试着理解我给你的代码。你不应该相信你在互联网上获得的任何代码而不理解它。如果您有任何问题,我会很乐意回答
  • 谢谢,蒂维。要获取文件夹名称,我可以添加如下内容: $myDirs = array(); foreach ($dir as $folder) { $myDirs[$folder->getDirname()] = array(); ?但是,如何使 PDF 从属?我想我需要某种循环,但我怎样才能每次都制作特定于每个目录的新数组?我是否围绕这个当前迭代器循环创建一个循环,类似于上面的内容? $myDirs = ...
  • 对不起,忽略!我用你的代码弄明白了。我将最后一部分编辑为: print '
      '; foreach ($myLinks as $year => $val) { print "
    • $year
      • "; foreach ($val as $name => $link) { print "
      • $name
      • "; } 打印'
      '; } 打印'
    ';
  • 顺便说一句,非常感谢您的帮助!
【解决方案2】:

首先我看到这条线

$str_result .= "</ul>";

但我没有看到打开的 ul 标记。这可能是疯狂的结果的来源。

1) 我会使用 scandir 而不是 readdir,因为它可以让您设置排序顺序。

2,3) 摆脱 $str_result .= "&lt;/ul&gt;"; 并在您的 while 循环中尝试这样的操作,以删除 dir 链接并获得正确的顺序:(注意:我没有运行这个)

if( ! in_array($file, array('.', '..')) ) { 
    if( is_dir($parent_dir . "/" . $file) ){
        $str_result .= "<li>{$file}</li>";
        $str_result .= "<ul>";
        $str_result .= "<li>" . read_dir_content($parent_dir . "/" . $file, $depth++) . "</li>";
        $str_result .= "</ul>";
    } else {
        $str_result .= "<li><a href='prs/{$file}'>{$file}</a></li>";
    }

}

【讨论】:

  • 谢谢,加布里埃尔 - 特别是指出那条明显的线!很高兴能够(至少部分地)知道我哪里出错了。 scandir 看起来也很棒!
猜你喜欢
  • 2013-06-13
  • 2016-07-28
  • 2013-11-05
  • 2012-12-27
  • 2010-10-24
  • 2011-03-10
  • 2010-12-09
  • 2023-04-04
  • 2013-06-17
相关资源
最近更新 更多