Компонент Поисковик

Компонент Поисковик находит файлы и каталоги через интуитивно свободный интерфейс.

Установка

Вы можете установить компонент 2 разными способами:

Then, require the vendor/autoload.php file to enable the autoloading mechanism provided by Composer. Otherwise, your application won't be able to find the classes of this Symfony component.

Применение

Класс Finder находит файлы и / или каталоги:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
use Symfony\Component\Finder\Finder;

$finder = new Finder();
$finder->files()->in(__DIR__);

foreach ($finder as $file) {
    // Сбрасывает абсолютный путь
    var_dump($file->getRealPath());

    // Сбрасывает относительный путь к файлу, опустив имя файла
    var_dump($file->getRelativePath());

    // Сбрасывает относительный путь к файлу
    var_dump($file->getRelativePathname());
}

$file является экземпляром SplFileInfo, который расширяет собственный SplFileInfo PHP, чтобы предоставить методы для работы с относительными путями.

Код выше отображает имена всех файлов в текущем каталоге в обратном порядке. Класс Поисковика использует свободный интерфейс, так что все методы возвращают экземпляр Поисковика.

Tip

Экземпляр Поисковика - это Iterator. Так что в дополнение к итерации Поисковика с помощью foreach, вы также можете конвертировать его в массив методом iterator_to_array, или получить количество объектов с iterator_count.

Caution

Объект Finder не перезагружает внутреннее состояние автоматически. Это означает, что вам нужно создать новый экземпляр, если вы не хотите получить смешнанный результат.

Caution

При поиске в нескольких локациях, переданных методу in(), для каждой локации внутренне создаётся отдельный итератор. Это означает, что у нас несколько наборов результатов собираются в один. Так как iterator_to_array использует ключи наборов результатов по умолчанию при конвертации в массив, некоторые ключи могут быть продублированы, а их значения - перезаписаны. Этого можно избежать передав false в качестве второго параметра iterator_to_array.

Критерии

Существует множество способов фильтровать и сортировать ваши результаты. Вы можете также использовать метод hasResults(), чтобы проверить, существует ли файл или каталог, соответствующий критериям поиска.

Локация

Локация - единственный обязательный критерий. Она сообщает поискоивку, какой каталог использовать для поиска:

1
$finder->in(__DIR__);

Искать в нескльких локациях, изменяя вызов на in():

1
2
3
4
5
// искать внутри *обоих* каталогов
$finder->in(array(__DIR__, '/elsewhere'));

// то же, что и выше
$finder->in(__DIR__)->in('/elsewhere');

Используйте символы-заполнители, чтобы искать в каталогах, соответствующих шаблону:

1
$finder->in('src/Symfony/*/*/Resources');

Каждый шаблон должен разрешать как минимум один путь каталога.

Исключить каталоги, совпадающие с методом :method:`Symfony\Component\Finder\Finder::exclude`^^

// каталоги, переданные в качестве аргумента, должны быть связаны с теми, что определены в методе in() $finder->in(__DIR__)->exclude('ruby');

Также возможно игнорировать каталоги, на чтение которых у вас нет разрешения:

1
$finder->ignoreUnreadableDirs()->in(__DIR__);

Так как Поисковик использует PHP итераторы, вы можете передать любой URL, поддерживаемым protocol:

1
2
3
4
5
// всегда добавляйте закрывающий слеш, когда ищете dir корна FTP
$finder->in('ftp://example.com/');

// вы можете также искать в каталоге FTP
$finder->in('ftp://example.com/pub/');

И это также работает с потоками, определёнными пользователями:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
use Symfony\Component\Finder\Finder;

$s3 = new \Zend_Service_Amazon_S3($key, $secret);
$s3->registerStreamWrapper('s3');

$finder = new Finder();
$finder->name('photos*')->size('< 100K')->date('since 1 hour ago');
foreach ($finder->in('s3://bucket-name') as $file) {
    // ... сделать что-то с файлом
}

Note

Простите документацию Потоки, чтобы узнать, как создавать собственные потоки.

Файлы или каталоги

По умолчанию, Поисковик возвращает файлы и каталоги; но методы files() и directories() контролируют это:

1
2
3
$finder->files();

$finder->directories();

Если вы хотите следовать ссылкам, используйте метод followLinks():

