Rakoon
Rakoon

Reputation: 93

is_dir does not recognize folders

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

Answers (8)

hlkstuv_23900
hlkstuv_23900

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

Daniel
Daniel

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

Gordon
Gordon

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

Cetra
Cetra

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

Wrikken
Wrikken

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

amphetamachine
amphetamachine

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

halfdan
halfdan

Reputation: 34264

You need to use:

while (false !== ($file = readdir($handle))) {
    if(file_exists($dir.'/'.$file) && is_dir($dir.'/'.$file)){echo "{$file}";}
}

See http://php.net/readdir

Upvotes: 1

nuqqsa
nuqqsa

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

Related Questions