Как на PHP скопировать директорию со всеми файлами

Стандартная функция copy в PHP умеет копировать только файл. Для копирования директориии со всем содержимым можно воспользоваться одним из следующих трюков:

 shell_exec("cp -r {$src} {$dest}");

Однако, что если нужно как-то дополнительно обработать сами файлы?

Возможно не самое лучшее решение, но самое элементарное — воспользоваться функцией  glob:

$files = glob("/var/www/app/storage/*");

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

$DirIterator = new RecursiveDirectoryIterator("/var/www/app/storage/");
$Iterator = new RecursiveIteratorIterator($DirIteratorRecursiveIteratorIterator::SELF_FIRST);

foreach($Iterator as $file) {
    echo $file"\n";
}

Данный код возвратит все файлы и директории с неограниченным уровнем вложенности, но есть нюанс: в списке файлов вы получите также и «.» и «..» директории, которые нужно будет отфильтровать.

Ещё один вариант — заморочиться и сделать рекурсивную версию функции glob:

function glob_recursive($pattern, $flags = 0) {
	$files = glob($pattern, $flags);
	foreach(glob(dirname($pattern) . '/*', GLOB_ONLYDIR | GLOB_NOSORT) as $dir) {
		$files = array_merge($files, glob_recursive($dir . '/' . basename($pattern), $flags) );
	}
	return $files;
}