Reputation: 9606
What is the best way of getting a list of all subdirectories and another list of all files under a given directory in php. I'm okay with a non-pure php code as long as I can use it from php(e.g. a c/java/python/... program). Something faster than pure recursion
, something built-in in some language(as these things tend to be fast.)
Upvotes: 1
Views: 1108
Reputation: 1
Since you don't want recursion, I just wrote this up with a few extra bits
// $dirs = [];
// Get All Files & Folders in $dir
$files = glob("$dir/*");
for ($i=0; $i < count($files); $i++) {
if (is_dir($files[$i])) {
$files = array_merge($files, glob("$files[$i]/*"));
// $dirs[] = $files[$i]; // This can add the folder to a dir array
}
}
// Remove folders from the list if you like
foreach ($files as $key => $file) {
if (is_dir($file)) {
unset($files[$key]);
}
}
// Clean up the key numbers if you removed files or folders
$files = array_values($files);
Upvotes: 0
Reputation: 2275
class Dir_helper{
public function __construct(){
}
public function getWebdirAsArray($rootPath){
$l1 = scandir($rootPath);
foreach ($this->getFileList($rootPath) as $r1){
if ($r1['type'] == 'dir'){
if (preg_match("/\./", $r1['name'])){
$toplevel[] = $r1['name'];
} else {
if (preg_match("/\d/",$r1['name'])){
$seclevel[] = $this->getFileList($r1['name']);
}
}
}
}
foreach ($seclevel as $sl){
foreach ($sl as $cur){
$sub[] = $cur['name'];
}
}
return $result = array_merge((array)$toplevel, (array)$sub);
}
public function getFileList($dir){
$retval = array();
if(substr($dir, -1) != "/") $dir .= "/";
$d = @dir($dir) or die("getFileList: Failed opening directory $dir for reading");
while(false !== ($entry = $d->read())) {
if($entry[0] == ".") continue;
if(is_dir("$dir$entry")) {
$retval[] = array(
"name" => "$dir$entry/",
"type" => filetype("$dir$entry"),
"size" => 0,
"lastmod" => filemtime("$dir$entry")
);
} elseif(is_readable("$dir$entry")) {
$retval[] = array(
"name" => "$dir$entry",
"type" => mime_content_type("$dir$entry"),
"size" => filesize("$dir$entry"),
"lastmod" => filemtime("$dir$entry")
);
}
}
$d->close();
return $retval;
}
}
Upvotes: 1
Reputation: 14136
use php's inbuilt RecursiveDirectoryIterator
EDIT
Something like:
$dirs = array();
$files = array();
$dir = __DIR__ . '/foo';
$iterator = new RecursiveDirectoryIterator(new DirectoryIterator($dir));
foreach ($iterator as $dirElement) {
if ($dirElement->isDir()) {
$dirs[] $dirElement->getPathname();
}
if ($dirElement->isFile()) {
$files[] = $dirElement->getPathname();
}
}
Upvotes: 0
Reputation: 12613
taken from php.net
s documentation on glob():
$path[] = 'starting_place/*';
while(count($path) != 0) {
$v = array_shift($path);
foreach(glob($v) as $item) {
if(is_dir($item))
$path[] = $item . '/*';
else if (is_file($item)) {
//do something
}
}
}
Upvotes: 1
Reputation: 46856
And if you don't like OOing things, you could perhaps run a loop of opendir() through the results of a find.
if (exec('find /startdir -type d -print', $outputarray)) {
foreach ($outputarray as $onepath) {
// do stuff in $onepath
}
}
You did specify "not pure PHP", as an option, right? :-)
Upvotes: 2
Reputation: 101936
Have a look at the RecursiveDirectoryIterator
:
foreach (new RecursiveDirectoryIterator('yourDir') as $file) {
// you don't want the . and .. dirs, do you?
if ($file->isDot()) {
continue;
}
if ($file->isDir()) {
// dir
} else {
// file
}
}
Upvotes: 4