Компонент Finder в Symfony.

Компонент 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();

    // ...
}

Добавить комментарий

Ваш адрес email не будет опубликован.