views:

42

answers:

1

I'm attempting to use a sample function on the PHP manual website (posted by a user). The function is supposed to return a nested array of all of the files and/or folders in a specified directory of your server.

I'm just learning php, so I think it's more likely that I'm doing something wrong, and less likely that the function doesn't work. But if there is an easier method than the function below please let me know.

I'm able to iterate through and echo all of the files in the base path, but not the files in my sample sub-folder. The index where the sub-folder should be is either blank or just the folder name and not an array depending on the parameters I use. When I was able to get the folder name, I tested it with is_array which returned false.

Here is the function:

list_array: return an array containing optionally all files, only directories or only files at a file system path

  • @param $base_path string either absolute or relative path

  • @param $filter_dir boolean Filter directories from result (ignored except in last directory if $recursive is true)

  • @param $filter_files boolean Filter files from result

  • @param $exclude string Pipe delimited string of files to always ignore

  • @param $recursive boolean Descend directory to the bottom?

  • @return $result_list array Nested array or false

    function directory_list($directory_base_path, $filter_dir = false, $filter_files = false, $exclude = ".|..|.DS_Store|.svn", $recursive = true){
    $directory_base_path = rtrim($directory_base_path, "/") . "/";
    
    
    if (!is_dir($directory_base_path)){
        error_log(__FUNCTION__ . "File at: $directory_base_path is not a directory.");
        return false;
    }
    
    
    $result_list = array();
    $exclude_array = explode("|", $exclude);
    
    
    if (!$folder_handle = opendir($directory_base_path)) {
        error_log(__FUNCTION__ . "Could not open directory at: $directory_base_path");
        return false;
    }else{
        while(false !== ($filename = readdir($folder_handle))) {
            if(!in_array($filename, $exclude_array)) {
                if(is_dir($directory_base_path . $filename . "/")) {
                    if($recursive && strcmp($filename, ".")!=0 && strcmp($filename, "..")!=0 ){ // prevent infinite recursion
                        error_log($directory_base_path . $filename . "/");
                        $result_list[$filename] = directory_list("$directory_base_path$filename/", $filter_dir, $filter_files, $exclude, $recursive);
                    }elseif(!$filter_dir){
                        $result_list[] = $filename;
                    }
                }elseif(!$filter_files){
                    $result_list[] = $filename;
                }
            }
        }
        closedir($folder_handle);
        return $result_list;
    }
    

    }

Here is one of the many things I've tried. The array contains 5 elements, but only 4 of them display. Echoing $array[4] is blank. I'm just trying to get the nested array at this point. But if there is an easier way to iterate through it, any tips are much appreciated.

$directory_base_path = "../sandbox/";
$filter_dir = false;
$filter_files = false;
$exclude_files = ".|..|.DS_Store|dir_read_test.php";
$recursive = true;
$array = directory_list($directory_base_path, $filter_dir, $filter_files, $exclude_files, $recursive);
$array_length = count($array);
echo $array_length;
echo "<br/>";
$count = 0;

while ( $array_length >= $count ) {
 echo $array[$count];
 echo "<br/>";
 $count = $count + 1;
}
+3  A: 

Have a close look at that routine:

    $result_list[$filename] = directory_list(/*recursive*/);
 else
    $result_list[] = $filename;

What's the difference? The recursive entries are put under index $filename, while the direct contents are put under an ascending integer index, using []. Your loop will only show the integer indexes.

If you would

print_r($array);

you will see all entries. (Or you could replace [$filename] with [], of course.) To loop through them yourself, replace the while loop with

foreach ( $array as $k=>$v )
{
    echo "$k: $v<br/>";
}

(for the subdir, this will show "subdir: Array", but that's another topic; you could test is_array($v) and take some action based on that)

mvds
Ok great, thanks. Working perfectly now.
Baa