按文件名(PHP)中的非常规日期排序文件


Order files by unconventional date in filename (PHP)

我正在使用一个PHP脚本,它允许按时间顺序浏览eggdrop生成的IRC日志。最初,我读取目录内容,并根据文件修改日期将日志名称插入到数组中。然而,在最近的服务器移动之后,文件的修改日期已经更新,导航现在是无序的!

日志文件名结构如下:

channel.log.dayMONTHyear.txt
例如:

shrawberry.log.08Apr2011.txt

,为了便于人类阅读,很难正确排序。

由于月份代码总是三个字符长,并且出现在序列中可预测的位置,因此我可以手动将非标准日期代码解析为Unix时间戳,遍历列表并将每个项目添加到具有该时间戳的数组中,然后按该数字对数组进行排序。

但这听起来太过分了。

我说对了吗,还是我提出的解决方案是理想的?


With Marc B。在我们的帮助下,我实现了以下代码:

function dateFromEggLog($string){
    $month = substr($string,-11,-8);
    $day = substr($string,-13,-11);
    $year = substr($string,-8,-4);
    for($i=1;$i<=12;$i++){
        if(strtolower(date("M", mktime(0, 0, 0, $i, 1, 0))) == strtolower($month)){
            $month = $i;
            break;
        }
    }
    return "$year-$month-$day";
}
function my_compare($a, $b) {
    $a_date = dateFromEggLog($a);
    $b_date = dateFromEggLog($b);
    if ($a_date == $b_date) {
        return 0;
    }
    $a = strtotime($a_date); // convert to PHP timestamp
    $b = strtotime($b_date); // convert to PHP timestamp
    return (($a < $b) ? -1 : 1);
}

这将成功地对日志进行排序,而不需要乱动数组。

您的示例文件名与"looks like"示例不匹配- 'txt'和日期字符串颠倒了。但是在任何情况下,您都可以使用PHP usort()函数,它允许用户定义的函数进行比较。

这可能不是特别有效,但您可以这样做:

function my_compare($a, $b) {
    $a_date = ... extract date field from filename in $a
    $b_date = ... extract date field from filename in $b
    if ($a_date == $b_date) {
        return 0;
    }
    $a = strtotime($a_date); // convert to PHP timestamp
    $b = strtotime($b_date); // convert to PHP timestamp
    return (($a < $b) ? -1 : 1);
}
usort($array_of_filenames, 'my_compare');

您以前使用过filemtime吗?为什么现在不使用filectime呢?

为什么不在你的排序函数中,使用字符串操作将channel.log.dayMONTHyear.txt重新排序到channel.log.yyyymmdd.txt,然后使用基本的字符串比较?

<?php
/* Helper stuff */
$months = Array(
  "Jan" => "01", "Feb" => "02", "Mar" => "03",
  "Apr" => "04", "May" => "05", "Jun" => "06",
  "Jul" => "07", "Aug" => "08", "Sep" => "09",
  "Oct" => "10", "Nov" => "11", "Dec" => "12"
);
/* The hard work */
function convertLogFilename($file) {
   $pos = strpos($file, ".log.");
   if ($pos === FALSE)
      throw new Exception("Invalid log file format");
   $pos += strlen(".log.");
   $dd   = substr($file, $pos, 2);
   $mm   = substr($file, $pos + 2, 3);
   $yyyy = substr($file, $pos + 5, 4);
   return substr($file, 0, $pos) . "$yyyy${months[$mm]}$dd.txt";
}
function sort_func($a, $b) {
   return convertLogFilename($a) < convertLogFilename($b);
}

/* Your program */
$files = Array(
   "channel.log.18Apr2011.txt",
   "channel2.log.21Jan2002.txt"
);
usort($files, 'sort_func');
print_r($files);
?>
输出:

Array
(
    [0] => channel2.log.21Jan2002.txt
    [1] => channel.log.18Apr2011.txt
)

这比为每个文件名创建完整的日期表示要快得多。