Linux中无法通过touch修改文件创建时间(btime),仅能可靠设置atime和mtime;ctime由内核自动更新,不可手动干预。

touch() 能直接设置文件的修改时间(mtime)和访问时间(atime),但不能改创建时间(ctime)——Linux 下 ctime 是内核自动维护的,PHP 无权覆盖。
用 touch() 创建或更新文件时间戳
最常用场景就是「让一个文件看起来是刚生成的」,比如测试缓存逻辑、模拟日志轮转、或绕过某些基于时间的判断。它会自动创建文件(如果不存在),且默认只设 mtime 和 atime 为当前时间:
-
touch('cache.json'):若文件不存在则新建空文件;存在则把mtime和atime都更新为time() - 返回值是布尔型:
true表示成功,false表示失败(常见于权限不足、路径不存在或磁盘满) - 注意:Web 环境下必须用绝对路径,比如
/var/www/html/logs/error.log;相对路径如'logs/error.log'很可能失败
touch() 设置指定时间戳(含 PHP 8 兼容写法)
要回拨或前移时间,就得传入 mtime 参数。PHP 8.0+ 支持 null 值,更安全:
-
touch('data.txt', time() - 3600):把修改时间设为 1 小时前,atime自动同步为同一时间 -
touch('data.txt', time() - 3600, time() - 7200):mtime设为 1 小时前,atime设为 2 小时前 -
touch('data.txt', null, time() - 3600)(PHP 8.0+):保持原mtime不变,仅更新atime - 时间戳必须是 Unix 时间戳整数(秒级),不是字符串或日期格式;误传
'2026-08-31'会导致函数静默失败
为什么 filectime() 总是不变?
这是正常现象,不是 touch() 的 bug。Linux 文件系统中:
立即学习“PHP免费学习笔记(深入)”;
-
filemtime()对应touch()的mtime参数,可被修改 -
fileatime()对应atime参数,也可被修改(除非挂载时用了noatime) -
filectime()是 inode 元数据变更时间,只要文件内容或权限/所有者等发生变化就会更新;但touch()不动 inode 元数据,所以ctime不变 - 想验证是否生效,别看
filectime(),改完后用filemtime('data.txt')和fileatime('data.txt')检查
Web 环境下容易踩的坑
在 Apache/Nginx + PHP-FPM 场景中,权限和路径问题比 CLI 环境更敏感:
- PHP 进程用户(如
www-data或nginx)必须对目标目录有写权限,否则touch()失败 - 修改符号链接本身的时间戳无效,
touch()会作用于链接指向的目标文件;如需改链接时间,得先unlink()再重建 - 某些容器或只读文件系统(如 Docker volume 挂载为 ro)会直接拒绝
touch(),错误不明显,需检查error_log中的Permission denied - 不要依赖
touch()来“伪造”创建时间——ctime无法伪造,业务逻辑若强依赖创建时间,得换方案(如记录到数据库)
关键点在于:它只管 mtime 和 atime,且 Web 下路径和权限是第一道关卡。别把它当成万能时间机器,该用数据库存时间戳的地方,就别硬塞文件系统。



















