问题描述
是的,我知道这是丑陋的代码:)而且它不起作用.
Yes, I know this is ugly code :) And it doesn't work.
我要遍历目录中的所有.php文件,然后按文件时间戳对其进行排序,然后我希望将文件名回显到每个月.但是,如何解决此循环,以便每个月的回显输出正确? $ path中的文件按日期排序,但是所有月份中所有文件的$ link_title都相同,因此我看不到$ paths是按月排列的.
I'm globbing all the .php files in a directory and then sorting them by file timestamp, and then I want to echo the file names into each month. But how do I fix this loop so the echoed output of each month is correct? The files by $path are sorted by date, but the $link_title is the same for all files in all months, so I don't see that the $paths are getting arranged by month.
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>';
}
}
}
}
}
修改18年6月21日
这有效并输出jQuery手风琴的正确标记:
This works and outputs the correct markup for a jQuery accordian:
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
数组中与特定字符串匹配的条目月:
Since your end-goal is to group the filenames by month, you need a loop to show you only the entries from the $files
array that match a particular month:
$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
结果时简单地将文件分组:
If you already know that you're not going to use your $files
array for anything else, another option might be to simply group the files while processing the glob
results:
foreach (glob("*.php") as $path) {
$timestamp = filemtime($path);
$files[date('Y-m', $timestamp)][$path] = $timestamp;
}
由于它现在是一个嵌套数组,所以不能简单地arsort()
整个过程.但是您可以将其延迟,直到您想要遍历文件列表以生成所需的HTML输出:
Since it's now a nested array, you can't simply arsort()
the whole thing. But you can delay that until you want to loop over the file list to generate the desired HTML output:
// 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>';
}
在更新问题后进行编辑
您似乎误解了在循环中定义变量的基本概念.
You seem to be misunderstanding a basic concept of defining variables in loops.
您的代码中有两个单独的循环:一个处理glob()
的结果,另一个将处理的结果转换为jQuery手风琴的标记.
You have two separate loops in your code: one that processes the result of glob()
and one that turns the result of that processing into markup for your jQuery accordion.
通过在 first 循环中定义$monthname
,当处理glob()
结果完成时,它将保持其最后一个值.
By defining $monthname
in the first loop, it will maintain its last value when processing the glob()
result is finished.
您想在 second 循环中使用 $monthname
,但是您没有在此处设置它.因此,它总是是相同的值:处理glob()
结果时的最后一个值.相反,您应该在要使用的位置定义$monthname
.
You want to use $monthname
in the second loop, but you're not setting it there. Therefore, it will always be the same value: the last value it was when processing the glob()
result. Instead, you should define $monthname
where you want to use it.
对于您看到的特定警告,它们是由您现在将每个文件两次存储到$files
数组中的事实引起的:
As for the specific warnings you're seeing, they are caused by the fact that you're storing each file into the $files
array twice now:
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
数组看起来像这样:
This means that the $files
array looks something like this:
Array
(
[/var/www/file.php] => 1529239095
[2018-06] => Array
(
[/var/www/file.php] => 1529239095
)
)
因为您仍然有第一个赋值,所以现在您偶尔尝试对时间戳(整数)(而不是数组)进行排序(错误地复制/粘贴,应该是arsort()
而不是krsort()
). path => timestamp
条目.您应该删除该第一个任务.
Because you still have that first assignment in there, you now occasionally try to sort (which you copy/pasted incorrectly, it should be an arsort()
instead of krsort()
) a timestamp (integer) instead of an array of path => timestamp
entries. You should remove that first assignment.
这篇关于Glob文件并按filemtime排序,分为几个月的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!