#php #symfony #symfony4
#php #symfony #symfony4
Вопрос:
Я использую Symfony Finder
, чтобы получить все файлы с определенным расширением и все каталоги в определенном каталоге.
protected function getDirectoryContent(string $directory): array
{
$finder = Finder::create()
->in($directory)
->depth(0)
->name(['*.json', '*.php'])
->sortByName();
return iterator_to_array($finder, true);
}
Таким образом, этот метод возвращает только все файлы с расширением .php
или .json
в определенном каталоге. Например, структура каталогов, которую я ищу, выглядит следующим образом:
/my/directory/
├── A
├── A.JSON
├── anotherfile.kas
├── file0.ds
├── file1.json
├── file2.php
├── file3.php
├── B
└── C
A
, B
и C
являются каталогами.
Когда я передаю вышеуказанное directory path
в качестве $directory
аргумента в методе, который я показал выше, я получаю массив со следующими элементами:
file1.json
file2.php
file3.php
Отлично !, но мой вопрос в том, как я мог бы также добавить все directories
в результирующий массив? Я ожидаю получить массив, подобный следующему:
A
B
C
file1.json
file2.php
file3.php
Ответ №1:
В вашем случае вы обращаетесь к finder:
- Пожалуйста, добавьте рекурсивный итератор каталогов с глубиной 0 (все в порядке, мы хотим искать только в корне)
- Пожалуйста, добавьте итератор имен файлов (это неправильно, потому что вы находите только файлы).
В результате это неправильно, потому что эти два правила противоречат друг другу — потому что вы хотите искать только файлы.
Но symfony finder можно использовать CallbackIterator
с моделью фильтра. В этой ситуации вы можете добавить много правил или условий. В вашем примере:
namespace Acme;
use SymfonyComponentFinderFinder;
use SymfonyComponentFinderSplFileInfo;
include __DIR__.'/vendor/autoload.php';
$finder = Finder::create();
$finder
->in(__DIR__)
->depth(0)
->filter(static function (SplFileInfo $file) {
return $file->isDir() || preg_match('/.(php|json)$/', $file->getPathname());
});
print_r(iterator_to_array($finder));
В этом случае вы говорите:
- Пожалуйста, найдите только в root.
- Пожалуйста, проверьте — или файл или совпадение по моему шаблону.
Комментарии:
1. Спасибо! @ZhukV, я задал тот же вопрос в репозитории symfony на github, пользователь дал мне идею, но я не счел это очень хорошей идеей, поскольку с его решением я бы повторял 2 раза каждый каталог. github.com/symfony/symfony/issues/38949#issuecomment-720137475 . Мне кажется, что ваше решение намного эффективнее, поскольку оно будет проходить через каталог только один раз, а затем фильтровать полученный массив. Еще раз большое вам спасибо.