使用SPL的DirectoryTreeIterator为每个目录排序文件 [英] Sorting files per directory using SPL's DirectoryTreeIterator

查看:141
本文介绍了使用SPL的DirectoryTreeIterator为每个目录排序文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现了几个问题(这一个这个问题)与SPL相关迭代器,但我不确定它们是否对我的情况有帮助,因为我使用的是 RecursiveIteratorIterator 的相当高级别的扩展; DirectoryTreeIterator

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.

有人可能会告诉我如何更改 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?

直接在Apache服务器上正确排序文件的方法是如果可以使用 .htaccess ,我也可以选择。

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.

这是<$的代码来自SPL的c $ c> 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元素。问题是我无法控制文件和目录的排序,所以我希望目录树看起来像这样:

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).

推荐答案

嗯,我是不知道你从哪里上课,但它正在做一些相当混乱的事情(包括一些错误至少可以说)。虽然它使用SPL,但它不是SPL类。

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.

现在,我不是100%肯定你的意思是排序,但假设你在谈论一种自然的排序,为什么不只是压平一个阵列,然后对它进行排序?

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?

$it = new RecursiveTreeIterator(
    new RecrusiveDirectoryIterator($dir),
    RecursiveTreeIterator::BYPASS_KEY,
    CachingIterator::CALL_TOSTRING
);
$files = iterator_to_array($it);
natsort($files);
echo implode("\n", $files);

$it = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($dir),
    RecursiveIteratorIterator::SELF_FIRST
);
$files = iterator_to_array($it);
$files = array_map(function($file) { return (string) $file; }, $files);
natsort($files);
echo implode("\n", $files);

编辑:根据您的编辑,以下是我将如何解决此问题:

Based on your edit, here's how I would solve it:

function BuildTree($it, $separator = '  ', $level = '') {
    $results = array();
    foreach ($it as $file) {
        if (in_array($file->getBasename(), array('.', '..'))) {
            continue;
        }
        $tmp = $level . $file->getBaseName();
        if ($it->hasChildren()) {
            $newLevel = $level . $separator;
            $tmp .= "\n" . BuildTree($it->getChildren(), $separator, $newLevel);
        }
        $results[] = $tmp;
    }
    natsort($results);
    return implode("\n", $results);
};
$it = new RecursiveDirectoryIterator($dir);
$tree = BuildTree($it);

这是一个非常简单的递归解析器,并且在每个级别上进行自然排序。

It's a pretty simple recursive parser, and does the natural sort on each level.

这篇关于使用SPL的DirectoryTreeIterator为每个目录排序文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