is_uploaded_file()仅验证$_files['field']['tmp_name']是否为本次上传的临时文件路径,不检查上传成功与否、内容合法性或mime类型,必须先确认$_files'field'===upload_err_ok再调用,并注意clearstatcache()缓存问题。

is_uploaded_file只认$_FILES['field']['tmp_name'],其他路径一律返回false
它不是“判断任意文件是否上传”的通用函数,而是专为验证 $_FILES 数组中临时路径的真实性而设。传入硬编码路径、$_GET['path'] 拼接值、甚至 __FILE__,结果都是 false——这不是 bug,是安全设计。
常见错误现象:
-
is_uploaded_file('/tmp/phpABC123')可能返回true,但前提是该文件确由本次请求生成;手动复制进去的同名文件也会失败 -
is_uploaded_file($_FILES['avatar']['name'])一定失败,因为name是原始文件名,不含路径 -
is_uploaded_file($_FILES['avatar']['tmp_name'] . '.bak')必然失败,哪怕文件存在且可读
必须配合UPLOAD_ERR_OK使用,否则检查无意义
is_uploaded_file() 不检查上传是否成功,只确认路径来源。如果用户没选文件、超了 upload_max_filesize、表单没加 enctype="multipart/form-data",$_FILES['field']['error'] 就会是 UPLOAD_ERR_NO_FILE 或其他非 UPLOAD_ERR_OK 值,此时调用 is_uploaded_file() 属于无效操作。
正确顺序必须是:
- 先检查
$_FILES['avatar']['error'] === UPLOAD_ERR_OK - 再确认
is_uploaded_file($_FILES['avatar']['tmp_name'])为true - 最后才调用
move_uploaded_file()
跳过第一步,is_uploaded_file() 可能对一个已损坏或空的临时路径做校验,结果不可靠。
PHP 7.4 下需注意 clearstatcache() 缓存问题
该函数结果会被 PHP 的 stat 缓存机制缓存,尤其在频繁上传、测试或调试时,可能返回过期判断。比如同一 tmp_name 被重复检查两次,第二次可能沿用第一次的缓存结果。
稳妥做法是在调用前清除缓存:
clearstatcache(true, $_FILES['avatar']['tmp_name']);
if (is_uploaded_file($_FILES['avatar']['tmp_name'])) { ... }
注意:clearstatcache() 第一个参数设为 true 表示只清指定路径缓存,避免全局刷新影响性能;不传参或传 false 会清整个缓存,不推荐。
它不校验内容,MIME 和扩展名仍需独立验证
is_uploaded_file() 只管“是不是这次上传的临时文件”,不管内容是否合规。攻击者仍可上传伪装成图片的 PHP 文件(如把 <?php phpinfo(); ?> 保存为 shell.jpg),is_uploaded_file() 依然返回 true。
真实安全链必须包含:
- 用
finfo_open(FILEINFO_MIME_TYPE)获取真实 MIME 类型 - 白名单比对(例如只允许
image/jpeg、application/pdf) - 拒绝
text/x-php、application/x-httpd-php等执行型类型 - 不信任
$_FILES['file']['type'],该字段完全由客户端控制,可轻易伪造
漏掉任何一环,is_uploaded_file() 的防护就形同虚设。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











