Php 递归目录迭代器缩进子文件夹

Php 递归目录迭代器缩进子文件夹,php,file,recursion,directory,indentation,Php,File,Recursion,Directory,Indentation,我使用递归目录迭代器列出了我的所有文件和文件夹,并且我希望以与浏览器相同的方式显示结果。 为此,我需要缩进子文件夹,但我不知道如何做。。。 我可以使用子文件夹计数器,但它只适用于级别1,对于级别2则不起作用 这是我的密码: $nb=1; $read_folder = './cases/'; $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($read_folder), Recu

我使用递归目录迭代器列出了我的所有文件和文件夹,并且我希望以与浏览器相同的方式显示结果。 为此,我需要缩进子文件夹,但我不知道如何做。。。 我可以使用子文件夹计数器,但它只适用于级别1,对于级别2则不起作用

这是我的密码:

    $nb=1;
    $read_folder = './cases/';
    $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($read_folder), RecursiveIteratorIterator::SELF_FIRST);
    foreach ($iterator as $file) {
    $nb++;
    if ($file->isDir()) {
        $list_docs .= '<li class="docResult"><i class="fa fa-folder"></i>&nbsp;<span id="file_'.$nb.'">'.$file->getFilename().'</span></li>';   
    } else {
        $list_docs .= '<li class="docResult"><i class="fa fa-file-o"></i>&nbsp;<span id="file_'.$nb.'">'.$file->getFilename().'</span></li>';   
    }
}
$nb=1;
$read_folder='./cases/';
$iterator=new recursiveiterator(new recursivedirectoryinterator($read_folder),recursiveiterator::SELF_FIRST);
foreach($iterator作为$file){
$nb++;
如果($file->isDir()){
$list_docs.='
  • '.$file->getFilename()。
  • '; }否则{ $list_docs.='
  • '.$file->getFilename()。
  • '; } }
    这是用于遍历目录树的程序的第2版

    它必须是一个不同的程序,因为需要对输出进行排序,以便在文件之前打印目录和文件

    现在,当我开始寻找答案的时候,它看起来很简单。嗯…;-/

    我最终得出结论,要么使用现成的软件包,比如,要么编写自己的
    目录迭代器
    组件

    我做了后者,并制作了自己的
    SortedDirectory

    输出没有以任何方式格式化。它使用浏览器的默认样式

    的源代码可用

    守则:

    <?php // http://stackoverflow.com/questions/31470421/recursivedirectoryiterator-indent-subfolders
    
    include 'Q31470421-sorted-directory-class.php';
    
    $sourceFolder = 'P:\developer\xampp\htdocs\testmysql\Q23408272'; // top level directory to search
    // $sourceFolder = 'P:\developer\xampp\htdocs\testmysql'; // top level directory to search
    
    /**
     * Sorted Directory for the supplied path
     */
    $dirIter = new SortedDirectory(new SplFileInfo($sourceFolder));
    
    /**
     * Process the complete path recursing around as required..
     */
    echo processDirectory($dirIter);
    
    exit; // end the program
    
    /**
     * Recurse around all the paths
     *
     * @param \SortedDirectory $directory
     */
    function processDirectory(\SortedDirectory $directory, $depth = 0)
    {
        $html = showOneDirectory($directory, $depth); // show all files in this directory
    
        foreach ($directory as $entry) {
            if ($entry->isDir()) { // recurse arount any sub-directories
                $html .= '<ul class="dir-start">';
                $html .=  processDirectory(new \SortedDirectory($entry), $depth + 1);
                $html .= '<!-- dir-end --></ul>';
            }
        }
    
        return $html;
    }
    
    /**
     * Process all the files for one directory
     *
     * @param \SortedDirectory $directory
     * @param type $depth
     * @return html
     */
    function showOneDirectory(\SortedDirectory $directory, $depth = 0)
    {
        $dirCount = 0;
        $fileCount = 0;
        $list_docs = '<ul>';
        foreach ($directory as $key => $entry) {
    
    
            if ($entry->isDir()) {
                $dirCount++;
                $list_docs .= '<li class="docResult">'
                              .'<i class="fa fa-folder">'
                              .'</i>&nbsp;<span id="file_'. $key .'">'
                              .' Directory: '
                              .' Name: '. $entry->getFilename()
                              .' | Path: '. $entry->getPath()
                              .' | Depth: '. $depth
                             .'</span></li>';
            }
            else {
                $fileCount++;
                $list_docs .= '<li class="docResult">'
                              .'<i class="fa fa-folder">'
                              .'</i>&nbsp;<span id="file_'. $key .'">'
                              .' File: '
                              .' Name: '. $entry->getFilename()
                              .' | Path: '. $entry->getPath()
                              .' | Depth: '. $depth
                             .'</span></li>';
            }
        }
        $list_docs .= '<li>'. "Counts: Dir: $dirCount, Files: $fileCount" .'</li>';
        return $list_docs .= '</ul>';
    }
    

    对于记录,我已经将一个类(
    recursivedirectoryinterator
    )转换为gist,它可以读取一个目录及其所有子目录,并输出一个JSON或一个数组

    以及输出的树查看器


    嘿,瑞安·文森特。非常感谢你的回答。你甚至还回答了我的下一个问题,那就是在当前文件夹下显示文件。你太棒了!哦,还有一件小事。首先声明SELF_时,在深度0上包含的文件夹位于顶部。但对于其他深度,子文件夹总是列在文件后面,你知道如何更正吗@瑞安-vincent@VincentTeyssier,看了看;-/。可悲的是,这不是一件“小事”;-/。这是可以做到的。第一部分是提供一个类,该类允许按照给定的“路径”的排序顺序分别列出目录和文件,这是一个相当便宜的“可执行”的类。在网上搜索了很多“有趣”的东西。但是,不确定需要多长时间来整理如果你想“滚动”你自己的,那么symfony Finder组件通过直观流畅的界面查找文件和目录,这可能很有用。事实上,我正在考虑另一种方法。我将对每个给定深度的
  • ID进行排序,而不是对结果进行排序。然后通过检查目录或文件是否。。。不确定是否更简单,但至少这是我在没有帮助的情况下可以做到的:)非常感谢您做出的不可估量的贡献。@VincentTeyssier,如果您需要额外的帮助,请随时发表评论。我也会对你最终如何解决它感兴趣,所以我们有另一种解决这类问题的技术。谢谢-任何问题都可以问-我会尝试帮助。新版本的代码可用。
    <?php // http://stackoverflow.com/questions/31470421/recursivedirectoryiterator-indent-subfolders
          // Q31470421-sorted-directory-class
    
    class SortedDirectory implements IteratorAggregate, Countable
    {
        /**
         * Sorted directory list
         *
         * @var array
         */
        private $directories = array();
    
        /**
         * sorted file list
         *
         * @var array
         */
        private $files = array();
    
        private $allFiles = null;
    
        /**
         * Read the supplied directory into the two lists and sort them
         *
         * Ignore the '.' and '..' entries
         *
         * @param SplFileInfo
         */
        public function __construct(\SplFileInfo $directory)
        {
           foreach (new DirectoryIterator($directory->getRealPath()) as $entry) {
               if ($entry->isDir()) {
                   $fname = $entry->getBasename();
                   if (substr($fname, 0, 1) === '.') {
                       if ($fname === '.' || $fname === '..') {
                           continue;
                       }
                    }
                    $this->directories[] = clone $entry;
               }
               else {
                   $this->files[] = clone $entry;
               }
           }
           $this->sortLists();
        }
    
    
        /**
         * Iterator of the sorted directory list
         *
         * @return \ArrayIterator
         */
        public function getDirIterator()
        {
           return new ArrayIterator($this->directories);
        }
    
        /**
         * Iterator of the sorted files
         *
         * @return \ArrayIterator
         */
        public function getFileIterator()
        {
           return new ArrayIterator($this->files);
        }
    
        /**
         * Iterator of all the directory entries
         *
         * @return \ArrayIterator All the files with directories before files
         */
        public function getIterator()
        {
           return new ArrayIterator($this->allFiles);
        }
    
        public function __get($property)
        {
           return $this->$property;
        }
    
        /*
         * Implement Iterator
         *
         */
    
        /**
         * @return \SplFileInfo
         */
        public function current()
        {
            return current($this->allFiles);
        }
    
        /**
         * @return int
         */
        public function key()
        {
            return key($this->allFiles);
        }
    
        public function next()
        {
            return next($this->allFiles);
        }
    
        public function reset()
        {
            return reset($this->allFiles);
        }
    
        public function rewind()
        {
            return reset($this->allFiles);
        }
    
        public function valid()
        {
            return current($this->allFiles) !== false;
        }
    
        /**
         * @return integer
         */
        public function count()
        {
            return count($this->allFiles);
        }
    
        /**
         * Sort lists using 'natural' compare
         */
        private function sortLists()
        {
           if (count($this->directories) >= 2) {
                usort($this->directories, array($this, 'cmpEntry'));
           }
           if (count($this->files) >= 2) {
                usort($this->files,  array($this, 'cmpEntry'));
           }
    
           $this->allFiles = array_merge($this->directories, $this->files);
        }
    
        private function cmpEntry(SplFileInfo $entry1, SplFileInfo $entry2)
        {
           return strnatcasecmp($entry1->getFilename(), $entry2->getFilename());
        }
    
    }