this PHP function displays any given directory structure as recursive list.
it even outputs nice HTML markup code with indenting.

directory structure to list” makes use of the built-in PHP functions entab( ), str_repeat( ), explode( ), count( ), opendir( ), is_dir( ), closedir( ) and preg_replace( ).

01 <?php
02 
03 function entab($num)
04 {
05     return "\n".str_repeat("\t",$num);
06 }
07  
08 function directory_to_list($dir,$onlydirs=FALSE,$sub=FALSE)
09 {
10     $levels = explode('/',$dir);
11     $subtab = (count($levels) > 2 ? count($levels)-2 : 0);
12     $t = count($levels)+($sub !== false ? 1+$subtab : 0);
13     $output = entab($t).'<ul>';
14     $dirlist = opendir($dir);
15     while ($file = readdir ($dirlist))
16     {
17         if ($file != '.' && $file != '..' && $file != '.DS_Store')
18         {
19             $newpath = $dir.'/'.$file;
20             $level = explode('/',$newpath);
21             $tabs = count($level)+($sub !== false ? 1+$subtab : 0);
22             $output .= (($onlydirs == TRUE && is_dir($newpath)) || $onlydirs == FALSE ? 
23                 entab($tabs).'<li><a href="'.$newpath.'">'.$file.'</a>'.(is_dir($newpath) ? 
24                     directory_to_list($newpath,$onlydirs,TRUE).entab($tabs) : 
25                     '').'</li>' : 
26                 '');
27         }
28     }
29     closedir($dirlist); 
30     $output .= entab($t).'</ul>';
31     if($onlydirs == TRUE)
32         $output = preg_replace('/\n([\t]+)<ul>\n([\t]+)<\/ul>\n([\t]+)/','',$output);
33     return $output;
34 }
35  
36 // demo of directory to list
37 
38 echo directory_to_list('.');
39  
40 // if you want to list directories only, use
41 
42 //echo directory_to_list('.',TRUE);
43 
44 ?>