
本文介绍如何准确识别并重命名指定目录下最新修改的文件(如将 file_0202.json 改为 file.json),解决因路径缺失、排序逻辑错误或正则误匹配导致的重命名失败问题。
在 php 中,仅依赖 scandir() 按字母降序排列文件名(如 file_0202.json、file_0101.json)无法可靠获取“最新文件”——因为文件名时间戳不等于实际修改时间,且 scandir() 不返回完整路径,导致 rename() 因相对路径错误而失败。
✅ 正确做法是:
- 使用 glob(‘content/myfiles/*.*’) 获取带完整路径的文件列表;
- 用 usort() + filemtime() 按最后修改时间(而非文件名)逆序排序;
- 安全提取并重命名目标文件,注意保留原始目录路径。
以下是优化后的完整代码:
Directory = 'content/myfiles'; $files = glob($directory . '/*.*'); // ✅ 返回含路径的绝对/相对路径(如 'content/myfiles/file_0202.json') // ⚠️ 空目录防护 if (empty($files)) { echo 'No files found.'; exit; } // 按最后修改时间降序排序(最新在前) usort($files, function($a, $b) { return filemtime($b) <=> filemtime($a); // PHP 7+ 强烈推荐使用 <=>(飞船操作符) }); $selected_file = $files[0]; $dirname = dirname($selected_file); $basename = basename($selected_file); // ? 精准替换:仅匹配文件名中最后一个下划线及其后、直到点号前的部分(避免误改路径或扩展名) $new_basename = preg_replace('/_[^_.]*.(?=[^.]*$)/', '.', $basename); $new_filepath = $dirname . '/' . $new_basename; // ✅ rename() 必须传入完整源路径和目标路径 if (rename($selected_file, $new_filepath)) { echo "Renamed successfully: {$basename} → {$new_basename}"; } else { echo "Failed to rename. Check permissions, file locks, or target existence."; } ?>
? 关键注意事项:
立即学习“PHP免费学习笔记(深入)”;
- scandir() 返回的是纯文件名,rename() 需要完整路径,否则会尝试在当前工作目录操作,必然失败;
- filemtime() 比 filectime() 更适合“最新内容”场景(修改时间 vs 创建时间,windows 下语义不同);
- 正则 /_[^_.]*./ 在原代码中未限定作用域,若 $selected_file 含路径(如 content/myfiles/file_0202.json),可能错误匹配路径中的 _;改进版先用 basename() 提取文件名再处理;
- 建议添加错误检查:file_exists()、is_writable()、error_get_last() 可进一步增强健壮性;
- 若仅处理 .json 文件,将 glob() 改为 glob($directory . ‘/*.json’) 更高效且安全。
通过以上方法,即可稳定、安全地重命名最新修改的文件,避免常见陷阱。