在3列中显示3个目录中的文件,以及每个文件的创建/修改日期

时间:2019-03-04 22:03:41

标签: php

我正在寻求一些帮助,以使其正常工作。

在根目录下,我有一个index.php文件(如下所示),并且我还有3个文件夹。图像被随机添加到这些文件夹中,我要做的是在表的这三列中显示(排序)每个文件夹中的最新文件及其创建/修改日期,或基本上是它们的添加日期。

我添加了一个屏幕截图以显示到目前为止的内容,通过浏览每个文件夹中的最新文件,这3列可以正常工作。但是,在每个图像下,它们似乎都具有相同的修改日期,这是错误的。

谁能看到我要去哪里错了?

<?php
date_default_timezone_set('Europe/London');
$dirname = "dir1";
$dirnameTwo = "dir2";
$dirnameThree = "dir3";

$cam1 = scandir($dirname, 1);
$cam2 = scandir($dirnameTwo, 1);
$cam3 = scandir($dirnameThree, 1);
?>
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>

<head>
    <meta http-equiv='refresh' content='10'>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    <meta http-equiv='cache-control' content='max-age=0' />
    <meta http-equiv='cache-control' content='no-cache' />
    <meta http-equiv='expires' content='0' />
    <meta http-equiv='expires' content='Tue, 01 Jan 1980 1:00:00 GMT' />
    <meta http-equiv='pragma' content='no-cache' />
</head>
<html>

<body>
<style type="text/css">
    .pi-title {
        padding: 1rem;
    }
</style>
<div class="container">
    <div class="row">
        <div class="pi-title">
            <h3>Testing</h3>
        </div>
        <div class="table-container col-md-12">
            <table class="table" border='1' cellpadding='5' cellspacing='0' bordercolor='#ccc'>
                <thead class="thead-dark">
                <tr>
                    <th scope="col">ID</th>
                    <th scope="col">1</th>
                    <th scope="col">2</th>
                    <th scope="col">3</th>
                </tr>
                </thead>
                <tbody>
                <tr></tr>
                <tr>
                    <?php
                    error_reporting(E_ALL & ~E_NOTICE);
                    array_multisort(array_map('filemtime', ($files = glob("*.*", GLOB_BRACE))), SORT_DESC, $files);
                    $dirs = array($dirname, $dirnameTwo, $dirnameThree);
                    foreach ($files as $filename) {
                                    for ($i = 1; $i <= 12; $i++) {
                                    if (file_exists($filename)) {
                                        echo "</tr>";
                                        echo "<td><font face='Arial' size='6'>$i</font></td>";
                                    echo "<td><img src='$dirs[0]/$cam1[$i]' height='180' width='220'><br>" . date("F d Y H:i", filemtime($filename));
                                    echo "</td>";
                                    echo "<td><img src='$dirs[1]/$cam2[$i]' height='180' width='220'><br>" . date("F d Y H:i", filemtime($filename));
                                    echo "</td>";
                                    echo "<td><img src='$dirs[2]/$cam3[$i]' height='180' width='220'><br>" . date("F d Y H:i", filemtime($filename));
                                    echo "</td>";
                                    }
                           if ($i === 12) break;
                           }
                        if ($i === 12) break;
                    }
                    ?>
                </tr>
                </tbody>
            </table>
        </div>
    </div>
</div>

Current Result

1 个答案:

答案 0 :(得分:0)

在这里我将为其中1个人做

//covers a single folder
$dirname = "dir1";
$cam1 = [];
foreach(array_diff(scandir($dirname), ['.','..']) as $file){
    $pathname = $dirname.DIRECORY_SEPERATOR.$file;
    if(is_dir($pathname)) continue; //skip folders

    $cam1[filemtime($pathname).'-'.$file] = $pathname;
}

ksort($cam1, SORT_NATURAL);
$latest = end($cam1);

理想情况下,您可以在函数或循环中使用以上内容。循环或函数会更好,因为如果您必须在其中添加另一个文件夹,则只需将其添加到数组中或使用它来调用函数。如果没有这个(如果有的话),如果要添加另一个,则必须复制所有代码。对于数组,它是这样的:

