首页 > 解决方案 > 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

解决方案


这是对我有用的完整解决方案,在调试环境中进行了测试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;

使用我们对两个目录的“值交换”。


推荐阅读