2013-01-13 24 views
10

Powiel możliwe:
PHP Get all subdirectories of a given directoryPHP - listingu wszystkie katalogi i podkatalogi rekurencyjnie w menu rozwijanego

Chcę menu rozwijane, aby pokazać wszystkie podkatalogi w ./files/$userid/ nie tylko główny folder. Na przykład: /files/$userid/folder1/folder2/

Mój obecny kod jest:

HTML:

<select name="myDirs"> 
<option value="" selected="selected">Select a folder</option> 

PHP:

if (chdir("./files/" . $userid)) { 

     $dirs = glob('*', GLOB_ONLYDIR); 
     foreach($dirs as $val){ 
      echo '<option value="'.$val.'">'.$val."</option>\n"; 
     }   
     } else { 
     echo 'Changing directory failed.'; 
} 
+0

I Twoje pytanie? Pamiętaj, że formułowanie wymagań nie jest kwestią programowania. Proponuję najpierw wyszukać swoje wymagania na stronie, ponieważ lista katalogów została już zadana i odebrana w różnych smakach. [Dlaczego więc nie zająć miejsca w barze i zamówić drinka?] (Http://stackoverflow.com/search) – hakre

+0

Będziesz musiał użyć natywnego kodu PHP [RecursiveDirectoryIterator] (http://php.net/manual/en /class.recursivedirectoryiterator.php) klasa. [Ta odpowiedź] (http://stackoverflow.com/a/2398163/427992) powinna pomóc. – hohner

+0

Próbowałem tego http://pastebin.com/fpJiiCbZ, ale to nie działa. To jest wynik, który otrzymuję: http://i.imgur.com/gWt3U.png – Brian

Odpowiedz

48

RecursiveDirectoryIterator powinno załatwić sprawę. Niestety, dokumentacja nie jest super, więc o to przykład:

$root = '/etc'; 

$iter = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($root, RecursiveDirectoryIterator::SKIP_DOTS), 
    RecursiveIteratorIterator::SELF_FIRST, 
    RecursiveIteratorIterator::CATCH_GET_CHILD // Ignore "Permission denied" 
); 

$paths = array($root); 
foreach ($iter as $path => $dir) { 
    if ($dir->isDir()) { 
     $paths[] = $path; 
    } 
} 

print_r($paths); 

To generuje następujący wynik na moim komputerze:

Array 
(
    [0] => /etc 
    [1] => /etc/rc2.d 
    [2] => /etc/luarocks 
    ... 
    [17] => /etc/php5 
    [18] => /etc/php5/apache2 
    [19] => /etc/php5/apache2/conf.d 
    [20] => /etc/php5/mods-available 
    [21] => /etc/php5/conf.d 
    [22] => /etc/php5/cli 
    [23] => /etc/php5/cli/conf.d 
    [24] => /etc/rc4.d 
    [25] => /etc/minicom 
    [26] => /etc/ufw 
    [27] => /etc/ufw/applications.d 
    ... 
    [391] => /etc/firefox 
    [392] => /etc/firefox/pref 
    [393] => /etc/cron.d 
) 
+0

dzięki @PleaseStand działa dobrze, potrzebuję tylko jednej pętli foreach do wyświetlenia listy, tak jak wyjście –

+0

Nice. Byłoby lepiej, gdybyś mógł zilustrować, jak odfiltrować ukryte foldery i ich zawartość (np. '.svn'). – Raptor

+0

nie działa dla mnie ... po prostu limity czasu nawet po upływie limitu czasu ustawiono na jedną godzinę, gdy liczba katalogów wynosi tylko 1000 –

3

Można użyć rekurencyjną implementację wzorca, jak w tej funkcji:

function rglob($pattern='*', $path='', $flags = 0) { 
$paths=glob($path.'*', GLOB_MARK|GLOB_ONLYDIR|GLOB_NOSORT); 
$files=glob($path.$pattern, $flags); 
foreach ($paths as $path) { 
    $files=array_merge($files,rglob($pattern, $path, $flags)); 
} 
return $files; 
} 
+0

@ user183391 z listą plików lub folderów? – Brian

+0

Możesz użyć GLOB_ONLYDIR dla argumentu $ flags – Alex

10

Możesz napisać własną rekurencyjnej listę katalogów jak:

function expandDirectories($base_dir) { 
     $directories = array(); 
     foreach(scandir($base_dir) as $file) { 
      if($file == '.' || $file == '..') continue; 
      $dir = $base_dir.DIRECTORY_SEPARATOR.$file; 
      if(is_dir($dir)) { 
       $directories []= $dir; 
       $directories = array_merge($directories, expandDirectories($dir)); 
      } 
     } 
     return $directories; 
} 

$directories = expandDirectories(dirname(__FILE__)); 
print_r($directories); 
+2

jest to świetne rozwiązanie php bez użycia zewnętrznych bibliotek – Katushai

+0

Porównując zaakceptowaną odpowiedź z tym, terminal: 'time php -f test.php', ten jest szybszy. –

Powiązane problemy