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 配置
做上传功能,安全永远第一位。
Nginx配置上传文件大小限制,client_max_body_size
前言
用户上传大文件,提示 413 Request Entity Too Large,这就是 Nginx 默认上传文件大小限制太小了。本文讲一下怎么改上传大小限制。
报错是什么样的
413 Request Entity Too Large
Nginx 默认限制是 1MB,传个大点的文件就报错。
配置方法
第一步:改 Nginx 配置
在 http 或 server 块里加:
client_max_body_size 50m;
意思是:最大允许上传 50MB 的文件。
第二步:同时改 PHP 配置
光改 Nginx 不够,PHP 自己也有上传限制:
upload_max_filesize = 50M
post_max_size = 50M
完整配置示例
Nginx 配置:
server {
listen 80;
server_name www.example.com;
root /var/www/html;
index index.php index.html;
# 上传文件大小限制
client_max_body_size 50m;
location ~ \.php$ {
fastcgi_pass unix:/run/php-fpm/www.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
PHP 配置(php.ini):
upload_max_filesize = 50M
post_max_size = 50M
重载生效
nginx -t
nginx -s reload
systemctl restart php-fpm
常见坑
坑1:只改了 Nginx,PHP 没改
改了 Nginx 的 client_max_body_size,但 PHP 的 upload_max_filesize 还是 2M,传大点的文件还是报错。
解决: Nginx 和 PHP 两边都要改。
坑2:413 还是 413
改了配置重载了,但还是 413。
原因: 改的不是实际加载的配置文件。
解决: 用 nginx -t 确认一下配置文件路径。
坑3:上传大文件超时
传个 50MB 的文件,传到一半 504 超时了。
原因: 上传慢,超时了。
解决: 调大超时时间:
client_body_timeout 300s;
fastcgi_read_timeout 300s;
坑4:post_max_size 比 upload_max_filesize 小
PHP 里 post_max_size 必须比 upload_max_filesize 大,否则还是上传不了。
建议: 两个设成一样大。
推荐配置
一般网站传图片、文档,设 20MB 够了:
client_max_body_size 20m;
upload_max_filesize = 20M
post_max_size = 20M
如果是视频网站,设 100MB 或更大。
总结
上传文件限制要改三个地方:
- Nginx 的
client_max_body_size - PHP 的
upload_max_filesize - PHP 的
post_max_size
记住: 改完两边都要重载,别只改一边。
遇到问题加QQ23979811 协助处理