RecursiveDirectoryIterator 缩进子文件夹

RecursiveDirectoryIterator indent subfolders

我使用 RecursiveDirectoryIterator 列出了我所有的文件和文件夹,我想以与资源管理器相同的方式显示结果。 为此,我需要缩进子文件夹,但我不知道该怎么做...... 我可以使用子文件夹计数器,但它只适用于级别 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>';   
    }
}

这是遍历目录树的程序的版本 2。

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

现在,当我开始寻找答案时,它似乎很简单。嗯...;-/

我最终得出结论,我要么必须使用现成的包,例如 synfony : The Finder Component,要么编写我自己的 Directory iterator 组件。

后者我做了,自己做了SortedDirectory class.

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

class SortedDirectory 的源代码可用。

代码:

<?php // 

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>';
}

SortedDirectory class:

如果您想更改排序顺序,请编辑:

private function cmpEntry(SplFileInfo $entry1, SplFileInfo $entry2)

<?php // 
      // 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());
    }

}

为了记录,我已经将 class (RecursiveDirectoryIterator) 变成了一个要点,它可以读取一个目录及其所有子目录并输出一个 JSON 或一个数组。

https://gist.github.com/jonataswalker/3c0c6b26eabb2e36bc90

以及输出的树查看器

http://codebeautify.org/jsonviewer/067c13