🤖 AI智能摘要
暂未配置
前言
文件上传是网站开发最常用、必考的功能之一。头像上传、图片发布、附件提交、后台素材上传等功能,全部基于PHP文件上传技术实现。
本章核心掌握:表单上传原理、$\_FILES 超级变量、文件类型/大小校验、防止覆盖上传、随机文件名、上传漏洞防护、完整通用上传类实战。
一、文件上传基础原理
1. 上传必备表单条件
普通表单无法上传文件,文件上传表单必须满足两个核心条件:
- form 表单必须添加属性:enctype="multipart/form-data"
- 表单提交方式必须为 method="post"(get无法传输文件二进制数据)
2. 上传表单完整代码
<!-- 文件上传专属表单 -->
<form action="upload.php" method="post" enctype="multipart/form-data">
选择文件:<input type="file" name="upfile"><br/>
<input type="submit" value="开始上传">
</form>二、$\_FILES 超级全局变量(核心)
文件上传后,所有文件信息(名称、类型、大小、临时路径、错误码)全部存储在 **$\_FILES** 中,$\_POST 无法获取文件数据。
1. $\_FILES 五大核心参数
- name:文件原始名称(用户本地文件名)
- type:文件MIME类型(文件格式标识)
- tmp\_name:服务器临时存储路径(核心!文件先存在服务器临时目录)
- size:文件大小(单位:字节Byte)
- error:上传错误码(0代表上传成功,无错误)
2. 打印文件上传信息(调试代码)
<?php
// 打印上传文件所有信息
var_dump($_FILES['upfile']);
?>3. 上传错误码详解
| 错误码 | 含义 |
|---|---|
| 0 | 上传成功,无任何错误 |
| 1 | 文件超过 php.ini 最大上传限制 |
| 2 | 文件超过表单 MAX\_FILE\_SIZE 限制 |
| 4 | 未选择任何文件,空上传 |
| 6/7 | 服务器临时目录异常、磁盘已满 |
三、核心上传函数:move\_uploaded\_file()
文件上传的本质:将服务器临时目录中的文件,移动到网站永久存储目录。临时文件执行完毕会自动销毁,必须移动保存。
语法:move_uploaded_file(临时路径, 目标保存路径)
1. 最简基础上传代码(入门版)
<?php
// upload.php 基础上传逻辑
if($_FILES['upfile']['error'] == 0){
// 定义保存路径+文件名
$path = "./upload/".$_FILES['upfile']['name'];
// 移动临时文件到永久目录
if(move_uploaded_file($_FILES['upfile']['tmp_name'],$path)){
echo "上传成功!<br/><a href='".$path."' target='_blank'>查看图片</a>";
}else{
echo "文件移动失败";
}
}else{
echo "上传出错,错误码:".$_FILES['upfile']['error'];
}
?>2. 基础版本两大致命问题
- 文件覆盖问题:同名文件会直接覆盖旧文件,造成数据丢失
- 安全漏洞问题:允许上传php、exe等恶意文件,黑客可上传木马控制网站
四、上传功能安全优化(必做)
1. 解决文件覆盖:生成随机唯一文件名
通过 time()时间戳 + 随机字符串 + 原文件后缀 生成唯一文件名,彻底避免覆盖。
2. 限制上传文件类型(禁止恶意文件)
白名单机制:只允许指定格式上传(推荐),禁止php、html、exe、js等脚本文件。
常用图片白名单:jpg、jpeg、png、gif、webp
3. 限制上传文件大小
防止超大文件占用服务器磁盘、恶意刷流量,日常图片上传限制 2MB 以内即可。
五、工业级完整上传代码(可直接商用)
整合:空判断、错误判断、类型校验、大小校验、随机文件名、自动创建文件夹、安全防护
<?php
// 1. 判断是否上传空文件
if($_FILES['upfile']['error'] != 0){
exit("文件上传异常,请重新上传!");
}
// 2. 配置上传规则
$allow_type = ['jpg','jpeg','png','gif','webp']; // 允许的文件后缀
$max_size = 2 * 1024 * 1024; // 最大限制2MB
$save_path = "./upload/"; // 文件保存目录
// 3. 获取文件后缀(统一小写,避免大小写绕过)
$file_name = $_FILES['upfile']['name'];
$file_ext = strtolower(pathinfo($file_name,PATHINFO_EXTENSION));
// 4. 类型校验
if(!in_array($file_ext,$allow_type)){
exit("仅允许上传 JPG、PNG、GIF、WEBP 格式图片!");
}
// 5. 大小校验
if($_FILES['upfile']['size'] > $max_size){
exit("文件过大!最大允许上传2MB文件");
}
// 6. 不存在目录则自动创建
if(!file_exists($save_path)){
mkdir($save_path,0777,true);
}
// 7. 生成唯一随机文件名
$new_name = time().rand(1000,9999).".".$file_ext;
$final_path = $save_path.$new_name;
// 8. 执行上传
if(move_uploaded_file($_FILES['upfile']['tmp_name'],$final_path)){
echo "✅ 上传成功<br/>";
echo "文件地址:<a href='{$final_path}' target='_blank'>{$final_path}</a>";
}else{
echo "❌ 文件保存失败";
}
?>六、php.ini 上传配置(服务器调优)
如需修改网站上传大小限制、超时时间,需修改 php.ini 核心配置:
| 配置项 | 作用 | 默认值 |
|---|---|---|
| file\_uploads | 是否开启文件上传功能 | On(开启) |
| upload\_max\_filesize | 单个文件最大上传大小 | 2M |
| post\_max\_size | POST表单最大提交大小 | 8M |
| max\_execution\_time | 脚本最大执行超时时间 | 30秒 |
修改配置后需重启Apache/Nginx服务器方可生效。
七、文件上传高危漏洞与防护总结
1. 常见漏洞
- 未校验文件后缀,上传 PHP 木马文件,被直接执行篡改网站
- 仅校验前端后缀,后端无校验,被抓包修改文件类型绕过
- 文件名可控,造成路径遍历、文件覆盖风险
2. 终极防护方案
- 后端白名单校验:只允许指定图片后缀,拒绝所有脚本格式
- 禁用上传目录执行权限:upload目录禁止运行PHP文件
- 统一重命名文件:不使用用户原始文件名,杜绝路径漏洞
- 限制文件大小:防止超大文件攻击
八、本章核心总结
- 文件上传表单必须满足:
method="post"+enctype="multipart/form-data"; - 所有文件数据通过 **$\_FILES** 获取,$\_POST 无法接收文件;
- 上传核心函数:
move_uploaded_file(临时路径, 永久路径); - 开发必须做四层校验:错误码校验、空校验、后缀白名单、大小限制;
- 必须生成随机文件名,解决文件覆盖问题;
- 安全第一:永远不信任前端提交的数据,所有校验必须放在后端。
(注:部分内容可能由 AI 生成)