1
$finder->files()->followLinks();

По умолчанию, итератор игнорирует поплуярные VCS файлы. Это можно изменить методом ignoreVCS():

1
$finder->ignoreVCS(false);

Сортировка

Сортируйте результат по имени или типу (вначале каталоги, потом файлы):

1
2
3
$finder->sortByName();

$finder->sortByType();

Note

Отметьте, что методы sort* должны получить все совпадающие элементы, чтобы делать свою работу. В случае с большими итераторами, это долго.

Вы также можете определять собственные алгоритмы сортировки методом sort():

1
2
3
4
5
6
$sort = function (\SplFileInfo $a, \SplFileInfo $b)
{
    return strcmp($a->getRealPath(), $b->getRealPath());
};

$finder->sort($sort);

Имя файла

Ограничьте файлы по имени методом name():

1
$finder->files()->name('*.php');

Метод name() принимает маски, строки или регулярные выражения:

1
$finder->files()->name('/\.php$/');

Метод notName() исключает файлы, совпадающие со схемой:

1
$finder->files()->notName('*.rb');

Содержание файла

Ограничьте файлы по содержанию, методом contains():

1
$finder->files()->contains('lorem ipsum');

Метод contains() принимает строки или регулярные выражения:

1
$finder->files()->contains('/lorem\s+ipsum$/i');

Метод notContains() исключает файлы, содержащие заданную схему:

1
$finder->files()->notContains('dolor sit amet');

Путь

Ограничьте файлы и папки по пути, методом path():

1
2
3
4
// сопоставляет файлы, содержащие "data" где-либо в их путях (файлах или каталогах)
$finder->path('data');
// например, это будет соответстсовать data/*.xml и data.xml, если они существуют
$finder->path('data')->name('*.xml');

На всех платформах слеш (т.е. /) нужно использвать как разделитель каталогов.

Метод path() принимает строку или регулярное выражение:

1
2
$finder->path('foo/bar');
$finder->path('/^foo\/bar/');

Внутренне, строки преобразуются в регулярные выражения, экранируя слеши и добавляя разграничители:

1
2
dirname    ===>    /dirname/
a/b/c      ===>    /a\/b\/c/

Метод notPath() исключает файлы по пути:

1
$finder->notPath('other/dir');

Размер файла

Ограничьте файлы по размеру, методом size():

1
$finder->files()->size('< 1.5K');

Ограничьте по диапазону размера, изменив вызовы:

1
$finder->files()->size('>= 1K')->size('<= 2K');

Оператор сравнения может быть чем-либо из следующего: >, >=, <, <=, ==, !=.

Целевое значение может использовать величины килобайтов (k, ki), мегабайтов (m, mi), или гигабайтов (g, gi). Те, что имеют суффикс i, используют соответствующую версию 2**n в соответствии со `стандартом IEC`_.

Данные файла

Ограничьте файлы по датам последних изменений, методом date()

1
$finder->date('since yesterday');

Оператор сравнения может быть любым из следующих: >, >=, <, <=, ==. Вы можете также использовать since или after в качестве дополнительного имени >, и until или before в качестве дополнительного имени <.

Целевое значение может быть любыми данными, поддерживаемыми функцией strtotime.

Глубина каталога

По умолчанию, Поисковик траверсирует каталоги в обратном порядке. Ограничьте глубину траверсирования методом depth():

1
2
$finder->depth('== 0');
$finder->depth('< 3');

Пользовательское фильтрование

Чтобы ограничить совпадающий файл вашей собственной стратегией, используйте filter():

1
2
3
4
5
6
7
8
$filter = function (\SplFileInfo $file)
{
    if (strlen($file) > 10) {
        return false;
    }
};

$finder->files()->filter($filter);

Метод filter() берёт Closure в качестве аргумента. Для каждого совпадающего файла, он вызываетя с файлом SplFileInfo в качестве экземпляра. Файл исключается из набора результатов, если замыкание возвращает false.

Чтение содержания возвращённых файлов

Содержание возвращённых файлов можно прочитать с помощью getContents():

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
use Symfony\Component\Finder\Finder;

$finder = new Finder();
$finder->files()->in(__DIR__);

foreach ($finder as $file) {
    $contents = $file->getContents();

    // ...
}

Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.