【问题标题】:Show files from 3 directories in 3 columns and each files creation/modified date在 3 列中显示来自 3 个目录的文件以及每个文件的创建/修改日期
【发布时间】:2019-03-05 07:01:35
【问题描述】:

我正在寻求一些帮助来完成这项工作。

在根目录中,我有一个 index.php 文件(如下所示),我还有 3 个文件夹。图像被随机添加到这些文件夹中,我想做的是在表格的这 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

【问题讨论】:

    标签: php


    【解决方案1】:

    这里我会为其中的 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 的常见烦恼。这些类似于 back 或 up 文件夹。

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

    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'];
    

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

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

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

    谢谢!

    【讨论】:

    • 对于其他目录,我需要再做 2 个 foreach 循环吗?在循环中我将如何回显时间戳?
    • @ArtisticPhooenix 感谢您迄今为止的帮助,伙计,我整个星期都得到了最接近的帮助。时间戳的回声 (echo filemtime($results[$dirname]);) 显示 'January 01 1970 01:00' 我猜第二列我只是使用相同的循环但用 $ 更改 $dirname dirnameTwo?
    • 重点是不要更改代码中的任何内容,而是更改代码使用的输入。这样代码就可以重用了。 (echo filemtime($results[$dirname]);) is showing 'January 01 1970 01:00' 什么是$results[$dirname] 应该是带路径的文件名。
    • 如果您使用最后一个示例函数One last one is this:,那么您将使用$results = getLatestFromFolders($dirname); 然后if(isset($results[$dirname])) echo $results[$dirname]['mtime'];
    • 我现在试试,谢谢你的帮助队友,这个问题卡了一周左右,哈哈
    猜你喜欢
    • 2017-12-07
    • 1970-01-01
    • 2019-08-15
    • 2021-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多