Приветствую! Сегодня я хотел бы поделится решением проблемы поиска файлов с которой мне пришлось столкнутся по работе.

Описание проблемы.

Передо мной стояла задача получить список файлов(путей) в какой то определенной директории. Результат должен иметь вид массива который я смог бы в дальнейшем перебрать.

Случай был не самый простой и я приступил к реализации решения.

Решение.

Далее я распишу ход процесса и буду снабжать участки кода комментариями.

Начинаем мы с того что получим путь до нужной нам директории. Методы получения пути до нее у вас могут отличаться.

$dirPath = $_SERVER['DOCUMENT_ROOT'].'/uploads/needle_dir';

Путь по которому будем искать файлы у нас есть, теперь приступим к написанию функции для поиска по этому пути.

Для начала мы создадим массив в который будут помещаться наши пути до файлов. Этот массив будет динамически наполняться нашей функцией в процессе обхода директории.

Для этого нам необходимо передать в функцию сам путь и созданный ранее массив. Для того чтобы все складывалось в ранее созданный массив необходимо указать ссылку на него в параметрах функции.

Вот как это выглядит:

function findFilesFromDirectory($path, &$files)
{

}
$dirPath = $_SERVER['DOCUMENT_ROOT'].'/uploads/needle_dir';
$files = [];
findFilesFromDirectory($dirPath, $files);

Итак. Каркас функции у нас есть, приступим к её наполнению.
Для начала нам нужно проверять имеющийся у нас путь на то является он директорией или файлом.

function findFilesFromDirectory($path, &$files)
{
        if (is_dir($path)) {
            //если переданный путь является директорией то мы продолжаем проверку
        } else if (is_file($path)) {
            //если же это файл то возвращаем путь до него.
            return $path;
	}
}

Предположим что наш путь является папкой, далее на нужно разбить этот путь на входящие в него файлы и папки.
В этом нам может помочь отличная php функция scandir ($path). Она анализирует переданный путь и возвращает массив содержащий в себе названия папой и файлов находящихся по переданному пути.

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

В нашем случае они не нужны и мы удаляем их из результата работы scandir ($path).

function findFilesFromDirectory($path, &$files)
{
        if (is_dir($path)) {
            $cleanPath = array_diff(scandir($path), array('.', '..'));
        } else if (is_file($path)) {
            return $path;
	}
}

Теперь у нас есть массив содержащий данные вида: ['files' , 'file.js' , 'index.html']. Нас это устраивает и мы можем переходить к этапу перебора этого массива.

function findFilesFromDirectory($path, &$files)
{
        if (is_dir($path)) {
            $cleanPath = array_diff(scandir($path), array('.', '..'));
            foreach ($cleanPath as $file) {
            	/* Соединяем $file с изначальным путем чтобы получить строку вида:
            	* urltodir/files/morefiles
            	*/
            	$finalPath = $path. '/' . $file;
            }
        } else if (is_file($path)) {
            return $path;
	}
}

Теперь у нас есть новый путь до папки в которой мы ищем файлы и нам остается только повторить поиск по новому пути и сохранять результат в массив ссылку на который мы передаем в параметры функции.

function findFilesFromDirectory($path, &$files)
{
        if (is_dir($path)) {
            $cleanPath = array_diff(scandir($path), array('.', '..'));
            foreach ($cleanPath as $file) {
            	$finalPath = $path. '/' . $file;
            	//Тут мы рекурсивно вызываем нашу функцию и передаем ей свежий путь до папки
            	$result = $this->findFilesFromDirectory($finalPath, $files);
            	/* Проверяем на то не вернул ли результат null,
            	* если нет то создаем новый элемент массива с путем до файла.
            	*/
                if (!is_null($result)) $files[] = $result;
            }
        } else if (is_file($path)) {
            return $path;
	}
}

Теперь после каждого обхода функции будет создаваться новый путь до папки пока функция не переберёт весь каталог и входящие в него папки. После выполнения работы данной функции мы можем перебрать получившийся массив $files  и получить нужные нам пути до файлов.

В конечно итоге наша конструкция будет выглядеть так:

function findFilesFromDirectory($path, &$files)
    {
        if (is_dir($path)) {
            $cleanPath = array_diff(scandir($path), array('.', '..'));
            foreach ($cleanPath as $file) {
                $finalPath = $path . '/' . $file;
                $result = $this->findFilesFromDirectory($finalPath, $files);
                if (!is_null($result)) $files[] = $result;
            }
        } else if (is_file($path)) {
            return $path;
        }
    }
$dirPath = $_SERVER['DOCUMENT_ROOT'].'/uploads/needle_dir';
$files = [];
$this->findFilesFromDirectory($dirPath, $files);
foreach ($files as $file){
    echo $file; // urltodir/files/somedirectory/file.js
}

На этом пожалуй все. Надеюсь мой опыт будет вам полезен. Успехов!

dmkweb.ru Права на контент защищены.