最直接的方式是调用filesize()获取字节数再与阈值比较,需先校验is_file()和is_readable(),上传场景应优先使用$_FILES'x'并配合error判断,注意单位统一为二进制且防范客户端伪造。

用 filesize() 获取文件大小再比较
PHP 判断文件是否超过指定大小,最直接的方式是调用 filesize() 获取字节数,再与阈值比较。它返回的是整型字节数,失败时返回 false(比如文件不存在、权限不足或符号链接指向无效路径),所以必须先检查返回值有效性。
-
filesize()对大文件(如 >2GB)在 32 位系统上可能返回负数或截断——不是 PHP Bug,而是底层off_t类型限制;64 位环境通常无此问题 - 务必用
is_file()和is_readable()做前置校验,避免filesize()警告干扰逻辑 - 阈值建议统一用字节表示(如 5MB →
5 * 1024 * 1024),避免单位歧义;若从配置读字符串(如"5M"),需手动解析
上传文件时用 $_FILES['xxx']['size'] 直接判断
用户上传场景下,$_FILES 数组中的 size 键已包含客户端实际上传的字节数,无需再调用 filesize()。这个值由 PHP 在接收上传时自动填充,可靠且高效。
- 该值在
UPLOAD_ERR_OK时才有效;若上传失败(如UPLOAD_ERR_FORM_SIZE或UPLOAD_ERR_INI_SIZE),size为 0,且不能仅靠size判断是否超限 - 必须配合
$_FILES['xxx']['error'] === UPLOAD_ERR_OK使用,否则可能把上传失败误判为“文件很小” - 注意:该值可被客户端伪造(虽然不影响服务端保存,但逻辑校验时若只信它,可能绕过业务层大小限制)
处理大文件时避免内存和超时问题
单纯读取文件头或统计块数并不比 filesize() 更快,反而增加复杂度。真正影响性能的是后续操作(如读取、移动、压缩)。对超大文件做大小判断本身开销极小,瓶颈往往出在其他环节。
-
filesize()是系统调用,不加载文件内容,无论文件多大都几乎瞬时返回(除非 NFS 等网络文件系统延迟高) - 如果判断后还要读取文件,建议用
fopen(..., 'rb')+fstat()一次性获取大小和句柄,避免重复系统调用 - Web 环境下注意
max_execution_time和memory_limit不会影响filesize(),但可能中断后续处理;CLI 脚本则更需关注这些设置
单位换算容易错:别信 MB = 1000×1000
PHP 默认按二进制单位(MiB)理解“MB”,但很多前端或配置项按十进制(MB)标称。例如用户说“不能超过 10MB”,实际可能是 10 * 1000 * 1000 还是 10 * 1024 * 1024?这个差异在百兆以上就达 4.8% 之多。
立即学习“PHP免费学习笔记(深入)”;
- PHP 内部无内置单位解析函数,
ini_get('upload_max_filesize')返回字符串(如"2M"),需自己实现转换逻辑 - 推荐统一使用二进制换算(
1024倍),与操作系统、df、ls -lh保持一致,减少混淆 - 若对接外部系统,务必确认其单位定义,宁可在文档里写死 “1MB = 1048576 bytes”,也不依赖模糊描述
实际中最容易被忽略的,是把 $_FILES['x']['size'] 当作绝对可信输入,以及在没检查 is_readable() 就调 filesize() 导致警告抑制失效。这两个点一旦漏掉,线上日志会突然冒出大量 Warning: filesize(): stat failed 或逻辑误判。











