2013-02-25 4 views
6
$dir = '/master/files'; 
$files = scandir($dir); 
foreach($files as $file){ 
    if(($file != '.') && ($file != '..')){ 
     if(is_dir($dir.'/'.$file)){ 
     echo '<li class="folder">'.$file.'</li>'; 
     }else{ 
     echo '<li class="file">'.$file.'</li>'; 
     } 
    } 
} 

ze skryptu powyżej, otrzymuję wynik:PHP sort folderu, a następnie pliki

images (folder) 
index.html  
javascript (folder) 
style.css 

Jak sortować folder, a następnie pliki?

+0

najpierw zapisz je w dwóch tablicach, a następnie wydrukuj (najpierw folder, a potem pliki) :) –

+0

Masz na myśli, że muszę zrobić dwa "foreach"? Jeden dla folderu, a potem dla plików? – Ogy

Odpowiedz

6

Spróbuj tego:

$dir = '/master/files'; 
$directories = array(); 
$files_list = array(); 
$files = scandir($dir); 
foreach($files as $file){ 
    if(($file != '.') && ($file != '..')){ 
     if(is_dir($dir.'/'.$file)){ 
     $directories[] = $file; 

     }else{ 
     $files_list[] = $file; 

     } 
    } 
} 

foreach($directories as $directory){ 
    echo '<li class="folder">'.$directory.'</li>'; 
} 
foreach($files_list as $file_list){ 
    echo '<li class="file">'.$file_list.'</li>'; 
} 
+2

Uważam, że dwa foreach nie są dobre, z wyjątkiem li podczas tworzenia tablicy, a następnie użycie implodu do drukowania jest lepsze –

+0

Dzięki, jego praca jest świetna! :) – Ogy

3

Nie trzeba zrobić 2 pętle, można wykonać zadanie z tego kawałka kodu:

<?php 

function scandirSorted($path) { 

    $sortedData = array(); 
    foreach(scandir($path) as $file) { 

     // Skip the . and .. folder 
     if($file == '.' || $file == '..') 
      continue;    

     if(is_file($path . $file)) { 
      // Add entry at the end of the array 
      array_push($sortedData, '<li class="folder">' . $file . '</li>'); 
     } else { 
      // Add entry at the begin of the array 
      array_unshift($sortedData, '<li class="file">' . $file . '</li>'); 
     } 
    } 
    return $sortedData; 
} 

?> 

Funkcja ta zwróci listę wpisów ścieżce, foldery, następnie pliki.

+0

Stylizacja w pętli to dobry pomysł, ale nie będzie to sortować folderów ani plików w kolejności "a-z". –

+0

Rzeczywiście, jeśli zamówienie jest ważne, musisz użyć dwóch tablic: – MatRt

3

modyfikowania kodu w jak najmniejszym stopniu:

$folder_list = ""; 
$file_list = ""; 
$dir = '/master/files'; 
$files = scandir($dir); 
foreach($files as $file){ 
    if(($file != '.') && ($file != '..')){ 
     if(is_dir($dir.'/'.$file)){ 
     $folder_list .= '<li class="folder">'.$file.'</li>'; 
     }else{ 
     $file_list .= '<li class="file">'.$file.'</li>'; 
     } 
    } 
} 

print $folder_list; 
print $file_list; 

This tylko pętle przez wszystko raz, a nie wymagające wielu podań.

1

Przechowuj dane wyjściowe w 2 tablicach, a następnie powtórz za pośrednictwem tablic, aby wyprowadzić je w odpowiedniej kolejności.

$dir = '/master/files'; 

$contents = scandir($dir); 

// create blank arrays to store folders and files 
$folders = $files = array(); 

foreach ($contents as $file) { 

    if (($file != '.') && ($file != '..')) { 

     if (is_dir($dir.'/'.$file)) { 

      // add to folders array 
      $folders[] = $file; 

     } else { 

      // add to files array 
      $files[] = $file; 

     } 
    } 
} 

// output folders 
foreach ($folders as $folder) { 

    echo '<li class="folder">' . $folder . '</li>'; 

} 

// output files 
foreach ($files as $file) { 

    echo '<li class="file">' . $file . '</li>'; 

} 
0

Spróbuj

