全局文件并按文件时间和月份排序
Glob files and sort by filemtime and into months
是的,我知道这是丑陋的代码 :) 而且它不起作用。
我正在遍历目录中的所有 .php 文件,然后按文件时间戳对它们进行排序,然后我想将文件名回显到每个月。但是我该如何修复这个循环,以便每个月的回显输出都是正确的? $path 的文件按日期排序,但是 $link_title 对于所有月份的所有文件都是相同的,所以我看不到 $paths 按月排列。
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>';
}
}
}
}
}
编辑 2018 年 6 月 21 日
这有效并为 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>';
由于您的最终目标是按月对文件名进行分组,因此您需要一个循环来仅向您显示 $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()
结果时保持它的最后一个值。
您想在 second 循环中 use $monthname
,但您没有在此处设置它。因此,它将 始终 是相同的值:处理 glob()
结果时的最后一个值。相反,您应该在要使用它的地方定义 $monthname
。
Sidenote: I used date('Y-m')
in my answer as an example, since I didn't know what you were going to display. If you always want to display the date as date('F')
, you can simply use that for the array key instead. Then there's no need to keep track of a separate $monthname
variable and you can simply output the $month
value in the second loop. However, this might not be what you want, if you have files in there that have been modified in the same month but in different years.
至于您看到的具体警告,它们是由于您现在将每个文件存储到 $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
)
)
因为你仍然有第一个任务,你现在偶尔会尝试排序(你 copy/pasted 不正确,它应该是 arsort()
而不是 krsort()
)时间戳(整数)而不是 path => timestamp
条目的数组。您应该删除第一个作业。
是的,我知道这是丑陋的代码 :) 而且它不起作用。
我正在遍历目录中的所有 .php 文件,然后按文件时间戳对它们进行排序,然后我想将文件名回显到每个月。但是我该如何修复这个循环,以便每个月的回显输出都是正确的? $path 的文件按日期排序,但是 $link_title 对于所有月份的所有文件都是相同的,所以我看不到 $paths 按月排列。
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>';
}
}
}
}
}
编辑 2018 年 6 月 21 日
这有效并为 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>';
由于您的最终目标是按月对文件名进行分组,因此您需要一个循环来仅向您显示 $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()
结果时保持它的最后一个值。
您想在 second 循环中 use $monthname
,但您没有在此处设置它。因此,它将 始终 是相同的值:处理 glob()
结果时的最后一个值。相反,您应该在要使用它的地方定义 $monthname
。
Sidenote: I used
date('Y-m')
in my answer as an example, since I didn't know what you were going to display. If you always want to display the date asdate('F')
, you can simply use that for the array key instead. Then there's no need to keep track of a separate$monthname
variable and you can simply output the$month
value in the second loop. However, this might not be what you want, if you have files in there that have been modified in the same month but in different years.
至于您看到的具体警告,它们是由于您现在将每个文件存储到 $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
)
)
因为你仍然有第一个任务,你现在偶尔会尝试排序(你 copy/pasted 不正确,它应该是 arsort()
而不是 krsort()
)时间戳(整数)而不是 path => timestamp
条目的数组。您应该删除第一个作业。