PHP实现仅列出目录中近一年内创建文件的问题排查
问题分析与解决
原代码的错误点
- 函数名错误:PHP中不存在
filetime()函数,正确获取文件时间的函数是filemtime()(文件最后修改时间)或filectime()(Windows下为文件创建时间,Linux下为文件元数据修改时间)。 - 语法错误:
if(filetime($item) > $beginningTimeStamp && < $todayTimeStamp)中,&&后缺少比较变量,应写成filemtime($item) < $todayTimeStamp。 - 输出错误:
echo "basename($item)";会直接输出字符串basename($item),而非调用函数获取文件名,正确写法是echo basename($item);。 - 变量名拼写错误:
$beginningTimeTtamp多打了一个t,应为$beginningTimestamp。 - 时间范围冗余:
$todayTimeStamp是当天零点的时间戳,文件时间戳不可能大于当前时间(系统时间异常除外),无需额外判断。
对疑问的解答
时间戳比较是否错误?
时间戳比较的思路本身没问题,但代码里的函数错误、语法错误导致逻辑失效,且时间范围判断冗余。只需判断文件时间戳大于一年前的时间戳即可。无法获取每个文件的filetime?
不是无法获取,是用了错误的函数名。替换成filemtime()或filectime()就能正常获取文件对应的时间戳。是否有更优实现方式?
有两种更优方案:- 修正原代码错误并简化逻辑;
- 使用
DirectoryIterator类,这是PHP专门用于目录遍历的工具,代码更简洁,性能更优,无需手动维护文件列表和排序。
修正后的基础版本代码
<?php $dirpath = "Dir/foo/bar/"; $files = glob($dirpath . "*"); rsort($files); // 计算一年前的时间戳 $oneYearAgo = strtotime("-1 year"); foreach($files as $item) { // 跳过目录,仅处理文件(可选,按需调整) if(!is_file($item)) continue; $fileTime = filemtime($item); if($fileTime > $oneYearAgo) { echo basename($item) . PHP_EOL; } }
更优的DirectoryIterator实现版本
<?php $dirpath = "Dir/foo/bar/"; $oneYearAgo = strtotime("-1 year"); $iterator = new DirectoryIterator($dirpath); foreach($iterator as $fileInfo) { // 跳过.、..及目录,仅处理文件 if($fileInfo->isDot() || !$fileInfo->isFile()) continue; $fileTime = $fileInfo->getMTime(); if($fileTime > $oneYearAgo) { echo $fileInfo->getBasename() . PHP_EOL; } }
该版本无需手动获取文件列表,DirectoryIterator会自动遍历目录,还能直接获取文件的各类属性,代码更简洁易维护。
内容的提问来源于stack exchange,提问作者Dirty Bird Design
相关产品推荐
相关产品推荐

