2

i have the following function when i try and return the vaule its only shows 1 folder but when i echo the function it show the correct informaion.

PHP Code:

$FolderList = "";

function ListFolder($path) {
    $path = str_replace("//","/",$path);

    //using the opendir function
    $dir_handle = @opendir($path) or die("Unable to open $path");

    //Leave only the lastest folder name
    $dirname = end(explode("/", $path));

    //display the target folder.
    $FolderList .= ('<option value="">'.$path.'</option>');

    while(false !== ($file = readdir($dir_handle))) {
        if($file!="." && $file!="..") {
            if(is_dir($path."/".$file)) {
                //Display a list of sub folders.
                ListFolder($path."/".$file);
            }
        }
    }

    //closing the directory
    closedir($dir_handle);

    return $FolderList; //ERROR: Only Shows 1 Folder
    echo $FolderList; //WORKS: Show All The Folders Correctly
}

Thanks

Phill Pafford
  • 83,471
  • 91
  • 263
  • 383
Rickstar
  • 6,057
  • 21
  • 55
  • 74
  • 1
    I believe this has to do with scope resolution, but my brain isn't working well enough right now to figure it out... You define the $FolderList outside the function and I believe you get unreliable results unless you define the variable as static and/or global. – Patrick Nov 17 '10 at 15:12
  • Linked post: http://stackoverflow.com/questions/4204728/how-to-display-folders-and-sub-folders-from-dir-in-php? – Matt Asbury Nov 17 '10 at 15:13
  • I tryed it inside the function and the something is happening – Rickstar Nov 17 '10 at 15:17

5 Answers5

2

Inside your while loop, you're calling ListFolder again. This is okay to do but you're not storing the result anywhere and just echoing the result every time ListFolder is called.

That correct format you're seeing on the page is not that 1 string being echoed at the end. its a single directory being echoed every time ListFolder is being called.

Below is the code that works.

function ListFolder($path)
{

    $FolderList = "";
    $path = str_replace("//","/",$path);

    //using the opendir function
    $dir_handle = @opendir($path) or die("Unable to open $path");

    //Leave only the lastest folder name
    $dirname = end(explode("/", $path));
    //display the target folder.

    $FolderList .= ('<option value="">'.$path.'</option>');

    while (false !== ($file = readdir($dir_handle)))
    {
        if($file!="." && $file!="..")
        {
            if (is_dir($path."/".$file))
            {
                //Display a list of sub folders.
                $FolderList .= ListFolder($path."/".$file);
            }
        }
    }

    //closing the directory
    closedir($dir_handle);

    return $FolderList;
}
castis
  • 8,154
  • 4
  • 41
  • 63
2

Give this a shot:

function ListFolder($path)
{
    $path = str_replace("//","/",$path);

    //using the opendir function
    $dir_handle = @opendir($path) or die("Unable to open $path");

    //Leave only the lastest folder name
    $dirname = end(explode("/", $path));
    //display the target folder.
    $FolderList = ('<option value="">'.$path.'</option>');
    while (false !== ($file = readdir($dir_handle)))
    {
        if($file!="." && $file!="..")
        {
            if (is_dir($path."/".$file))
            {
                //Display a list of sub folders.
                $FolderList .= ListFolder($path."/".$file);
            }
        }
    }


    //closing the directory
    closedir($dir_handle);

    return $FolderList;
}

echo ListFolder('/path/to/folder/');

I simply changed the $FolderList to be assigned to the return value of the ListFolder function.

Jim
  • 18,673
  • 5
  • 49
  • 65
1

Each function call has its own variable scope. You need to union the returned value from your recursive call with the one that you’ve gathered in the while loop:

while(false !== ($file = readdir($dir_handle))) {
    if($file!="." && $file!="..") {
        if(is_dir($path."/".$file)) {
            $FolderList .= ListFolder($path."/".$file);
        }
    }
}
Gumbo
  • 643,351
  • 109
  • 780
  • 844
1

You forgot to catch the return value of the function calls

$FolderList .= ListFolder($path."/".$file);

You just add one folder to the string, than call the function, but do nothing with the return value. Then you return $FolderList, which only contains the one entry you add before the while-loop

When *echo*ing it, its just send directly to the browser independently on which level of recursion you are, so you think, that $FolderList is full, but in fact its just every sungle $FolderList from each recursion step.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
KingCrunch
  • 128,817
  • 21
  • 151
  • 173
0

Alternative Method

function ListFolder($path, &$FolderList = array()) {
    $path = str_replace("//","/",$path);

    //using the opendir function
    $dir_handle = @opendir($path) or die("Unable to open $path");

    //Leave only the lastest folder name
    $dirname = end(explode("/", $path));

    //display the target folder.
    $FolderList[] = '<option value="">'.$path.'</option>';

    while(false !== ($file = readdir($dir_handle))) {
        if($file!="." && $file!="..") {
            if(is_dir($path."/".$file)) {
                //Display a list of sub folders.
                ListFolder($path."/".$file, $FolderList);
            }
        }
    }

    //closing the directory
    closedir($dir_handle);

    return $FolderList;
}

$paths = ListFolder(getcwd());
echo "<select>".implode("", $paths)."</select>";
Phill Pafford
  • 83,471
  • 91
  • 263
  • 383