使用 SPL 的 DirectoryTreeIterator 对每个目录的文件进行排序
我发现了几个问题(这个和这个问题)与SPL迭代器相关,但是我不确定它们对我的情况是否有帮助,因为我使用的是 RecursiveIteratorIterator
的相当高级的扩展; DirectoryTreeIterator。
有人可以告诉我如何更改 DirectoryTreeIterator 或如何在迭代器输出后按目录对返回的数组进行排序吗?
直接在 Apache 服务器上正确排序文件的方法对我来说也是一种选择,例如,如果可以使用 .htaccess
的话。
这是来自 SPL 的 DirectoryTreeIterator
代码:
/** @file directorytreeiterator.inc
* @ingroup Examples
* @brief class DirectoryTreeIterator
* @author Marcus Boerger
* @date 2003 - 2005
*
* SPL - Standard PHP Library
*/
/** @ingroup Examples
* @brief DirectoryIterator to generate ASCII graphic directory trees
* @author Marcus Boerger
* @version 1.1
*/
class DirectoryTreeIterator extends RecursiveIteratorIterator
{
/** Construct from a path.
* @param $path directory to iterate
*/
function __construct($path) {
parent::__construct(
new RecursiveCachingIterator(
new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::KEY_AS_FILENAME
),
CachingIterator::CALL_TOSTRING|CachingIterator::CATCH_GET_CHILD
),
parent::SELF_FIRST
);
}
/** @return the current element prefixed with ASCII graphics
*/
function current() {
$tree = '';
for ($l=0; $l < $this->getDepth(); $l++) {
$tree .= $this->getSubIterator($l)->hasNext() ? ' ' : ' ';
}
return $tree . ($this->getSubIterator($l)->hasNext() ? ' ' : ' ')
. $this->getSubIterator($l)->__toString();
}
/** Aggregates the inner iterator
*/
function __call($func, $params) {
return call_user_func_array(array($this->getSubIterator(), $func), $params);;
}
}
为了澄清我为什么使用上面的代码,因为它完全符合我的需求。我想生成一个以空格为前缀的递归目录树 - Marcus Boerger 的原始代码示例添加了一些 ASCI 元素。问题是我无法控制文件和目录的排序,所以我希望目录树显示如下:
dir001
subdir001
subdir002
subfile001.jpg
file001.png
file002.png
file003.png
dir002
apple.txt
bear.txt
contact.txt
dir003
[...]
相反,迭代器返回的列表根本没有排序,它向我显示了类似这样的内容:
dir002
bear.txt
apple.txt
contact.txt
dir001
subdir001
subdir002
subfile001.jpg
file002.png
file001.png
file003.png
dir003
[...]
所以我想我正在寻找的解决方案是每次索引子目录并将其添加到目录树时调用排序方法的某种方法。
我希望我已经说得更清楚了,作为一个非母语人士,有时很难将想法放入连贯的句子(甚至是与此相关的单词)中。
I found a couple of questions (this one and this question) related to the SPL iterators, but I'm not sure if they're helpful in my case, as I'm using a rather high level extension of the RecursiveIteratorIterator
; the DirectoryTreeIterator
.
Could somebody perhaps show me how to alter the DirectoryTreeIterator
or how to sort the returned array per directory after it has been outputted by the iterator?
A method of sorting the files correctly directly on the Apache server is also an option for me, if it's possible using .htaccess
for example.
This is the code of DirectoryTreeIterator
from the SPL:
/** @file directorytreeiterator.inc
* @ingroup Examples
* @brief class DirectoryTreeIterator
* @author Marcus Boerger
* @date 2003 - 2005
*
* SPL - Standard PHP Library
*/
/** @ingroup Examples
* @brief DirectoryIterator to generate ASCII graphic directory trees
* @author Marcus Boerger
* @version 1.1
*/
class DirectoryTreeIterator extends RecursiveIteratorIterator
{
/** Construct from a path.
* @param $path directory to iterate
*/
function __construct($path) {
parent::__construct(
new RecursiveCachingIterator(
new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::KEY_AS_FILENAME
),
CachingIterator::CALL_TOSTRING|CachingIterator::CATCH_GET_CHILD
),
parent::SELF_FIRST
);
}
/** @return the current element prefixed with ASCII graphics
*/
function current() {
$tree = '';
for ($l=0; $l < $this->getDepth(); $l++) {
$tree .= $this->getSubIterator($l)->hasNext() ? ' ' : ' ';
}
return $tree . ($this->getSubIterator($l)->hasNext() ? ' ' : ' ')
. $this->getSubIterator($l)->__toString();
}
/** Aggregates the inner iterator
*/
function __call($func, $params) {
return call_user_func_array(array($this->getSubIterator(), $func), $params);;
}
}
To clarify why I'm using the code above is because it fits my needs exactly. I want to generate a recursive directory tree prefixed by whitespaces - the original code example by Marcus Boerger adds some ASCI elements. The problem is I don't have control over the sorting of files and directories, so I would like the directory tree to appear like this:
dir001
subdir001
subdir002
subfile001.jpg
file001.png
file002.png
file003.png
dir002
apple.txt
bear.txt
contact.txt
dir003
[...]
Instead, the listings returned by the iterator isn't sorted at all and it shows me something like this:
dir002
bear.txt
apple.txt
contact.txt
dir001
subdir001
subdir002
subfile001.jpg
file002.png
file001.png
file003.png
dir003
[...]
So I guess the solution I'm looking for is some way to call a sort method every time a subdirectory is indexed and added to the directory tree.
I hope I've made it somewhat clearer, as a nonnative speaker it's sometimes hard to put thoughts into coherent sentences (or even words for that matter).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好吧,我不确定你从哪里得到这个类,但它做了一些非常混乱的事情(至少可以说包括一些错误)。虽然它使用 SPL,但它不是 SPL 类。
现在,我不是 100% 确定“排序”是什么意思,但假设您正在谈论自然排序,为什么不直接展平数组,然后对其进行排序呢?
或
编辑:根据您的编辑,我将如何解决它:
这是一个非常简单的递归解析器,并且在每个级别上进行自然排序。
Well, I'm not sure where you got that class from, but it's doing some pretty messed up things (including a few bugs to say the least). And while it uses SPL, it's not an SPL class.
Now, I'm not 100% sure what you mean by "sort", but assuming you're talking about a natural sort, why not just flatten an array, and then sort it?
or
Edit: Based on your edit, here's how I would solve it:
It's a pretty simple recursive parser, and does the natural sort on each level.
不了解 SPL 迭代器,但对于迭代器,您应该将项目放入数组中,然后对它们进行排序并将它们添加到 $tree 中。我修改了函数current但没有测试它:
Don't know about SPL iterators, but for your iterator you should put the items in an array, then sort them and add them to $tree. I modified the function current but didn't test it: