#php #symfony #iterator #symfony-finder
Вопрос:
Следующий код возвращает разные результаты в двух средах (которые, однако, должны были быть как можно ближе друг к другу: одна и та же версия PHP и т. Д.).
/var/www/html/project/vendor/package/path/to/some/folder
Каталог содержит точно такой же набор файлов в обеих средах. Сами файлы были помещены туда composer
.
use SymfonyComponentFinderFinder;
// Don't mind this. The real app uses an autoloading mechanism.
require __DIR__ . '/../vendor/symfony/finder/Finder.php';
require __DIR__ . '/../vendor/symfony/finder/SplFileInfo.php';
require __DIR__ . '/../vendor/symfony/finder/Iterator/FilterIterator.php';
require __DIR__ . '/../vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php';
require __DIR__ . '/../vendor/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php';
require __DIR__ . '/../vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php';
require __DIR__ . '/../vendor/symfony/finder/Iterator/PathFilterIterator.php';
require __DIR__ . '/../vendor/symfony/finder/Iterator/FilenameFilterIterator.php';
require __DIR__ . '/../vendor/symfony/finder/Iterator/FileTypeFilterIterator.php';
$path = '/var/www/html/project/vendor/package/path/to/some/folder';
$path = Finder::create()->files()->followLinks()->name('/.(php|inc|hh)$/')->in($path);
$iterator = $path->getIterator();
$iterator->rewind();
$current = $iterator->current();
echo $current->getRelativePathname();
Это не случайно. Результаты согласуются в одной среде. Но в любой среде отображается другое имя пути. Мне удалось проследить его до родного PHP: FilterIterator::rewind
, но я не уверен, что здесь проблема в перемотке.
Комментарии:
1. Подразумевает ли какая-либо документация, что вы будете извлекать имена файлов в каком-либо определенном порядке?
2. @NigelRen Нет, я не смог найти такую информацию ни в одном из них.
3. Лично я бы предположил, что к ним не применяется конкретный порядок. Это может быть просто порядок записей в файловой системе или какая-то другая внутренняя вещь. При необходимости может быть безопасно применить вашу собственную сортировку.
Ответ №1:
Для компонента Finder не существует определенного порядка «по умолчанию».
Итератор Finder ( SymfonyComponentFinderIteratorRecursiveDirectoryIterator
) распространяется на ядро RecursiveDirectoryIterator
, которое не определяет порядок по умолчанию (или способ «установить» порядок). Таким образом, заказ не является гарантированно определенным или гарантированным. Он сильно зависит от системы и файловой системы, и на него не следует полагаться.
Если вам нужен надежный, согласованный порядок сортировки, просто используйте соответствующие sort*()
методы в экземпляре Finder. Это приведет к тому , что при вызове результат будет помещен в getIterator()
сортировщик, и результаты будут упорядочены предсказуемым образом.
Комментарии:
1. Я пришел к тому же выводу. Порядок файлов-это «порядок каталогов» (в основном то, что вы получаете при вводе
ls -U
). Это зависит от файловой системы, и вы не можете полагаться на нее.