用 == 比较扩展名会导致弱类型转换引发逻辑错误,如空字符串、数字字符串被误判为 true;必须用 === 严格比较,配合 is_string() 校验和 in_array($ext, $allowed, true) 白名单检查。

在 PHP 8 中用 pathinfo($filename, PATHINFO_EXTENSION) 获取文件后缀后,若紧接着用 == 判断扩展名是否等于 'jpg' 或 false,极易因弱类型比较规则导致逻辑错误——比如上传 shell.php 却被误判为合法图片,或 config.(末尾带点)被当成有扩展名而放行。
用 == 比较扩展名会出什么问题
第一步:调用 $ext = pathinfo('test.php', PATHINFO_EXTENSION) → 返回字符串 'php';
第二步:写判断 if ($ext == 'php') → 表面看没问题;
但若变量未初始化或路径为空,pathinfo('', PATHINFO_EXTENSION) 返回空字符串 '',而 '' == false、'' == 0、'' == '0' 全为 true;
更危险的是,当用户上传文件名为 0.php,pathinfo('0.php', PATHINFO_EXTENSION) 返回 'php',但若你误写成 if ($ext == 0),PHP 会把 'php' 转成整数 0,结果恒为 true —— 这不是你想要的校验逻辑。
必须用 === 替代 == 的三个硬性场景
方法一:判断扩展名是否为空
错误写法:if ($ext == '') → false、0、null 都会触发,误杀合法扩展名;
【正确写法:if ($ext === '')】 → 只有真·空字符串才匹配,类型和值双重锁定。
方法二:比对白名单时防止类型混淆
例如 $allowed = ['jpg', 'png'];,若写 in_array($ext, $allowed, true) 第三个参数必须为 true 启用严格比较,否则 '1' 会被当成 1 匹配成功;
这一步不能省,漏掉就失去白名单意义。
方法三:处理函数返回值边界情况pathinfo('/var/www/', PATHINFO_EXTENSION) 返回 ''(空字符串),不是 false;
而 pathinfo('file', PATHINFO_FILENAME) 在无点时也返回原字符串,此时 PATHINFO_EXTENSION 仍是 '';
所以校验前先确认 is_string($ext) && $ext !== '',再用 === 比对,避免空值穿透校验。
PHP 8 下更安全的扩展名提取+判断组合
① 提取扩展名时加非空校验:$ext = pathinfo(basename($filename), PATHINFO_EXTENSION);
② 强制转小写并排除空值:$ext = strtolower($ext) ?: ''; (注意这里用 ?: 是因 '' 为 falsy,但不会把 '0' 当空)
③ 白名单比对必须用严格模式:in_array($ext, $allowed, true)
④ 关键防线:若 $ext === '',直接拒绝,不进入后续比对逻辑 —— 因为 archive.、.gitignore、/tmp/ 这些都不该被当作有效扩展名。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











