Сортировка списка каталогов с помощью RecursiveDirectoryIterator
Я использую RecursiveDirectoryIterator
и RecursiveIteratorIterator
для создания дерева списка файлов, используя следующий код. Мне нужно отсортировать список - либо каталоги, либо файлы в алфавитном порядке, либо просто в алфавитном порядке.
Может ли кто-нибудь сказать мне, как сортировать список файлов?
$dir_iterator = new RecursiveDirectoryIterator($groupDirectory);
$iterator = new RecursiveIteratorIterator($dir_iterator, RecursiveIteratorIterator::SELF_FIRST);
foreach ($iterator as $file) {
// do stuff with $file
}
Ответы
Ответ 1
Это невозможно с помощью самого Итератора. Я видел расширение класса Iterator
где-то на SO, которое сортировалось, но смутно помню, что у него были проблемы с ним.
Может быть, ответы на этот вопрос помогут, даже если они указывают на Итератор?
Обновить: Здесь является обманом вашего вопроса с некоторыми ответами - правда, не так много, хотя!
Ответ 2
Доступно несколько опций, которые вы можете использовать для сортировки итератора так или иначе. Лучший вариант будет очень зависеть от того, как вы хотите манипулировать содержимым итератора, из чего вы хотите выйти из итератора, и действительно, сколько или мало итератора вы действительно хотите/нуждаетесь.
Подходы будут варьироваться; используя классы типа SplHeap
(или Min
, Max
), SplPriorityQueue
(возможно, для таких вещей, как размер файла), или просто обертывание вашего итератора чем-то вроде ArrayObject
, которое может сортировать его собственное содержимое.
В качестве примера я использую 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
Ответ 3
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