SplFileInfo 在 PHP 7.4 中原生可用,但需注意:路径必须存在且预检,getCTime() 在 Linux 下非创建时间而是 inode 更改时间,getType() 与 isFile() 行为不同,getPerms() 返回八进制数值,且对象缓存 stat 结果不自动更新。

SplFileInfo 在 PHP 7.4 中完全可用,无需额外扩展,但要注意它不返回“真实创建时间”——尤其在 Linux 下 getCTime() 是 inode 更改时间,不是 Windows 意义上的创建时间。
怎么安全初始化 SplFileInfo 对象
传入的路径必须存在且可访问,否则多数方法(如 getSize()、getMTime())会返回 false,而不是抛异常。PHP 不会自动检查路径合法性。
- 用
is_file()或file_exists()预检再实例化,避免后续调用返回意外false - 路径支持相对路径、绝对路径、甚至带
phar://或zip://封装协议的文件(只要底层流包装器支持) - 如果路径含中文或特殊字符,确保 PHP 运行环境的 locale 和文件系统编码一致,否则
getBasename()可能截断或乱码
获取时间戳时为什么 getCTime() 在 Linux 下不准
Linux 文件系统(ext4/xfs 等)不记录“创建时间”,getCTime() 实际对应 stat 结构体中的 st_ctime,即“inode 元数据最后一次变更时间”——包括权限修改、所有者变更、重命名等,和文件内容无关。Windows NTFS 才真正存有 creation time。
-
getMTime()在所有平台都可靠:文件内容最后一次写入时间 -
getATime()受noatime挂载选项影响,Linux 上可能长期不更新 - 若业务强依赖“创建时间”,需在应用层自己写入时间戳到文件头、数据库或 xattr(Linux 扩展属性),不能依赖
getCTime()
判断文件类型和权限的常见误用点
getType() 返回 "file"、"dir" 或 "link",但它不等价于 isFile() —— 后者做的是 is_file() 系统调用,而 getType() 是基于 stat() 的缓存推导,对符号链接行为不同。
立即学习“PHP免费学习笔记(深入)”;
- 用
isFile()/isDir()/isLink()做逻辑分支,它们语义明确且跨平台一致 -
getPerms()返回八进制数值(如33188),不是字符串"0644";要格式化成常用权限表示,得用sprintf('%o', $file->getPerms() & 0777) -
isReadable()和isWritable()检查的是当前 PHP 进程的有效 UID/GID 权限,不是文件所有者视角——例如 webserver 用户无法写入 root 所有但权限为 644 的文件,这两个方法就返回false
链式调用和类型安全怎么配合 PHP 7.4 属性声明
SplFileInfo 本身不强制类型,但你可以把它作为 DTO 或实体类的属性,利用 PHP 7.4+ 的类型声明增强可控性。比如封装一个只读文件元数据对象:
$file = new SplFileInfo('/tmp/data.txt');
class ReadOnlyFile
{
public SplFileInfo $info;
public string $extension;
public int $size;
public function __construct(string $path)
{
$this->info = new SplFileInfo($path);
$this->extension = $this->info->getExtension();
$this->size = $this->info->getSize() ?: 0; // 处理 false
}
}
- 直接声明
public SplFileInfo $info能防止被赋值为数组或字符串,IDE 和静态分析工具也能识别 - 注意
getSize()、getMTime()等方法返回int|false,不能直接赋给int类型属性,需判空或转换 - 如果要用
?SplFileInfo表示可为空,必须确保构造逻辑允许 null,并在后续所有调用前加isset()或空合并
真正容易被忽略的是:SplFileInfo 缓存了第一次 stat() 的结果,后续多次调用 getMTime() 或 getSize() 返回的是初始快照,不是实时值。需要最新状态时,得重建对象或手动清缓存(无公开 API,只能 new 新实例)。



















