本文目录导读:

在PHP项目中配置文件上传后缀,主要有以下几种方法,按推荐程度排序:
在PHP代码中验证(最推荐)
这是最安全、最灵活的方式:
<?php
$allowed_extensions = ['jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx'];
$uploaded_file = $_FILES['file'];
$file_extension = strtolower(pathinfo($uploaded_file['name'], PATHINFO_EXTENSION));
if (!in_array($file_extension, $allowed_extensions)) {
die('不允许的文件类型');
}
// 继续处理上传
优点:灵活可控,可以针对不同上传场景设置不同规则
修改php.ini配置文件(全局生效)
找到并编辑 php.ini 文件:
; 允许上传的最大文件大小 upload_max_filesize = 20M post_max_size = 20M ; 允许的文件MIME类型(注意:这不是后缀限制,而是MIME类型) ; 实际上PHP没有直接限制后缀的配置,需要通过代码控制
使用MIME类型验证(辅助验证)
<?php
$allowed_mime = [
'image/jpeg',
'image/png',
'image/gif',
'application/pdf'
];
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime_type = finfo_file($finfo, $_FILES['file']['tmp_name']);
finfo_close($finfo);
if (!in_array($mime_type, $allowed_mime)) {
die('不允许的文件类型');
}
完整的文件上传安全示例
<?php
class FileUploader {
private $allowed_extensions = ['jpg', 'jpeg', 'png', 'gif'];
private $allowed_mime_types = ['image/jpeg', 'image/png', 'image/gif'];
private $max_file_size = 5 * 1024 * 1024; // 5MB
private $upload_dir = 'uploads/';
public function upload($file) {
// 1. 检查错误
if ($file['error'] !== UPLOAD_ERR_OK) {
return ['success' => false, 'message' => '上传错误'];
}
// 2. 检查文件大小
if ($file['size'] > $this->max_file_size) {
return ['success' => false, 'message' => '文件太大'];
}
// 3. 获取并验证扩展名
$extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
if (!in_array($extension, $this->allowed_extensions)) {
return ['success' => false, 'message' => '不允许的文件类型'];
}
// 4. 验证MIME类型
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime_type = finfo_file($finfo, $file['tmp_name']);
finfo_close($finfo);
if (!in_array($mime_type, $this->allowed_mime_types)) {
return ['success' => false, 'message' => '文件MIME类型不匹配'];
}
// 5. 生成唯一文件名
$new_filename = uniqid() . '.' . $extension;
$destination = $this->upload_dir . $new_filename;
// 6. 移动文件
if (move_uploaded_file($file['tmp_name'], $destination)) {
return ['success' => true, 'filename' => $new_filename];
}
return ['success' => false, 'message' => '保存失败'];
}
}
// 使用示例
$uploader = new FileUploader();
$result = $uploader->upload($_FILES['userfile']);
if ($result['success']) {
echo "上传成功: " . $result['filename'];
} else {
echo "上传失败: " . $result['message'];
}
.htaccess 配置(Apache服务器)
在 uploads/ 目录下创建 .htaccess 文件:
# 只允许特定文件类型访问
<FilesMatch "\.(jpg|jpeg|png|gif)$">
Order Allow,Deny
Allow from all
</FilesMatch>
# 禁止执行PHP文件
<FilesMatch "\.php$">
Order Deny,Allow
Deny from all
</FilesMatch>
Nginx 配置
# 限制上传文件大小
client_max_body_size 20M;
# 限制特定目录只能访问图片
location /uploads/ {
# 只允许访问图片文件
location ~* \.(jpg|jpeg|png|gif)$ {
expires 30d;
}
# 拒绝其他文件访问
location ~* \.php$ {
deny all;
return 403;
}
}
安全建议
- 不依赖客户端验证:前端验证只是用户体验,后端必须验证
- 使用白名单而非黑名单:明确允许的文件类型
- 验证文件内容:不只是检查扩展名
- 重命名文件:避免文件名注入攻击
- 限制文件大小
- 使用专用上传目录:禁止执行权限
- 定期清理临时文件
常见问题
问题:为什么修改了配置还没生效? 解决:重启Web服务器或PHP-FPM
# Apache sudo service apache2 restart # Nginx + PHP-FPM sudo systemctl restart php7.4-fpm sudo systemctl restart nginx
建议:始终在代码层进行严格验证,不要完全依赖配置文件。