Opendir получить массив файлов перед файлами в подпапке
У меня есть функция, которая возвращает массив файлов в папке рекурсивной.
protected function getFiles($base) {
$files = array();
if(!is_dir($base)) return $files;
if (($handle = opendir($base)) != false) {
while (false !== ($file = readdir($handle))) {
if ($file == "." || $file == "..") continue;
if(is_dir("$base/$file")) {
$subfiles = $this->getFiles("$base/$file");
$files = array_merge($files, $subfiles);
} else {
if(File::type($file,false) == "xml")
$files[] = "$base/$file";
}
}
closedir($handle);
}
return $files;
}
Как я могу изменить это так, чтобы он всегда перечислял корневые файлы перед любыми подпапками? На данный момент по умолчанию папки всегда на первом месте.
3 ответа
Просто создайте массив подкаталогов, пока вы зацикливаете указатель каталога, и итерируйте массив каталогов в конце:
protected function getFiles($base) {
$files = $dirs = array();
if(!is_dir($base)) return $files;
if (($handle = opendir($base)) != false) {
while (false !== ($file = readdir($handle))) {
if ($file == "." || $file == "..") continue;
if(is_dir("$base/$file")) {
$dirs[] = "$base/$file";
} else {
if(File::type($file,false) == "xml")
$files[] = "$base/$file";
}
}
closedir($handle);
foreach ($dirs as $dir) {
$subfiles = $this->getFiles($dir);
$files = array_merge($files, $subfiles);
}
}
return $files;
}
Вы можете взглянуть на класс PHP SPL DirectoryIterator. Вы можете создать экземпляр объекта, а затем быстро выполнить итерацию для сегментирования каталогов, файлов и ссылок и получить полный объект SplFileInfo для каждого (что позволяет действительно легко получить любую информацию о файлах, которую вы хотите).
$directory = '/path/to/directory';
$iterator = new DirectoryIterator($directory);
$dirs = array();
$files = array();
$links = array();
foreach($iterator as $obj) {
if($obj->isFile()) {
$files[] = $obj;
} else if ($obj->isDir()) {
$dirs[] = $obj;
} else if ($obj->isLink()) {
$links[] = $obj;
}
}
Извините, только что понял, что вы хотите сделать это рекурсивно. Хорошо, для этого используйте RecursiveDirectoryIterator, но концепция почти такая же.
Используйте два массива, один для файлов в текущей папке и один для тех, что в подпапках, затем объедините их.
protected function getFiles($base) {
$files = array();
$subFiles = array();
if(!is_dir($base)) return $files;
if (($handle = opendir($base)) != false) {
while (false !== ($file = readdir($handle))) {
if ($file == "." || $file == "..") continue;
if(is_dir("$base/$file")) {
$subFiles = array_merge($subFiles, $this->getFiles("$base/$file"));
} else {
if(File::type($file,false) == "xml")
$files[] = "$base/$file";
}
}
closedir($handle);
}
return array_merge($files, $subFiles);
}