Компонент Finder в Symfony находит файлы и каталоги на основе различных критериев (имя, размер файла, время модификации и т.д.) Через интуитивно понятный интерфейс.
Установка.
composer require symfony/finder
Если вы устанавливаете этот компонент вне приложения Symfony, вам потребуется файл vendor/autoload.php в вашем коде, чтобы включить механизм автозагрузки классов, предоставляемый Composer.
Использование.
Класс Finder ищет файлы и/или директории:
use Symfony\Component\Finder\Finder;
$finder = new Finder();
// ищет все файлы в текущей директории
$finder->files()->in(__DIR__);
// проверка, что есть результаты поиска
if ($finder->hasResults()) {
// ...
}
foreach ($finder as $file) {
$absoluteFilePath = $file->getRealPath();
$fileNameWithExtension = $file->getRelativePathname();
// ...
}
Переменная $file является экземпляром SplFileInfo, который расширяет собственный SplFileInfo PHP для предоставления методов для работы с относительными путями.
Объект Finder не сбрасывает свое внутреннее состояние автоматически. Это означает, что вам нужно создать новый экземпляр, если вы не хотите получать смешанные результаты.
Поиск файлов и каталогов.
Компонент предоставляет множество методов для определения критериев поиска. Все они могут быть объединены в цепочку, потому что они реализуют fluent interface.
Место поиска (Location).
Расположение файла является единственным обязательным критерием. Он сообщает Finder, какой каталог использовать для поиска:
$finder->in(__DIR__);
Поиск в нескольких местах осуществляется с помощью цепочки вызовов метода in():
// search inside *both* directories
$finder->in([__DIR__, '/elsewhere']);
// same as above
$finder->in(__DIR__)->in('/elsewhere');
Используйте * в качестве подстановочного символа для поиска в каталогах, соответствующих шаблону (каждый шаблон должен иметь как минимум один путь к каталогу):
$finder->in('src/Symfony/*/*/Resources');
Исключить каталоги из соответствия можно с помощью метода exclude():
// каталоги, передаваемые в качестве аргумента, должны быть относительно тех, которые определены методом in()
$finder->in(__DIR__)->exclude('ruby');
Также возможно игнорировать каталоги, на которые у вас нет разрешения на чтение:
$finder->ignoreUnreadableDirs()->in(__DIR__);
Поскольку Finder использует итераторы PHP, вы можете передавать любой URL-адрес с поддерживаемой оболочкой PHP для протоколов в стиле URL (ftp: //, zlib: // и т. д.):
// всегда добавляйте слеш при поиске в корневом каталоге FTP
$finder->in('ftp://example.com/');
// вы также можете искать вконкретном каталоге FTP
$finder->in('ftp://example.com/pub/');
И это также работает с пользовательскими потоками:
use Symfony\Component\Finder\Finder;
// register a 's3://' wrapper with the official AWS SDK
$s3Client = new Aws\S3\S3Client([/* config options */]);
$s3Client->registerStreamWrapper();
$finder = new Finder();
$finder->name('photos*')->size('< 100K')->date('since 1 hour ago');
foreach ($finder->in('s3://bucket-name') as $file) {
// ... do something with the file
}
Прочитайте документацию по потокам PHP, чтобы узнать, как создавать свои собственные потоки.
Файлы или каталоги.
По умолчанию Finder возвращает файлы и каталоги; но методы files() и directoryies() помогают корректировать это поведение:
// look for files only; ignore directories
$finder->files();
// look for directories only; ignore files
$finder->directories();
Если вы хотите переходить по символическим ссылкам, используйте метод followLinks():
Файлы контроля версий.
Системы контроля версий (или сокращенно «VCS»), такие как Git и Mercurial, создают некоторые специальные файлы для хранения своих метаданных. Эти файлы по умолчанию игнорируются при поиске файлов и каталогов, но вы можете изменить это с помощью метода ignoreVCS():
$finder->ignoreVCS(false);
Имена файлов.
Чтобы найти файлы по имени используется метод name():
$finder->files()->name('*.php');
Метод name() принимает строки, регулярные выражения или массив строк или регулярных выражений:
$finder->files()->name('/\.php$/');
Несколько имен файлов могут быть определены цепочкой вызовов или передачей массива:
$finder->files()->name('*.php')->name('*.twig');
// такой же результат как выше
$finder->files()->name(['*.php', '*.twig']);
Метод notName() исключает файлы, соответствующие шаблону:
$finder->files()->notName('*.rb');
Несколько имен файлов могут быть исключены путем объединения вызовов или передачи массива:
$finder->files()->notName('*.rb')->notName('*.py');
// same as above
$finder->files()->notName(['*.rb', '*.py']);
Содержимое файла.
Находите файлы по содержимому с помощью метода contains():
$finder->files()->contains('lorem ipsum');
Метод contains() поддерживает строки или регулярные выражения:
$finder->files()->contains('/lorem\s+ipsum$/i');
Метод notContains() исключает файлы, содержащие переданный шаблон:
$finder->files()->notContains('dolor sit amet');
Пути к файлам.
Находите файлы и каталоги по нужному пути с помощью метода path():
// сопоставляет файлы, которые содержат «data» в любом месте своего пути (файлы или каталоги)
$finder->path('data');
// например, это будет соответствовать data/*.xml или data.xml, если они существуют
$finder->path('data')->name('*.xml');
Используйте слеш (т.е. /) в качестве разделителя каталогов на всех платформах, включая Windows. Компонент производит необходимые преобразования внутри автоматически.
Метод path() принимает строку, регулярное выражение или массив строк или регулярных выражений:
$finder->path('foo/bar');
$finder->path('/^foo\/bar/');
Несколько путей могут быть определены цепочкой вызовов или передачей массива:
$finder->path('data')->path('foo/bar');
// same as above
$finder->path(['data', 'foo/bar']);
Метод notPath() исключает файлы по пути:
$finder->notPath('other/dir');
Несколько путей могут быть исключены путем объединения вызовов или передачи массива:
$finder->notPath('first/dir')->notPath('other/dir');
// same as above
$finder->notPath(['first/dir', 'other/dir']);
Размер файла.
Ищите файлы по размеру с помощью метода size() :
$finder->files()->size('< 1.5K');
Ограничивайте диапазон размеров путем объединения вызовов или передачи массива:
$finder->files()->size('>= 1K')->size('<= 2K');
// same as above
$finder->files()->size(['>= 1K', '<= 2K']);
Оператор сравнения может быть любым из следующих:>,> =, <, <=, ==,! =.
Целевое значение может использовать величины в килобайтах (k, ki), мегабайтах (m, mi) или гигабайтах (g, gi). Те, с суффиксом i, используют соответствующую версию 2 ** n в соответствии со стандартом IEC.
Даты файлов.
Можете искать нужные файлы по дате их последней модификации с помощью метода date() :
$finder->date('since yesterday');
Ограничение диапазоном дат путем объединения вызовов или передачи массива:
$finder->date('>= 2018-01-01')->date('<= 2018-12-31');
// same as above
$finder->date(['>= 2018-01-01', '<= 2018-12-31']);
Оператор сравнения может быть любым из следующих:>,> =, <, <=, ==. Вы также можете использовать с или после в качестве псевдонима для>, и до или до того, как псевдоним для <.
Целевым значением может быть любая дата, поддерживаемая strtotime.
Глубина вложенности директорий.
По умолчанию Finder рекурсивно пересекает каталоги. Ограничьте глубину перемещения с помощью метода depth():
$finder->depth('== 0');
$finder->depth('< 3');
Ограничение диапазоном глубины путем объединения вызовов или передачи массива:
$finder->depth('> 2')->depth('< 5');
// same as above
$finder->depth(['> 2', '< 5']);
Пользовательская фильтрация.
Чтобы отфильтровать результаты по вашей собственной стратегии, используйте метод filter():
$filter = function (\SplFileInfo $file)
{
if (strlen($file) > 10) {
return false;
}
};
$finder->files()->filter($filter);
Метод filter () принимает Closure в качестве аргумента. Для каждого соответствующего файла он вызывается вместе с файлом как экземпляр SplFileInfo. Файл исключается из результирующего набора, если Closure возвращает false.
Сортировка результатов
Сортируйте результаты по имени или по типу (сначала каталоги, а затем файлы):
$finder->sortByName();
$finder->sortByType();
По умолчанию метод sortByName () использует PHP-функцию strcmp (например, file1.txt, file10.txt, file2.txt). Передайте true в качестве аргумента, чтобы вместо этого использовать естественный алгоритм сортировки PHP (например, file1.txt, file2.txt, file10.txt).
Сортируйте файлы и каталоги по времени последнего доступа или изменения, или даты модификации:
$finder->sortByAccessedTime();
$finder->sortByChangedTime();
$finder->sortByModifiedTime();
Вы также можете определить свой собственный алгоритм сортировки с помощью метода sort():
$finder->sort(function (\SplFileInfo $a, \SplFileInfo $b) {
return strcmp($a->getRealPath(), $b->getRealPath());
});
Вы можете отменить любую сортировку, используя метод reverseSorting ():
// results will be sorted "Z to A" instead of the default "A to Z"
$finder->sortByName()->reverseSorting();
Обратите внимание, что методы sort * должны получить все соответствующие элементы для выполнения своей работы. Для больших итераторов это медленно.
Преобразование результатов в массивы.
Экземпляр Finder — это PHP-класс IteratorAggregate. Таким образом, помимо итерации результатов Finder с помощью foreach, вы также можете преобразовать его в массив с помощью функции iterator_to_array или получить количество элементов с помощью iterator_count.
Если вы вызываете метод in() более одного раза для поиска по нескольким местоположениям, передайте false в качестве второго параметра iterator_to_array, чтобы избежать проблем (для каждого местоположения создается отдельный итератор и, если вы не передаете false в iterator_to_array, ключи наборов результатов используются, и некоторые из них могут быть дублированы, а их значения перезаписаны).
Чтение содержимого возвращаемых файлов.
Содержимое возвращенных файлов можно прочитать с помощью getContents():
use Symfony\Component\Finder\Finder;
$finder = new Finder();
$finder->files()->in(__DIR__);
foreach ($finder as $file) {
$contents = $file->getContents();
// ...
}