2010-04-19 167 views
41

我目前有一個index.php文件,它允許我輸出同一目錄內的文件列表,輸出顯示名稱,然後我使用filemtime()函數來顯示文件的日期被修改了。我現在的問題是,我將如何對輸出進行排序以顯示最新的修改文件?,我一直在想如何做到這一點。如果我只是用mysql進行交互,那麼根本沒有問題。請給我演示一個如何排序和輸出從最新修改文件開始的文件列表的例子。這就是我現在在PHP中按日期排序文件

if ($handle = opendir('.')) { 
while (false !== ($file = readdir($handle))) { 
     if ($file != "." && $file != "..") { 
     $lastModified = date('F d Y, H:i:s',filemtime($file)); 
      if(strlen($file)-strpos($file,".swf")== 4){ 
      echo "<tr><td><input type=\"checkbox\" name=\"box[]\"></td><td><a href=\"$file\" target=\"_blank\">$file</a></td><td>$lastModified</td></tr>"; 
      } 
     } 
    } 
    closedir($handle); 
} 

回答

19

您需要將這些文件放入數組中以排序並查找最後修改的文件。

$files = array(); 
if ($handle = opendir('.')) { 
    while (false !== ($file = readdir($handle))) { 
     if ($file != "." && $file != "..") { 
      $files[filemtime($file)] = $file; 
     } 
    } 
    closedir($handle); 

    // sort 
    ksort($files); 
    // find the last modification 
    $reallyLastModified = end($files); 

    foreach($files as $file) { 
     $lastModified = date('F d Y, H:i:s',filemtime($file)); 
     if(strlen($file)-strpos($file,".swf")== 4){ 
      if ($file == $reallyLastModified) { 
      // do stuff for the real last modified file 
      } 
      echo "<tr><td><input type=\"checkbox\" name=\"box[]\"></td><td><a href=\"$file\" target=\"_blank\">$file</a></td><td>$lastModified</td></tr>"; 
     } 
    } 
} 

未經測試,但這是如何做到這一點。

+14

@sasori注意,當你有相同的時間文件,這個解決方案將無法正常工作,因爲它將覆蓋該時間的前一個文件名。 – Gordon 2010-04-19 14:34:26

+2

正是戈登,我希望能有一種方法來BUMP評論更明顯,因爲我花了一個小時挖什麼是錯的..顯然,上述代碼背後的想法是正確的,但這個錯誤使得它絕對無用。 – 2012-08-14 17:57:40

+0

編輯代碼以使密鑰具有唯一性(通過重複添加一秒)。當一些文件具有一秒不同(但不完全相同)的時間時,它會使事情略微混淆,但在大多數情況下這並不重要。 – 2014-02-20 11:37:28

137

這將有.swf擴展名的/到/文件得到所有文件路徑到一個數組,然後通過文件的修改時間排序數組

$files = glob('path/to/files/*.swf'); 
usort($files, function($a, $b) { 
    return filemtime($a) < filemtime($b); 
}); 

的以上使用Lambda function並且需要PHP 5.3。在此之前5.3,你會怎麼做

usort($files, create_function('$a,$b', 'return filemtime($a)<filemtime($b);')); 

如果你不想使用匿名函數,你可以和定義回調作爲常規功能,並通過函數名稱來代替usort

有了結果數組,那麼您需要遍歷文件是這樣的:

foreach($files as $file){ 
    printf('<tr><td><input type="checkbox" name="box[]"></td> 
      <td><a href="%1$s" target="_blank">%1$s</a></td> 
      <td>%2$s</td></tr>', 
      $file, // or basename($file) for just the filename w\out path 
      date('F d Y, H:i:s', filemtime($file))); 
} 

需要注意的是,因爲你整理文件的時候就已經被稱爲filemtime,有在foreach再次調用時,它無需任何額外費用循環由於stat cache

+2

-1你不使用他的代碼,usort是在這種情況下使用的最差的排序函數。但地獄,所有人都投票給你,因爲它看起來很花哨。 * - * – elias 2010-04-19 12:08:30

+30

@elias沒有冒犯性,但我覺得很荒唐,因爲你給的原因downvote一個完全有效的答案。談到可讀性,你的代碼需要比我的更長的時間才能發現。我會稱之爲意大利麪條代碼。如果你不喜歡這麼糟糕,那就比用PHP的bug追蹤器投訴。 – Gordon 2010-04-19 12:14:16

+0

當然,這個問題已經很老了,我現在要使用'usort()';祈禱,'usort()'有什麼問題? (關於上面的@elias評論) – 2015-06-10 09:23:25

8

一個使用RecursiveDirectoryIterator類的示例,它是通過文件系統遞歸迭代的一種便捷方式。

$output = array(); 
foreach(new RecursiveIteratorIterator( 
    new RecursiveDirectoryIterator('path', FilesystemIterator::SKIP_DOTS | FilesystemIterator::UNIX_PATHS)) as $value) {  
     if ($value->isFile()) { 
      $output[] = array($value->getMTime(), $value->getRealPath()); 
     } 
} 

usort ($output, function($a, $b) { 
    return $a[0] > $b[0]; 
}); 
+0

人們需要在PHP中採用OOP方法,以使其與其他語言競爭。 – 2015-04-06 17:00:23

+1

@RaheelKhan爲什麼?當解決問題更容易時使用OOP,當它更復雜時不要使用OOP。面向對象不會讓任何事情變得更好,也不會使你的代碼或語言更好。它只是允許某些問題更有效地解決(我不認爲這裏是這種情況)。 – 2015-06-19 11:23:13

+0

對'''爲+1;我不明白爲什麼其他答案就我的代碼而言失敗了,但你的成功。正確的比較運算符:'>'而不是'<'。 – 1111161171159459134 2015-12-18 21:25:54

0

我用你的確切建議的代碼只有幾個額外的行。這個想法或多或少與@elias提出的想法是一樣的,但是在這個解決方案中不能有衝突,因爲目錄中的每個文件都有不同的文件名,因此將它添加到密鑰可以解決衝突。關鍵字的第一部分是日期時間字符串,其格式可以按照字典順序對其中兩個進行比較。

if ($handle = opendir('.')) { 
    $result = array(); 
    while (false !== ($file = readdir($handle))) { 
     if ($file != "." && $file != "..") { 
      $lastModified = date('F d Y, H:i:s',filemtime($file)); 
      if(strlen($file)-strpos($file,".swf")== 4){ 
       $result [date('Y-m-d H:i:s',filemtime($file)).$file] = 
        "<tr><td><input type=\"checkbox\" name=\"box[]\"></td><td><a href=\"$file\" target=\"_blank\">$file</a></td><td>$lastModified</td></tr>"; 
      } 
     } 
    } 
    closedir($handle); 
    krsort($result); 
    echo implode('', $result); 
} 
-1

$文件和array_diff =(SCANDIR($目錄,SCANDIR_SORT_DESCENDING),陣列( '.. ')'。'); print_r($ files);