php - PHP:检查来自两个目录的文件(或递归地检查子目录)
问题描述
如果我能问一个关于 php 的问题,我将不胜感激。
在我的网站中,我将使用 public_html 下的文件“timestamp.php”来显示更新目录“public_html”中文件的时间间隔。
$dir = dir($directory); // get directory handler
while(($file = $dir->read()) !== false) { // read the directory in loop
if($file == '..') continue; // this is the parent folder
if($file == '.') continue; // this is the current folder // this is the php file
让我称这个网站为“正式网站”。
现在我想创建一个“开发站点”但共享相同的时间计数器:即更新“开发站点”也会更新显示在正式站点上的计数器。
我在 public_html/development_site 建立了“开发站点”。(我不确定这是否是放置“development_site”的最佳位置,但作为初学者)
但是此时更新 public_html 中的文件确实会更新计数器,但更新 public_html/development_site 中的文件不会更新计数器。
因此我需要设置timestamp.php 来查找public_html/development_site 中的文件。我想知道如何修改 timestamp.php 以检查 public_html/development_site 中的文件。
我试过了
$directory= "/nfs/.../public_html";
$devdirectory="/nfs/.../public_html/development_site";
$dir = dir($directory); // get directory handler
$dir2=dir($devdirectory);//
while((($file = $dir2->read()) !== false)|| (($file = $dir->read()) !== false))
{ // read the directory in loop
if($file == '..') continue; // this is the parent folder
if($file == '.') continue; // this is the current folder // this is the php file
但是当开发目录中的文件更新时,它不会更新计数器。我会很感激评论。
这是整个代码。
<?php
$stats_array = array();
$counter = 1;
$directory = "/nfs/.../public_html";
$devdirectory = "/nfs/.../public_html/dev";
if(is_file('/nfs/.../filestat.txt')) {
$file_array = file('/nfs/.../filestat.txt');
foreach($file_array as $line) {
// tab delimited timestamp, filename, counter
$line = trim($line);
if(!empty($line)) {
$line_array = explode("\t",$line);
$stats_array[md5($line_array[1])] = $line_array;
}
}
}
$files = array(); // create empty array
$dir = dir($directory); // get directory handler
$dir2 = dir($devdirectory); // get directory handler
while(($file = $dir->read()) !== false) { // read the directory in loop
if($file == '..') continue; // this is the parent folder
if($file == '.') continue; // this is the current folder // this is the php file
if(strpos($file, '.jpg') !== false) continue;
if(strpos($file, '.jpeg') !== false) continue;
if(strpos($file, '.xml') !== false) continue;
if(strpos($file, '.gif') !== false) continue;
if(strpos($file, '.png') !== false) continue;
if(strpos($file, '.png') !== false) continue;
if(strpos($file, '.html') == false) continue; // this is the html file
if($file == '.htaccess') continue; // this is the security file
if($file == 'filestat.txt') continue; // this is the stats file
$file = $directory . '/' . $file;
if(is_dir($file)) continue; // this is the folder
if(!file_exists($file)) continue;
$fileinfo = new SplFileInfo($file); // get file info object
// put the file info into an array with UNIXTIME key.
$files[$fileinfo->getMTime()] = array('name'=>$file,'mtime'=>date('Y:m:d:H:i:s', $fileinfo->getMTime()),'unixtime'=>$fileinfo->getMTime());
$key = md5($file);
if(array_key_exists($key, $stats_array)) {
if($stats_array[$key][0] != date('Y:m:d:H:i:s', $fileinfo->getMTime())) {
$stats_array[$key][2]++;
$stats_array[$key][0] = date('Y:m:d:H:i:s', $fileinfo->getMTime());
}
} else {
$stats_array[$key] = array(
date('Y:m:d:H:i:s', $fileinfo->getMTime()),
$file,
1
);
}
$datetime = new \DateTime();
$datetime->setTimestamp($fileinfo->getMTime());
$files[$fileinfo->getMTime()]['age'] = $datetime->diff(new \DateTime())->format('%H:%I:%S');
if($datetime->diff(new \DateTime())->format('%a') != '0')
{
$days = ($datetime->diff(new \DateTime())->format('%a') == '1') ? ' day ' : ' days ';
$files[$fileinfo->getMTime()]['age'] = $datetime->diff(new \DateTime())->format('%a') . $days . $files[$fileinfo->getMTime()]['age'];
}
}
$dir->close(); // close the handler
ksort($files); // sort array by keys in ascending order
$newest_file = array_pop($files); //extract latest file from array
foreach($stats_array as $stat) {
$counter += $stat[2];
}
printf(
"Counter %s. (%s) Time Since the Last upload: <span class='update_time' mtime='%s'>%s</span>.",
$counter,
$newest_file['mtime'],
$newest_file['unixtime'],
$newest_file['age']// this is formatted date and time string
);
$put = '';
foreach($stats_array as $line) {
$put .= implode("\t",$line)."\n";
}
file_put_contents('/nfs/.../filestat.txt',$put);
?>
解决方案
这是对我有用的完整解决方案,在调试环境中进行了测试php v7.3.19-1~deb10u1
:
<?php
/*-----
CONFIG
------*/
$filestat_path = "/nfs/.../filestat.txt";
$directory = "/nfs/.../public_html";
$devdirectory = "/nfs/.../public_html/dev";
/*-----*/
$stats_array = array();
$counter = 1;
if(is_file($filestat_path)) {
$file_array = file($filestat_path);
foreach($file_array as $line) {
// tab delimited timestamp, filename, counter
$line = trim($line);
if(!empty($line)) {
$line_array = explode("\t",$line);
$stats_array[md5($line_array[1])] = $line_array;
}
}
}
$files = array(); // create empty array
$dir1 = dir($directory); // get directory handler
$dir2 = dir($devdirectory); // get directory handler
$switch = true; //we change this to false as we want to switch to $dir2
do {
//if true this if not this
$file = $switch ? $dir1->read() : $dir2->read(); //dynamically assigning $dir1 or $dir2 to $file according to value of $switch
$crdir = $switch ? $directory : $devdirectory;
if ($file !== false) {
//
//Your loop handling
//
if($file == '..') continue; // this is the parent folder
if($file == '.') continue; // this is the current folder // this is the php file
if(strpos($file, '.jpg') !== false) continue;
if(strpos($file, '.jpeg') !== false) continue;
if(strpos($file, '.xml') !== false) continue;
if(strpos($file, '.gif') !== false) continue;
if(strpos($file, '.png') !== false) continue;
if(strpos($file, '.png') !== false) continue;
if(strpos($file, '.html') == false) continue; // this is the html file
if($file == '.htaccess') continue; // this is the security file
if($file == 'filestat.txt') continue; // this is the stats file
$file = $crdir . '/' . $file;
if(is_dir($file)) continue; // this is the folder
if(!file_exists($file)) continue;
$fileinfo = new SplFileInfo($file); // get file info object
// put the file info into an array with UNIXTIME key.
$files[$fileinfo->getMTime()] = array('name'=>$file,'mtime'=>date('Y:m:d:H:i:s', $fileinfo->getMTime()),'unixtime'=>$fileinfo->getMTime());
$key = md5($file);
if(array_key_exists($key, $stats_array)) {
if($stats_array[$key][0] != date('Y:m:d:H:i:s', $fileinfo->getMTime())) {
$stats_array[$key][2]++;
$stats_array[$key][0] = date('Y:m:d:H:i:s', $fileinfo->getMTime());
}
} else {
$stats_array[$key] = array(
date('Y:m:d:H:i:s', $fileinfo->getMTime()),
$file,
1
);
}
$datetime = new \DateTime();
$datetime->setTimestamp($fileinfo->getMTime());
$files[$fileinfo->getMTime()]['age'] = $datetime->diff(new \DateTime())->format('%H:%I:%S');
if($datetime->diff(new \DateTime())->format('%a') != '0')
{
$days = ($datetime->diff(new \DateTime())->format('%a') == '1') ? ' day ' : ' days ';
$files[$fileinfo->getMTime()]['age'] = $datetime->diff(new \DateTime())->format('%a') . $days . $files[$fileinfo->getMTime()]['age'];
}
//
//END Your loop handling
//
}
elseif ($switch === true) { //switch to $dir2 if not already
$switch = false;
}
else { //if already switched to $dir2, exit loop
break;
}
} while (true);
$dir1->close(); // close the handler
$dir2->close();
ksort($files); // sort array by keys in ascending order
$newest_file = array_pop($files); //extract latest file from array
foreach($stats_array as $stat) {
$counter += $stat[2];
}
printf(
"Counter %s. (%s) Time Since the Last upload: <span class='update_time' mtime='%s'>%s</span>.",
$counter,
$newest_file['mtime'],
$newest_file['unixtime'],
$newest_file['age']// this is formatted date and time string
);
$put = '';
foreach($stats_array as $line) {
$put .= implode("\t",$line)."\n";
}
file_put_contents($filestat_path,$put);
?>
请注意CONFIG
我在顶部添加的部分,在这里您可以设置和更改路径,它们在脚本中随处使用,因此您只需更改一个值。
解释
我基本上做了一个循环,首先通过主目录,然后通过开发目录($file
变量值的切换是通过变量完成的$switch
,这会影响分配的值),所有这些都由突出显示的配置中的路径变量指定区域。然后遵循您提供的基本未更改的处理代码,这已经完成了,因为所有值都存储在一个变量中,并且最后的排序同时执行“仅显示两个目录的最新更改”的事情。
需要注意的重要一点是,必须对此代码进行一项更改:
该行
$file = $directory . '/' . $file;
必须改为
$file = $crdir . '/' . $file;
在 上方添加以下行if ($file !== false)
:
$crdir = $switch ? $directory : $devdirectory;
使用我们对两个目录的“值交换”。
推荐阅读
- python - on_delete=models.PROTECT 在 Django 中不起作用
- node.js - 在 mongoose 中使用查找填充一个集合
- node.js - 通过 Github Push 在 Heroku 中的 NodeJS 应用程序部署错误
- python - Django 无法在管理页面中登录超级用户
- javascript - Aria 选择器在 FB 上找不到元素
- sql - 在 PostgreSQL 中保存多个用于聚合的动态过滤器
- css - 如何在 React 中减少引导程序的表单宽度输入
- css - CSS 会改变 DOM 吗?
- scala - 将 docker 插件与 sbt 一起使用
- javascript - Fetch-api OpenWeather,访问属性“名称”值并显示它的问题