php 8.1 文件类型校验应结合 mime 类型(finfo)、扩展名白名单和 getimagesize() 三重验证,杜绝仅依赖 $_files['type'] 或扩展名,确保安全可靠。

PHP 8.1 中做文件类型校验,不能只依赖客户端传来的 $_FILES['file']['type'](易伪造),也不能仅靠扩展名(可随意改)。推荐结合 MIME 类型检测 + 文件头(magic bytes)校验 + 白名单控制,兼顾安全与实用性。
使用 finfo 扩展识别真实 MIME 类型
PHP 内置的 finfo 是最可靠的方式之一,它读取文件前若干字节判断类型:
// 示例:校验上传文件是否为 PNG 或 JPG
$allowedMimes = ['image/png', 'image/jpeg', 'image/jpg'];
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$realMimeType = finfo_file($finfo, $_FILES['file']['tmp_name']);
finfo_close($finfo);
if (!in_array($realMimeType, $allowedMimes)) {
throw new RuntimeException('不支持的文件类型:' . $realMimeType);
}
补充检查文件扩展名(白名单+小写统一)
扩展名虽可伪造,但作为第二道防线仍有必要,尤其防止用户误传或绕过前端限制:
$uploadedName = $_FILES['file']['name'];
$extension = strtolower(pathinfo($uploadedName, PATHINFO_EXTENSION));
$allowedExtensions = ['png', 'jpg', 'jpeg', 'gif'];
if (!in_array($extension, $allowedExtensions)) {
throw new RuntimeException('不支持的文件扩展名:' . $extension);
}
可选:验证图片尺寸或是否为有效图像
对图片类文件,可用 getimagesize() 进一步确认(该函数会解析文件头,失败则不是合法图像):
$imageInfo = @getimagesize($_FILES['file']['tmp_name']);
if ($imageInfo === false) {
throw new RuntimeException('上传的不是有效图像文件');
}
// 还可限制宽高,例如:
if ($imageInfo[0] > 4000 || $imageInfo[1] > 4000) {
throw new RuntimeException('图片尺寸超出限制(最大 4000×4000)');
}
完整校验逻辑整合示例
把上述步骤组合成一个健壮的校验函数:
function validateUploadedImage(array $file): void
{
if ($file['error'] !== UPLOAD_ERR_OK) {
throw new RuntimeException('文件上传失败,错误码:' . $file['error']);
}
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $file['tmp_name']);
finfo_close($finfo);
$allowedMimes = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif'];
if (!in_array($mime, $allowedMimes)) {
throw new RuntimeException('不支持的文件类型:' . $mime);
}
$ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
$allowedExts = ['jpg', 'jpeg', 'png', 'gif'];
if (!in_array($ext, $allowedExts)) {
throw new RuntimeException('不支持的扩展名:' . $ext);
}
// 图像有效性检查(非必需但推荐)
$size = @getimagesize($file['tmp_name']);
if ($size === false) {
throw new RuntimeException('文件内容不是有效图像');
}
}
// 使用
validateUploadedImage($_FILES['avatar']);
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











