scandir() для сортировки по дате изменения

Я пытаюсь заставить функцию scandir(); выйти за свои письменные ограничения, мне нужно больше, чем альфа-сортировка, которую она поддерживает в настоящее время. Мне нужно отсортировать результаты scandir(); по дате модификации.

Я пробовал несколько решений, которые я нашел здесь, и некоторые другие решения с разных веб-сайтов, но ни одно из них не сработало для меня, поэтому я думаю, что для меня разумно опубликовать здесь.

То, что я пробовал до сих пор, это:

function scan_dir($dir)
{
    $files_array = scandir($dir);
    $img_array   = array();
    $img_dsort   = array();
    $final_array = array();

    foreach($files_array as $file)
    {
        if(($file != ".") && ($file != "..") && ($file != ".svn") && ($file != ".htaccess"))
        {
            $img_array[] = $file;
            $img_dsort[] = filemtime($dir . '/' . $file);   
        }
    }

    $merge_arrays = array_combine($img_dsort, $img_array);
    krsort($merge_arrays);

    foreach($merge_arrays as $key => $value)
    {
        $final_array[] = $value;    
    }

    return (is_array($final_array)) ? $final_array : false;
}

Но у меня это не работает, он возвращает только 3 результата, но должен вернуть 16 результатов, потому что в папке 16 изображений.


person aborted    schedule 12.08.2012    source источник


Ответы (4)


Это отличный вопрос, и ответ Района Шермана дает надежный ответ, но мне нужно было немного больше гибкости для моих нужд, поэтому я создал эту новую функцию: better_scandir.

Цель состоит в том, чтобы флаги порядка сортировки scandir работали должным образом; не только метод обратной сортировки массива в ответе Риона. А также явно установить SORT_NUMERIC для сортировки массива, поскольку эти значения времени четко цифры.

Использование такое; просто переключите SCANDIR_SORT_DESCENDING на SCANDIR_SORT_ASCENDING или вообще оставить его пустым по умолчанию:

better_scandir(<filepath goes here>, SCANDIR_SORT_DESCENDING);

А вот и сама функция:

function better_scandir($dir, $sorting_order = SCANDIR_SORT_ASCENDING) {

  /****************************************************************************/
  // Roll through the scandir values.
  $files = array();
  foreach (scandir($dir, $sorting_order) as $file) {
    if ($file[0] === '.') {
      continue;
    }
    $files[$file] = filemtime($dir . '/' . $file);
  } // foreach

  /****************************************************************************/
  // Sort the files array.
  if ($sorting_order == SCANDIR_SORT_ASCENDING) {
    asort($files, SORT_NUMERIC);
  }
  else {
    arsort($files, SORT_NUMERIC);
  }

  /****************************************************************************/
  // Set the final return value.
  $ret = array_keys($files);

  /****************************************************************************/
  // Return the final value.
  return ($ret) ? $ret : false;

} // better_scandir
person Giacomo1968    schedule 23.05.2019

Альтернативный пример..

$dir = "/home/novayear/public_html/backups";
chdir($dir);
array_multisort(array_map('filemtime', ($files = glob("*.{sql,php,7z}", GLOB_BRACE))), SORT_DESC, $files);
foreach($files as $filename)
{
  echo "<a>".substr($filename, 0, -4)."</a><br>"; 
}  
person NovaYear    schedule 20.12.2013

Другой scandir хранит последние 5 файлов:

public function checkmaxfiles()
{

    $dir = APPLICATION_PATH . '\\modules\\yourmodulename\\public\\backup\\';
    // '../notes/';
    $ignored = array('.', '..', '.svn', '.htaccess');
    $files = array();
    foreach (scandir($dir) as $file) {
        if (in_array($file, $ignored)) continue;
        $files[$file] = filemtime($dir . '/' . $file);
    }
    arsort($files);
    $files = array_keys($files);
    $length = count($files);
    if($length < 4 ){
        return;
    }
    for ($i = $length; $i > 4; $i--) {
           echo "Erase : " .$dir.$files[$i];
           unlink($dir.$files[$i]);
    }

}
person Letech    schedule 20.05.2021

person    schedule
comment
@dugi попробуйте этот метод. Имена файлов в одном каталоге должны быть уникальными. Поэтому их можно использовать в качестве ключа. Затем массив сортируется по значениям (времени модификации) и ключи (имена файлов) возвращаются в правильном порядке. - person Ryon Sherman; 12.08.2012
comment
Работает отлично. Чтобы игнорировать все точечные файлы, вы можете использовать индексацию строк в виде массива вместо in_array для проверки первого символа имени файла: if ($file[0] === '.') continue; - person Richard; 03.07.2015
comment
вы спасли мое приложение .. Спасибо, дорогая - person Ramesh_D; 02.06.2018