Как мне организовать цикл foreach PHP по имени файла, который он выплевывает? - PullRequest
2 голосов
/ 03 августа 2011

Всем привет

Я пытаюсь организовать список файлов, которые возвращаются циклом foreach - файлы помечены месяцем: например, отчет - январь 2011 г., отчет - февраль 2011 г. и т. Д.

В настоящее время они выплевывают их в случайном порядке, например, июль, февраль, декабрь, март, и я хочу, чтобы они появлялись в таком порядке, как, январь, февраль, март, апрель и т. Д.

Можете ли вы, ребята, пролить свет на то, как я это сделаю.

Это моя функция:

function getDirectoryList($directory) {
$results = array();
$handler = opendir($directory);
while ($file = readdir($handler)) {
    if ($file != "." && $file != ".." && $file != "img") {
        $results[] = $file;
    }
}
closedir($handler);
return $results;
}

Это вызов функции: (обратите внимание, "filepath" устанавливается с помощью define ())

$files = getDirectoryList(filepath.$username."/".date("Y"));

Это цикл foreach:

foreach ($files as $f) {    
$path_parts = pathinfo(filepath.$f);
$dir = $path_parts['dirname'];
$base = $path_parts['basename'];
$ext = $path_parts['extension'];
$fname = $path_parts['filename'];

echo "<div class='file ".$ext."'>".
    "<a href='".downloadpath.$username."/".$f."' target='_blank' title='Download $f'>". $fname ."</a>
    <span class='del'><a href='../inc/delete.php?id=".$_GET["id"]."&amp;f=$f' title='Delete $f'>Delete</a></span>
    </div>";
}

Ответы [ 5 ]

5 голосов
/ 03 августа 2011

Сортировка массива перед циклом

function cmp($a, $b) {
  $a = pathinfo(filepath.$a);
  $b = pathinfo(filepath.$b);
  $months = array(1 => 'January', 2 => 'February', 3 => 'March', 4 => 'April', 5 => 'May', 6 => 'June', 7 => 'July', 8 => 'August', 9 => 'September', 10 => 'October', 11 => 'November', 12 => 'December');

  $a_val = $b_val = 0;
  foreach ($months as $value => $month) {
    if (stripos($a['filename'], $month) !== false) $a_val = $value;
    if (stripos($b['filename'], $month) !== false) $b_val = $value;
  }
  return ($a_val < $b_val) ? -1 : 1;
}

uasort($files, 'cmp');
1 голос
/ 03 августа 2011

Используйте usort для сортировки массива.

usort($files, 'cmp');

Используйте ассоциативный массив для настройки критерия сравнения:

$months = array ("january" => 0, "february" => 1, ...);

Настройка функции сравнения:

function cmp($file1, $file2) {
    $months = array ("january" => 0, "february" => 1, ...);
    // or global $months;
    // or $this->months;
    $month1 = ... extract month from $file1;
    $month2 = ... extract month from $file2;
    return $months[$month1] < $months[$month2] ? -1 : 1;
}

Извлеките строку месяца из вашего файла:

preg_match("/^\w+/", $file, $match);
$month = $match[0];

Edit:

Массив $ months не нужно хранить в методе cmp.Это приведет к тому, что массив будет создаваться при каждом вызове метода.Вместо этого используйте подход ООП или глобальное ключевое слово global $months.

0 голосов
/ 03 августа 2011

Используйте usort в ваших $ files aray с пользовательской функцией.

function my_sort($a,$b) {
     $month = array (
        'january' => 1,
        'february' => 2,
        'march' => 3,
        'april' => 4,
        'may' => 5,
        'june' => 6,
        'july' => 7,
        'august' => 8,
        'september' => 9,
        'october' => 10,
        'november' => 11,
        'december' => 12
    );

    // Might need to extract month from filename here
    $a_idx = $month[$a['filename']];
    $b_idx = $month[$b['filename']];

    if ($a_idx == $b_idx) {
        return 0;
    }
    else {
        return ($a_idx < $b_idx ? -1 : 1);
    }
}

usort($files,'my_sort');
0 голосов
/ 03 августа 2011
function getSortableDate( $s ) {
    $months = array( 'january' => '01', 'february' => '02', 'march' => '03', ... );
    preg_match( '/^(\w+) (\d+)$/', $s, $matches );
    return $matches[2].$months[ $matches[1] ];
}

function cmp($a, $b) {
    return ( getSortableDate( $a['filename'] ) < getSortableDate( $b['filename'] ) ) ? -1 : 1;
}

uasort( $files, 'cmp' );

В качестве альтернативы вы можете применить getSortableDate () ко всем именам файлов перед сортировкой, а затем отсортировать с помощью простого сравнения строк, это ускорит процесс, предотвратив избыточные вызовы getSortableDate ().

Но я бы лично так не поступил, это перебор, просто переименуйте ваши файлы в 2011-01 2011-02 и т. Д., Чтобы их можно было сравнивать как строки.

0 голосов
/ 03 августа 2011

try ksort с filemtime

function getDirectoryList($directory) {
$results = array();
    $handler = opendir($directory);
    while ($file = readdir($handler)) {
        if ($file != "." && $file != ".." && $file != "img") {
            $inDate = filemtime($directory.$file);
            $results[$inDate] = $file;
        }
    }
    closedir($handler);
    ksort($results);
    return $results;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...