PHP 上传文件处理
PHP 上传文件处理
文件上传是 Web 开发常见功能,安全处理很重要。
1. HTML 表单
<form method="post" action="upload.php" enctype="multipart/form-data">
<input type="file" name="file">
<button type="submit">上传</button>
</form>
注意:必须加 enctype="multipart/form-data"。
2. PHP 接收文件
// $_FILES 接收上传文件
$file = $_FILES['file'];
// 文件信息
$name = $file['name']; // 文件名
$tmp = $file['tmp_name']; // 临时路径
$size = $file['size']; // 文件大小
$error = $file['error']; // 错误码
$type = $file['type']; // MIME类型
3. 错误码说明
- UPLOAD_ERR_OK (0): 上传成功
- UPLOAD_ERR_INI_SIZE (1): 超过 php.ini 限制
- UPLOAD_ERR_FORM_SIZE (2): 超过表单限制
- UPLOAD_ERR_PARTIAL (3): 部分上传
- UPLOAD_ERR_NO_FILE (4): 没有文件
4. 完整上传代码
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$file = $_FILES['file'];
// 检查错误
if ($file['error'] !== UPLOAD_ERR_OK) {
exit('上传失败');
}
// 检查大小(限制2M)
if ($file['size'] > 2 * 1024 * 1024) {
exit('文件太大');
}
// 允许的扩展名
$allowExt = ['jpg', 'png', 'gif'];
$ext = pathinfo($file['name'], PATHINFO_EXTENSION);
if (!in_array($ext, $allowExt)) {
exit('不允许的文件类型');
}
// 生成新文件名
$newName = uniqid() . '.' . $ext;
$uploadDir = 'uploads/';
// 移动文件
if (move_uploaded_file($file['tmp_name'], $uploadDir . $newName)) {
echo '上传成功';
} else {
echo '保存失败';
}
}
5. php.ini 配置
; 上传最大文件大小
upload_max_filesize = 2M
; 表单最大提交大小
post_max_size = 8M
; 允许上传
file_uploads = On
; 临时目录
upload_tmp_dir = /tmp
6. 安全注意事项
1)不要用原文件名
- 防止覆盖文件和路径穿越
- 用 uniqid 生成新文件名
2)验证文件类型
- 不要只看扩展名
- 用 finfo 检查 MIME 类型
$finfo = new Finfo(FILEINFO_MIME_TYPE);
$mime = $finfo->file($file['tmp_name']);
3)上传目录不可执行
- 上传目录关闭 PHP 执行
- 防止上传木马
4)重命名文件
- 不要保留用户上传的文件名
- 防止覆盖和目录穿越攻击
7. 常见问题
1)上传失败,$_FILES 为空
- 检查表单是否有 enctype
- 检查 post_max_size 够不够大
2)move_uploaded_file 失败
- 检查目录权限
- 检查目录是否存在
3)大文件上传超时
- 修改 max_execution_time
- 修改 memory_limit
总结
PHP 文件上传要点:
- 表单必须加 enctype
- 用 $_FILES 接收文件
- 检查错误码和文件大小
- 验证文件类型
- 重命名文件防止安全问题
- 上传目录关闭执行权限
- 注意 php.ini 配置
做上传功能,安全永远第一位。