filesize() 在 PHP 7.4 中最常用但需谨慎使用:文件不存在、权限不足、符号链接失效、独占写入或大文件(>2GB)均会导致返回 false 或错误值;需配合 file_exists()、clearstatcache(true, $path) 及 64 位环境判断,并避免用于远程文件。

filesize() 在 PHP 7.4 中仍是最常用、最直接的本地文件大小获取方式,但它不是“拿来即用”的安全函数——稍不注意就会返回 false、报 E_WARNING、或给出错误数值。
为什么 filesize() 会返回 false 而不是报错?
它失败时不抛异常,只静默返回 false 并触发 E_WARNING(默认在 CLI 或开发环境可见,生产环境常被屏蔽)。常见触发点:
- 文件不存在 —— 必须先用
file_exists()检查,不能只靠if (filesize($path)) - 权限不足 —— Web 进程用户(如
www-data)无读取权限,即使文件存在也失败 - 路径是符号链接但目标不可达 ——
filesize()不自动解析或报错,可能返回false - 文件被其他进程独占写入(如日志轮转中)—— 某些系统下会失败
大文件(>2GB)在 PHP 7.4 下怎么避免溢出?
PHP 7.4 默认仍是 32 位整数平台(尤其 Windows 或旧 Linux 容器),filesize() 对 2–4GB 文件会返回负数或截断值。这不是 bug,而是底层 stat() 系统调用和 PHP int 类型限制共同导致的。
安全做法:
立即学习“PHP免费学习笔记(深入)”;
- 优先确认运行环境是否为 64 位(
PHP_INT_SIZE === 8) - 若不确定,改用
sprintf('%u', filesize($path))强制无符号输出 —— 这能修复 2–4GB 区间显示问题 - 超过 4GB 的文件,
filesize()本身已不可靠,应换用fstat(fopen($path, 'rb'))['size']或直接走 shell 命令(如stat -c '%s' $path)
filesize() 的结果会被缓存,什么时候必须清?
PHP 会缓存文件元数据(包括大小),同一请求内多次调用 filesize() 同一路径,返回的是首次调用时的缓存值 —— 即使文件在这期间被追加或截断,也不会更新。
典型踩坑场景:
- 循环监控日志文件增长:每次
filesize()都得配clearstatcache(true, $path) - 上传后立刻检查大小:若上传前刚调过
filesize(),需清缓存再查 - 并发写入场景(如多个 worker 写同一文件):缓存会让大小判断严重滞后
注意:clearstatcache() 清的是整个缓存;若只清单个文件,务必传 true 和具体 $path,否则无效。
远程文件不能用 filesize()?别硬试
PHP 7.4 默认不支持通过 http:// 或 https:// 路径调用 filesize() —— 即使启用了 allow_url_fopen,多数服务器也禁用 URL wrapper 对 stat() 系列的支持。
强行调用只会返回 false 并报 warning,且无法区分是网络超时、404 还是权限拒绝。
正确替代方案:
- 用
curl_init()发送HEAD请求,读取Content-Length头 - 用
get_headers($url, 1)获取响应头(注意开启user_agent避免被拦截) - 对 OSS、S3 等对象存储,应调用其 SDK 的
headObject方法,而非模拟 HTTP
真正容易被忽略的,是缓存行为和大文件边界 —— 它们不会当场报错,却会在上线后某天突然让“文件大小校验”逻辑失效,而且很难复现。



















