Сортировка списка каталогов с помощью RecursiveDirectoryIterator - PullRequest
13 голосов
/ 28 мая 2010

Я использую RecursiveDirectoryIterator и RecursiveIteratorIterator для построения дерева списка файлов, используя код, как показано ниже. Мне нужно, чтобы список был отсортирован - или каталоги, и файлы по алфавиту, или просто по алфавиту.

Может кто-нибудь сказать мне, как отсортировать список файлов?

$dir_iterator = new RecursiveDirectoryIterator($groupDirectory);
$iterator = new RecursiveIteratorIterator($dir_iterator, RecursiveIteratorIterator::SELF_FIRST);
foreach ($iterator as $file) {
    // do stuff with $file
}

Ответы [ 3 ]

23 голосов
/ 29 мая 2010

Доступно несколько опций, которые вы можете использовать для сортировки итератора тем или иным способом. Лучший вариант будет во многом зависеть от того, как именно вы хотите манипулировать содержимым итератора, что вы хотите получить от итератора и, действительно, сколько или мало того итератора вам действительно нужно / нужно.

Подходы будут отличаться; используя классы типа SplHeap (или Min, Max разновидностей), SplPriorityQueue (возможно, для таких вещей, как размер файла) или просто оборачивая ваш итератор во что-то вроде ArrayObject, которое может сортировать свое собственное содержимое. 1008 *

Я буду использовать SplHeap в качестве примера. Поскольку вы хотите расположить все содержимое RecursiveDirectoryIterator в алфавитном порядке, можно использовать что-то вроде следующего:

class ExampleSortedIterator extends SplHeap
{
    public function __construct(Iterator $iterator)
    {
        foreach ($iterator as $item) {
            $this->insert($item);
        }
    }
    public function compare($b,$a)
    {
        return strcmp($a->getRealpath(), $b->getRealpath());
    }
}

$dit = new RecursiveDirectoryIterator("./path/to/files");
$rit = new RecursiveIteratorIterator($dit);
$sit = new ExampleSortedIterator($rit);
foreach ($sit as $file) {
    echo $file->getPathname() . PHP_EOL;
}

Порядок сортировки в алфавитном порядке, смешивание файлов и папок:

./apple
./apple/alpha.txt
./apple/bravo.txt
./apple/charlie.txt
./artichoke.txt
./banana
./banana/aardvark.txt
./banana/bat.txt
./banana/cat.txt
./beans.txt
./carrot.txt
./cherry
./cherry/amy.txt
./cherry/brian.txt
./cherry/charlie.txt
./damson
./damson/xray.txt
./damson/yacht.txt
./damson/zebra.txt
./duck.txt
1 голос
/ 28 мая 2010

Это невозможно при использовании самого итератора. Я видел расширение класса Iterator где-то на SO, которое выполняло сортировку, но помнил, что у него были проблемы с ним.

Может быть, ответы на этот вопрос помогут, даже если они указывают на итератор?

Обновление : Здесь - обман на ваш вопрос с некоторыми ответами - правда, не так много!

0 голосов
/ 26 октября 2011

Sönke Ruempler предлагает отличное решение:

class SortingIterator implements IteratorAggregate
{

        private $iterator = null;

        public function __construct(Traversable $iterator, $callback)
        {
                if (!is_callable($callback)) {
                        throw new InvalidArgumentException('Given callback is not callable!');
                }

                $array = iterator_to_array($iterator);
                usort($array, $callback);
                $this->iterator = new ArrayIterator($array);
        }


        public function getIterator()
        {
                return $this->iterator;
        }
}

Источник: http://www.ruempler.eu/2008/08/09/php-sortingiterator

...