Reputation: 16803
I have a function which returns an array of files in a folder recursive.
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;
}
How can I modify this so that it always lists the root files first before any sub folders? At the moment by default the folders always come first.
Upvotes: 0
Views: 829
Reputation: 71414
You may want to take a look at the PHP SPL DirectoryIterator Class. You can instantiate the object and then quickly iterate over to segment out directories vs. files vs. links and get the full SplFileInfo object for each (which makes it really easy to get whatever info you want about the files).
$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;
}
}
Sorry just realized you wanted to do it recursively. Well for that use RecursiveDirectoryIterator , but concept is much the same.
Upvotes: 1
Reputation: 97707
Use two arrays one for the files in the current folder and one for the those in subfolders then merge them.
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);
}
Upvotes: 0
Reputation: 88697
Just create an array of sub-directories while you loop the directory pointer, and iterate the array of directories at the end:
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;
}
Upvotes: 0