<?php 
    $path = $_SERVER['DOCUMENT_ROOT']; 
    chdir ($path); 

    $dir = array_diff (scandir ('.'), array ('.', '..', '.DS_Store', 'Thumbs.db')); 

    usort ($dir, create_function ('$a,$b', ' 
     return is_dir ($a) 
     ? (is_dir ($b) ? strnatcasecmp ($a, $b) : -1) 
     : (is_dir ($b) ? 1 : (
      strcasecmp (pathinfo ($a, PATHINFO_EXTENSION), pathinfo ($b, PATHINFO_EXTENSION)) == 0 
      ? strnatcasecmp ($a, $b) 
      : strcasecmp (pathinfo ($a, PATHINFO_EXTENSION), pathinfo ($b, PATHINFO_EXTENSION)) 
     )) 
    ; 
')); 

    header ('content-type: text/plain'); 
    print_r ($dir); 
?> 
1

Mam rozwiązanie dla N głębokim rekurencyjnego przeszukiwania katalogu:

function scanRecursively($dir = "/") { 
    $scan = array_diff(scandir($dir), array('.', '..'); 
    $tree = array(); 
    $queue = array(); 
    foreach ($scan as $item) 
     if (is_file($item)) $queue[] = $item; 
     else $tree[] = scanRecursively($dir . '/' . $item); 
    return array_merge($tree, $queue); 
} 
0

bycia kochanką CodeIgniter, mam w rzeczywistości zmodyfikowany rdzeń directory_helper z tego włączenie możliwości wyłączenia niektórych plików ze skanowania oprócz ustawienia głębokości i wyboru, czy powinny być włączone ukryte pliki.

Wszystkie zasługi należą się oryginalnym autorom CI. Po prostu dodałem do niego z wyłączoną tablicą i budowaniem w sortowaniu.

Wykorzystuje ksort zamówić foldery, jak nazwa folderu jest ustawiony jako klucz i natsort zamówić pliki w każdym folderze.

Jedyne, co musisz zrobić, to zdefiniować, czym jest DIRECTORY_SEPARATOR dla twojego środowiska, ale nie sądzę, że będziesz musiał zmodyfikować znacznie więcej.

function directory_map($source_dir, $directory_depth = 0, $hidden = FALSE, $exempt = array()) 
{ 
    if ($fp = @opendir($source_dir)) 
    { 
     $folddata = array(); 
     $filedata = array(); 
     $new_depth = $directory_depth - 1; 
     $source_dir = rtrim($source_dir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR; 

     while (FALSE !== ($file = readdir($fp))) 
     { 
      // Remove '.', '..', and hidden files [optional] 
      if ($file === '.' OR $file === '..' OR ($hidden === FALSE && $file[0] === '.')) 
      { 
       continue; 
      } 

      is_dir($source_dir.$file) && $file .= DIRECTORY_SEPARATOR; 

      if (($directory_depth < 1 OR $new_depth > 0) && is_dir($source_dir.$file)) 
      { 
       $folddata[$file] = directory_map($source_dir.$file, $new_depth, $hidden, $exempt); 

      } 
      elseif(empty($exempt) || !empty($exempt) && !in_array($file, $exempt)) 
      { 
       $filedata[] = $file; 
      } 
     } 

     !empty($folddata) ? ksort($folddata) : false; 
     !empty($filedata) ? natsort($filedata) : false; 

     closedir($fp); 
     return array_merge($folddata, $filedata); 
    } 

    return FALSE; 
} 

Przykładem użycia może być:

$filelist = directory_map('full_server_path'); 

Jak wspomniano powyżej, będzie ustawić nazwę folderu jako kluczu tablicy dziecko, więc można się spodziewać czegoś na wzór następujący:

Array(
[documents/] => Array(
    [0] => 'document_a.pdf', 
    [1] => 'document_b.pdf'  
    ), 
[images/] => Array(
    [tn/] = Array(
     [0] => 'picture_a.jpg', 
     [1] => 'picture_b.jpg' 
     ), 
    [0] => 'picture_a.jpg', 
    [1] => 'picture_b.jpg'   
    ), 
[0] => 'file_a.jpg', 
[1] => 'file_b.jpg' 
); 

Należy pamiętać, że zwolnienie zostanie zastosowane do wszystkich folderów. Jest to przydatne, jeśli chcesz pominąć plik index.html lub inny plik, który jest używany w katalogach, których nie chcesz uwzględnić.