//covers all 3 directories
$dirs = ["dir1","dir2","dir3"];

$results = [];
foreach($dirs as $dirname){
   $res = [];
   if(!is_dir($dirname)) continue; //or issue an error

   foreach(array_diff(scandir($dirname), ['.','..']) as $file){
       $pathname = $dirname.DIRECORY_SEPERATOR.$file;
       if(is_dir($pathname)) continue; //skip folders

       $res[filemtime($pathname).'-'.$file] = $pathname;
   }

   ksort($res, SORT_NATURAL);
   $results[$dirname] = end($res);
}

//['dir1' => 'dir1/somefile.jpg', 'dir2' => ....]

解释一下。

array_diff删除了...之类的路径,这是scandir的常见问题。这些就像备份或备份文件夹。

作为额外的预防措施,我们可以检查给定“路径”是否为跳过继续目录的目录。

filemtime

以UNIX时间戳获取文件的时间,然后我们附加文件名,因为如果在完全相同的时间制作了2个文件,我们希望将它们都保留。

然后,我们可以对键进行排序,这些键应该(如果我没记错的话)将最高的键放在最后(或较大的最近时间戳记)。然后,我们只需使用end从数组中获取最后一个。

scandir排序参数(参数2)仅适用于文件名。

更新

  

[我将如何回应时间戳记

有两种简单的方法,您可以再次使用filemtime

echo filemtime($results[$dirname]);

或者您可以在遍历它们时将其添加到其中:

   foreach(array_diff(scandir($dirname), ['.','..']) as $file){
       $pathname = $dirname.DIRECORY_SEPERATOR.$file;
       if(is_dir($pathname)) continue; //skip folders

       $filemtime = filemtime($pathname);

       //$res[filemtime($pathname).'-'.$file] = $pathname;
       //change the structure of this to:

       $res[$filemtime.'-'.$file] = [
             'pathname'=>$pathname,
             'mtime' => $filemtime
       ]; 
   }

然后你会做

echo $results[$dirname]['mtime'];

对于最后一个,我将其作为一个完整的功能来实现(首选):

//all the above stuff wrapped in a function
function getLatestFromFolders($dirs, array $exclude = ['.','..']){
   //normalize to array
   if(!is_array($dirs)) $dirs = [$dirs];
   $results = [];
   foreach($dirs as $dirname){
      //if(!is_dir($dirname)) continue; //or issue an error
      if(!is_dir($dirname)) throw new Exception($dirname.' Not found');

      $res = [];

      foreach(array_diff(scandir($dirname), $exclude) as $file){
          $pathname = $dirname.DIRECORY_SEPERATOR.$file;
          if(is_dir($pathname)) continue; //skip folders

          $filemtime = filemtime($pathname);

          $res[$filemtime.'-'.$file] = [
             'pathname'=>$pathname,
             'mtime' => $filemtime
          ]; 
      }//end foreach $files

       ksort($res, SORT_NATURAL);
       $results[$dirname] = end($res);
  }//end foreach $dirs

  return $results;
} //end getMyFolders

//call it like this for one path
$results = getLatestFromFolders('dir1');
echo $results['dir1']['mtime'];
echo $results['dir1']['pathname'];

//call it like this for multiple paths
$results = getLatestFromFolders(['dir1','dir2']);
echo $results['dir1']['mtime'];
echo $results['dir2']['mtime'];

//call it like this to exclude file .htaccess or any other files 
//the ['.','..'] dosnt matter because of if(is_dir($pathname)) continue; //skip folders
$results = getLatestFromFolders(['dir1','dir2'], ['.htaccess']);
echo $results['dir1']['mtime'];
echo $results['dir2']['mtime'];

未经测试,但理论上应该可以工作。由于scandir在大多数情况下都处于关闭状态,因此我无法在sanbox中对其进行测试。

所以请原谅任何错别字...

我只是想使用preg_grepfunction getLatestFromFolders($dirs, $regex = '/.+/'){ ... foreach(preg_grep($regex, scandir($dirname)) as $file)对文件名使用正则表达式。然后,您可以进行getLatestFromFolders($dir, '/\.(jpg|png)$/')等操作并匹配扩展名,但是我将把它再留一天。

谢谢!