Glob文件并按filemtime和几个月排序

时间:2018-06-16 14:52:03

标签: php glob

是的,我知道这是丑陋的代码:)它不起作用。

我正在对目录中的所有.php文件进行全局处理,然后按文件时间戳对它们进行排序,然后我想将文件名回显到每个月。但是如何修复此循环以使每个月的回显输出正确? $ path的文件按日期排序,但$ link_title对于所有月份的所有文件都是相同的,所以我没有看到$ path按月排列。

foreach (glob("*.php") as $path) {

        $files[$path] = filemtime($path);

} arsort($files);

$currentdate = strtotime(date("Y-m-d H:i:s"));

$julybegin = strtotime("2018-07-01 00:00:00");
$julyend = strtotime("2018-07-31 23:23:59");

$junebegin = strtotime("2018-06-01 00:00:00");
$juneend = strtotime("2018-06-30 23:23:59");

$maybegin = strtotime("2018-05-01 00:00:00");
$mayend = strtotime("2018-05-31 23:23:59");

$aprilbegin = strtotime("2018-04-01 00:00:00");
$aprilend = strtotime("2018-04-30 23:23:59");

$timestamp = filemtime ($path);
$link_title = $path;

    foreach ($files as $path => $timestamp) {

if($timestamp > $julybegin && $timestamp < $julyend) {
echo '<li>';
echo $path . ' ' . $link_title;
echo '</li>';

} else {

if($timestamp > $junebegin && $timestamp < $juneend) {
echo '<li>';
echo $path . ' ' . $link_title;
echo '</li>';

} else {

if (($timestamp >= $maybegin) && ($timestamp <= $mayend)){

echo '<li>';
echo $path . ' ' . $link_title;
echo '</li>';

} else {

if (($timestamp >= $aprilbegin) && ($timestamp <= $aprilend)){

echo '<li>';
echo $path . ' ' . $link_title;
echo '</li>';

}
}
}
}
}

编辑6/21/18

这可以为jQuery手风琴输出正确的标记:

foreach (glob("*.php") as $path) {

    $timestamp = filemtime($path);

    $files[date('F', $timestamp)][$path] = $timestamp;

}

arsort($files); 

        echo '<div class="accordion">';

        foreach ($files as $month => $paths) {

            krsort($paths);

        echo '<h6>' . $month . '</h6><div><ul>';

        foreach ($paths as $path => $timestamp) {

        echo '<li>' . $path . '</li>';
    }
        echo '</ul></div>';

    }
        echo '</div>';

1 个答案:

答案 0 :(得分:2)

由于您的最终目标是按月对文件名进行分组,因此您需要一个循环来仅显示$files数组中与特定月份匹配的条目:

$months = array(
    '2018-07',
    '2018-06',
    '2018-05',
    '2018-04'
);

foreach ($months as $month) {
    // just some example markup
    echo '<p>' . $month . '</p>';

    echo '<ul>';
    foreach ($files as $path => $timestamp) {
        if (date('Y-m', $timestamp) == $month) {
            echo '<li>' . $path . '</li>';
        }
    }
    echo '</ul>';
}

如果您已经知道不打算将$files数组用于其他任何内容,则另一个选项可能是在处理glob结果时简单地对文件进行分组:

foreach (glob("*.php") as $path) {
    $timestamp = filemtime($path);

    $files[date('Y-m', $timestamp)][$path] = $timestamp;
}

因为它现在是一个嵌套数组,所以你不能简单地arsort()整个事情。但是你可以延迟它,直到你想循环文件列表来生成所需的HTML输出:

// first sort the whole thing by keys (year + month), so that the months are sorted:
krsort($files);

foreach ($files as $month => $paths) {
    // now sort the paths by their timestamps
    arsort($paths);

    // and output whatever markup you want
    echo '<p>' . $month . '</p>';

    echo '<ul>';
    foreach ($paths as $path => $timestamp) {
        echo '<li>' . $path . '</li>';
    }
    echo '</ul>';
}

更新问题后编辑

您似乎误解了在循环中定义变量的基本概念。

您的代码中有两个独立的循环:一个用于处理glob()的结果,另一个用于将该处理的结果转换为jQuery手风琴的标记。

通过在第一个循环中定义$monthname,它会在处理完glob()结果时保持其最后一个值。

您希望在第二个循环中使用 $monthname,但您没有将其设置在那里。因此,始终是相同的值:处理glob()结果时的最后一个值。相反,您应该定义要使用它的$monthname

  

旁注:我在答案中使用了date('Y-m')作为例子,因为我不知道你要展示什么。如果您始终希望将日期显示为date('F'),则只需将其用于数组键即可。然后,无需跟踪单独的$monthname变量,您只需在第二个循环中输出$month值即可。但是,如果您的文件在同一个月但在不同年份已被修改,那么可能可能不是您想要的。

至于您所看到的具体警告,它们是由于您现在将每个文件存储到$files数组两次这一事实引起的:

foreach (glob("*.php") as $path) {
    if($path == 'index.php') {
    continue;
    }  // removes all files names index.php

/**** HERE: ****/
    $files[$path] = filemtime($path);

    $timestamp = filemtime ($path);
    // needed to define $timestamp

/**** AND HERE: ****/
    $files[date('Y-m', $timestamp)][$path] = $timestamp;

    $monthname = (date('F', $timestamp));
    // display month full name instead of month numeral
}

这意味着$files数组看起来像这样:

Array
(
    [/var/www/file.php] => 1529239095
    [2018-06] => Array
        (
            [/var/www/file.php] => 1529239095
        )

)

因为你仍然有第一个作业,你现在偶尔会尝试排序(你复制/粘贴错误,它应该是arsort()而不是krsort())时间戳(整数)一组path => timestamp个条目。你应该删除第一个作业。