本文目录导读:

- 文件上传错误代码验证($_FILES[”error”])
- 文件大小验证
- 文件类型验证(MIME 类型)
- 文件扩展名验证
- 重写文件名(防止路径穿越与冲突)
- 图片内容验证(针对图片)
- 其他安全与业务规则
- 完整的安全验证流程(推荐顺序)
- 常见误区和陷阱
在 PHP 中进行文件验证(通常指文件上传时的验证),主要目的是确保上传的文件安全、有效且符合预期,以下是常见且必须的 PHP 文件验证规则,通常按顺序执行:
文件上传错误代码验证($_FILES[”error”])
这是第一道防线,PHP 会根据上传是否成功自动填充一个错误代码。
UPLOAD_ERR_OK(值 0):无错误,文件上传成功。UPLOAD_ERR_INI_SIZE(1):文件超过php.ini中upload_max_filesize限制。UPLOAD_ERR_FORM_SIZE(2):文件超过 HTML 表单中MAX_FILE_SIZE指定的大小。UPLOAD_ERR_PARTIAL(3):文件只有部分被上传(网络问题)。UPLOAD_ERR_NO_FILE(4):没有上传文件(用户未选择)。UPLOAD_ERR_NO_TMP_DIR(6):缺少临时文件夹(服务器环境问题)。UPLOAD_ERR_CANT_WRITE(7):写入磁盘失败。
示例代码:
if ($_FILES['file']['error'] !== UPLOAD_ERR_OK) {
die('上传失败,错误代码:' . $_FILES['file']['error']);
}
文件大小验证
防止用户上传过大文件撑爆服务器。
- PHP 配置限制(服务器端):
upload_max_filesize和post_max_size。 - 代码验证(推荐): 使用
$_FILES['file']['size']进行校验。
$maxSize = 2 * 1024 * 1024; // 2MB
if ($_FILES['file']['size'] > $maxSize) {
die('文件大小不能超过 2MB');
}
文件类型验证(MIME 类型)
注意: 不能仅依赖 $_FILES['file']['type'],因为这个值由客户端(浏览器)控制,极易被篡改,不安全的做法如下:
// ❌ 不安全:客户端可以随意修改这个值
if ($_FILES['file']['type'] !== 'image/jpeg') {
die('只允许 JPEG 图片');
}
正确做法:使用服务器端函数检测。
- 图片文件:
getimagesize()或exif_imagetype()。 - 通用文件:
finfo_open()与finfo_file()(基于文件魔数魔术字节,更可靠)。
// ✅ 安全:使用服务器端真实文件检测
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimeType = finfo_file($finfo, $_FILES['file']['tmp_name']);
finfo_close($finfo);
$allowedTypes = ['image/jpeg', 'image/png'];
if (!in_array($mimeType, $allowedTypes)) {
die('只允许 JPEG 或 PNG 图片');
}
文件扩展名验证
防止用户上传 shell.php 并伪装成图片(双重校验)。
$extension = strtolower(pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION));
$allowedExts = ['jpg', 'jpeg', 'png', 'gif'];
if (!in_array($extension, $allowedExts)) {
die('不允许的文件扩展名');
}
重写文件名(防止路径穿越与冲突)
用户上传的文件名可能包含恶意字符(如 ../../etc/passwd)或中文字符。永远不要使用原始文件名保存到磁盘。
- 方案: 生成唯一文件名(UUID、时间戳 + 随机数)。
- 安全存储: 将文件移出
document_root(网站根目录),或设置http://example.com/uploads/目录下.htaccess禁止执行 PHP。
$newFileName = uniqid() . '.' . $extension; // 如 61f8a3b1c2d3e.jpg
if (!move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/' . $newFileName)) {
die('文件保存失败');
}
验证(针对图片)
如果只允许图片,除了 MIME 检测,还需验证图片完整性。
$imageInfo = getimagesize($_FILES['file']['tmp_name']);
if ($imageInfo === false) {
die('文件不是有效的图片');
}
// 可以继续检查宽度、高度等
if ($imageInfo[0] > 2000 || $imageInfo[1] > 2000) {
die('图片尺寸过大');
}
其他安全与业务规则
- 目录权限检查: 确保
uploads/目录可写,且不允许执行。 - 文件数量限制: 防止用户恶意批量上传。
- 黑名单检测: 禁止包含 PHP 代码片段(如
<?php)在文件内容中(用于简易文本验证)。 - SVG 文件警告: SVG 可能包含 JavaScript(XSS 攻击),需严格消毒或禁用。
- 临时文件清理: 如果未用
move_uploaded_file(),临时文件会在脚本结束后自动删除。
完整的安全验证流程(推荐顺序)
- 检查
$_FILES['file']['error']是否为UPLOAD_ERR_OK。 - 检查文件大小
$_FILES['file']['size']是否符合限制。 - 使用
finfo检测真实的 MIME 类型。 - 检查文件扩展名(作为辅助手段)。
- 如果是图片,使用
getimagesize()验证图片完整性。 - 生成唯一文件名(避免原有名称)。
- 使用
is_uploaded_file()+move_uploaded_file()移动文件(确保是上传的文件)。
常见误区和陷阱
- 🚫 不要使用
$_FILES['file']['type']作唯一判断。 - 🚫 不要使用黑名单扩展名(如
.php3、.phtml仍可能被解析)。 - 🚫 不要允许
.htaccess或.user.ini上传。 - ✅ 推荐:上传目录关闭 PHP 执行权限(Nginx 中
location ~ \.php$ { deny all; })。 - ✅ 推荐:将文件存储到非 Web 可访问目录,通过 PHP 代理脚本读取并提供下载。
这些规则不仅用于上传,也适用于脚本中处理文件时的基本验证逻辑。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播