Reputation: 93
I am trying to make a function that scans a folder for subfolders and then returns a numeric array with the names of those folders.
This is the code i use for testing. Once i get it to print out the folder names and not just "." and ".." for present and above folder all will be well, and I can finish the function.
<?php
function super_l_getthemes($dir="themes")
{
if ($handle = opendir($dir)) {
echo "Handle: {$handle}\n";
echo "Files:\n";
while (false !== ($file = readdir($handle))) {
echo "{$file}<br>";
}
closedir($handle);
}
?>
The above code works fine, and prints out all the contents of the folder: files, subfolders and the "." and ".."
but if i replace:
while (false !== ($file = readdir($handle))) {
echo "{$file}<br>";
}
with:
while (false !== ($file = readdir($handle))) {
if(file_exists($file) && is_dir($file)){echo "{$file}";}
}
The function only prints "." and ".." , not the two folder names that I'd like it to print.
Any help is appreciated.
Upvotes: 4
Views: 19505
Reputation: 882
$directory = scandir($path);
foreach($directory as $a){
if(is_dir($path.$a.'/') && $a != '.' && $a != '..'){
echo $a.'<br/>';
}
}
With the path given as shown, it displays the folders present in the path.
Upvotes: 0
Reputation: 870
I agree with nuqqsa's solution, however, I'd like to add something to it.
Instead of specifying the path, you can change the current directory instead.
For example,
// open directory handle
// ....
chdir($dir);
while (false !== ($file = readdir($handle)))
if(is_dir($file))
echo $file;
// close directory handle
Upvotes: -2
Reputation: 317207
If you only want the directories of the starting folder, you can simply do:
glob('/some/path/to/search/in/*', GLOB_ONLYDIR);
which would given you only those foldernames in an array. If you want all directories below a given path, try SPL's RecursiveDirectoryIterator
$fileSystemIterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator('/some/path/to/look/in'),
RecursiveIteratorIterator::SELF_FIRST);
Iterators can be used with foreach
:
$directories = array();
foreach($fileSystemIterator as $path => $fileSystemObject) {
if($fileSystemObject->isDir()) {
$directories[] = $path;
}
}
You will then have an array $directories
with all directories under the given path.
Upvotes: 1
Reputation: 2621
I don't think you need both file_exists
and is_dir
,
You just need the is_dir
function. From the manual:
is_dir
Returns TRUE if the filename exists and is a directory, FALSE otherwise.
Use this:
while (false !== ($file = readdir($handle))) {
if(is_dir($file)){echo "{$file}";}
}
is_dir
will also check whether it's a relative path or an absolute path.
Upvotes: 0
Reputation: 70540
$files = array();
foreach(new DirectoryIteraror('/path') as $file){
if($file->isDir() /* && !$file->isDot()*/) $files[] = $file->getFilename();
}
[edit: though you wanted to skip the dot, commented it out)
Upvotes: 0
Reputation: 30651
The problem with readdir
is that it only reads the strings of the named entries inside of the directory.
For instance, if you had file "foo" inside of directory "/path/to/files/", when using readdir
on "/path/to/files/", you would eventually come to the string "foo".
Normally this wouldn't be a problem if it were in the same directory as the current working directory of the script, but, since you are reading from an arbitrary director, when you are attempting to inspect the entry (file, directory, whatever), you are calling is_dir
on the bare string "foo".
I would try prefixing the name you pull out using readdir
with the path to the file.
if ($handle = opendir($dir)) {
echo "Handle: {$handle}\n";
echo "Files:\n";
while ($file = readdir($handle)) {
/*** make $file into an absolute path ***/
$absolute_path = $dir . '/' . $file;
/*** NOW try stat'ing it ***/
if (is_dir($absolute_path)) {
/* it's a directory; do stuff */
}
}
closedir($handle);
}
Upvotes: 3
Reputation: 34264
You need to use:
while (false !== ($file = readdir($handle))) {
if(file_exists($dir.'/'.$file) && is_dir($dir.'/'.$file)){echo "{$file}";}
}
Upvotes: 1
Reputation: 4521
You must provide the absolute path to file_exists
, otherwise it will look for it in the current execution path.
while (false !== ($file = readdir($handle))) {
$file_path = $dir . DIRECTORY_SEPARATOR . $file;
if (file_exists($file_path) && is_dir($file_path)) {
echo "{$file}";
}
}
Upvotes: 6