【问题标题】:How to get the newest file in a directory in php如何在php中获取目录中的最新文件
【发布时间】:2012-07-20 19:07:35
【问题描述】:

所以我有这个处理 CSV 文件的应用程序。我有一行代码来加载文件。

$myFile = "data/FrontlineSMS_Message_Export_20120721.csv";  //The name of the CSV file
$fh = fopen($myFile, 'r');                             //Open the file

我想找到一种方法,可以在 data 目录中查找并获取最新文件(它们都有日期标签,因此它们将在 data 中按顺序排列)并将名称设置为$myFile.

我真的找不到和理解 php 目录的文档,所以任何有用的资源也将不胜感激。谢谢。

【问题讨论】:

标签: php directory


【解决方案1】:

这是使用scandir 的尝试,假设目录中仅有的文件具有时间戳文件名

$files = scandir('data', SCANDIR_SORT_DESCENDING);
$newest_file = $files[0];

我们首先按降序列出目录中的所有文件,然后,该列表中的第一个文件名具有“最大”文件名——因此时间戳值最大——因此是最新的。

请注意,scandir 是在 PHP 5 中添加的,但its documentation page 显示了如何在 PHP 4 中实现该行为。

【讨论】:

  • @Mike: 酷 :) 我现在离开我的启用 PHP 的盒子,所以这个示例虽然只有两行长,但未经测试,所以如果它不起作用,请告诉我它应该是什么。
  • 常量 SCANDIR_SORT_DESCENDING 和 SCANDIR_SORT_ASCENDING 是从 PHP 5.4 开始定义的——对于 5.4 之前的 PHP 5 版本,您必须分别使用 1 和 0 来定义排序顺序。
  • 如果我错了请纠正我,但 scandir 按字母顺序对节点名称进行排序,而不是时间戳值顺序。
  • @mike:没错!碰巧,OP 的文件在名称中包含时间戳,因此在这里按名称排序就足够了。不知道如何在实际修改日期之前做到这一点......
  • 重要提示:如上所述,这是 alpha 排序,而不是实际的时间戳排序。因此,如果日期戳反映在文件名中,它将正常工作,否则将不会给出预期的结果。
【解决方案2】:

对于带有通配符的搜索,您可以使用:

<?php
$path = "/var/www/html/*";

$latest_ctime = 0;
$latest_filename = '';

$files = glob($path);
foreach($files as $file)
{
        if (is_file($file) && filectime($file) > $latest_ctime)
        {
                $latest_ctime = filectime($file);
                $latest_filename = $file;
        }
}
return $latest_filename;
?>

【讨论】:

  • 请不要只发布代码作为答案,还要解释您的代码的作用以及它如何解决问题的问题。带有解释的答案通常更有帮助,质量更高,更有可能吸引投票。
【解决方案3】:

我的解决方案,Max Hofmann 改进的解决方案:

$ret = [];
$dir = Yii::getAlias("@app") . "/web/uploads/problem-letters/{$this->id}"; // set directory in question

if(is_dir($dir)) {
   $ret = array_diff(scandir($dir), array(".", "..")); // get all files in dir as array and remove . and .. from it
}

usort($ret, function ($a, $b) use ($dir) {
    if(filectime($dir . "/" . $a) < filectime($dir . "/" . $b)) {
         return -1;
    } else if(filectime($dir . "/" . $a) == filectime($dir . "/" . $b)) {
         return 0;
    } else {
         return 1;
    }
}); // sort array by file creation time, older first

echo $ret[count($ret)-1]; // filename of last created file

【讨论】:

    【解决方案4】:

    这是一个例子,我觉得使用自己的验证器而不是简单地依赖带有scandir() 的时间戳更有信心。

    在这种情况下,我想检查我的服务器是否有比客户端版本更新的文件版本。所以我从文件名中比较版本号。

    $clientAppVersion = "1.0.5";
    $latestVersionFileName = "";
    
    $directory = "../../download/updates/darwin/"
    $arrayOfFiles = scandir($directory);
    foreach ($arrayOfFiles as $file) {
        if (is_file($directory . $file)) {
            // Your custom code here... For example:
            $serverFileVersion = getVersionNumberFromFileName($file);
            if (isVersionNumberGreater($serverFileVersion, $clientAppVersion)) {
                $latestVersionFileName = $file;
            }
        }
    }
    
    
    // function declarations in my php file (used in the forEach loop)
    function getVersionNumberFromFileName($fileName) {
        // extract the version number with regEx replacement
        return preg_replace("/Finance D - Tenue de livres-darwin-(x64|arm64)-|\.zip/", "", $fileName);
    }
    
    function removeAllNonDigits($semanticVersionString) {
        // use regex replacement to keep only numeric values in the semantic version string
        return preg_replace("/\D+/", "", $semanticVersionString);
    }
    
    function isVersionNumberGreater($serverFileVersion, $clientFileVersion): bool {
        // receives two semantic versions (1.0.4) and compares their numeric value (104)
        // true when server version is greater than client version (105 > 104)
        return removeAllNonDigits($serverFileVersion) > removeAllNonDigits($clientFileVersion);
    }
    

    使用此手动比较而不是时间戳,我可以获得更手术的结果。如果您有类似的需求,我希望这能给您一些有用的想法。

    (PS:我花时间发布,因为我对我找到的与我的特定要求相关的答案不满意。请善待我也不太习惯 StackOverflow - 谢谢!)

    【讨论】:

    • 感谢您分享您的解决方案,但由于它没有回答提问者的问题,因此这里可能没有用。此外,任何寻找与您类似的解决方案的人都很难在答案中找到它。如果您想分享一个新颖的想法或解决方案,可以尝试就您解决的问题提出问题并自己回答。这将帮助面临相同问题的其他人通过搜索轻松找到您的解决方案。
    • 谢谢@SakibulAlam。我应该从这里删除它吗?
    猜你喜欢
    • 2012-03-11
    • 1970-01-01
    • 2021-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-04
    相关资源
    最近更新 更多