php文件上传必须通过$_files数组,且表单enctype必须为multipart/form-data、input类型为file、method必须为post;$_files是嵌套数组,需先检查error值是否为0,用is_uploaded_file()校验并move_uploaded_file()移动文件,同时注意php.ini中file_uploads、upload_max_filesize和post_max_size配置。

PHP 文件上传不是靠 file_get_contents 或 fopen 读取路径就能完成的——必须走 $_FILES 超全局数组,且表单 enctype 必须是 multipart/form-data,否则 $_FILES 永远为空。
表单和 HTML 层必须满足的三个硬性条件
很多上传失败,根本没进 PHP 就卡死了:
- form 标签必须有
enctype="multipart/form-data",缺了这个,浏览器根本不会把文件二进制数据发过去 - input 类型必须是
<input type="file" name="avatar">,name 值会成为$_FILES的键名(如$_FILES['avatar']) - form 的
method必须是POST;GET 不支持文件上传,服务器直接忽略$_FILES
$_FILES 数组结构和常见错误现象
上传后不检查 $_FILES 结构就写逻辑,90% 会出错。它不是扁平数组,而是嵌套结构:
$_FILES['avatar'] = [ 'name' => 'photo.jpg', 'type' => 'image/jpeg', 'tmp_name' => '/tmp/phpABC123', 'error' => 0, 'size' => 204800 ];
关键点:
-
error是第一道关卡:值为0才表示成功;1或2是超限(upload_max_filesize或MAX_FILE_SIZE),4表示没选文件 -
tmp_name是唯一有效的临时路径,必须用move_uploaded_file()移动,不能用copy()或rename() -
name来自客户端,不可信,必须过滤或重命名,否则可能被构造为../../etc/passwd
安全移动文件的实操要点
用 move_uploaded_file() 不只是“习惯”,它是 PHP 唯一验证临时文件来源合法性的方式:
- 目标路径必须是绝对路径,相对路径容易出错,建议用
__DIR__ . '/uploads/' - 务必先
is_uploaded_file($_FILES['avatar']['tmp_name'])校验,防止伪造tmp_name参数绕过 - 重命名文件:不要保留
$_FILES['avatar']['name'],推荐用uniqid() . '_' . md5_file($_FILES['avatar']['tmp_name']) . '.jpg'之类方式 - 上传目录要关闭 PHP 解析(如 Nginx 配置
location ~ \.php$ { deny all; }),否则用户传个shell.php就完蛋
PHP 配置项对上传的实际影响
代码写对了,但 php.ini 限制没调,照样失败。重点看这三项:
-
file_uploads = On:默认开,但某些容器或共享主机可能关掉 -
upload_max_filesize = 2M:这是单个文件上限,不是总和;改完还要重启 PHP-FPM 或 Apache -
post_max_size = 8M:必须 ≥upload_max_filesize,否则整个 POST 请求被截断,$_FILES为空
运行时可用 ini_get('upload_max_filesize') 检查当前值,别只信配置文件。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











