Php 递归目录迭代器缩进子文件夹
我使用递归目录迭代器列出了我的所有文件和文件夹,并且我希望以与浏览器相同的方式显示结果。 为此,我需要缩进子文件夹,但我不知道如何做。。。 我可以使用子文件夹计数器,但它只适用于级别1,对于级别2则不起作用 这是我的密码: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
$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> <span id="file_'.$nb.'">'.$file->getFilename().'</span></li>';
} else {
$list_docs .= '<li class="docResult"><i class="fa fa-file-o"></i> <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> <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> <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());
}
}