You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP文件上传功能忽略已设3项校验限制规则问题咨询

问题原因

  • 文件名大写校验逻辑存在缺陷
    ctype_lower() 函数的判断规则是:仅当字符串中所有字母都是小写且至少包含1个字母时才返回true。如果文件名不含任何字母、或者全小写字母,要么会误判通过校验,要么会触发错误的提示信息。
  • 校验分支的错误提示逻辑不匹配
    文件名校验的else分支统一输出“文件名不能超过50字符”的提示,当文件名长度符合要求但全小写时,用户看不到正确的错误提示,也会误以为规则未生效。
  • 超大文件的大小校验逻辑失效
    如果上传的文件大小超过php.ini中upload_max_filesize或表单MAX_FILE_SIZE的限制,PHP会直接将$_FILES["uploadedFile"]["size"]置为0,此时会通过你写的$_FILES["uploadedFile"]["size"] < 3000000判断,不会触发你写的大小超限逻辑。
  • 错误码校验顺序错位
    你把$_FILES["uploadedFile"]["error"]的判断放在了MIME校验之后,上传出错的文件(比如大小超限的文件)会先走完前面的大小、文件名、MIME校验,才会报错,逻辑顺序不合理。

修复后的完整代码

<?php
// 先判断文件字段是否正常上传
if (!isset($_FILES["uploadedFile"]) || $_FILES["uploadedFile"]["error"] != UPLOAD_ERR_OK) {
    $errorMap = [
        UPLOAD_ERR_INI_SIZE => '文件大小超过服务器限制',
        UPLOAD_ERR_FORM_SIZE => '文件大小超过表单限制',
        UPLOAD_ERR_PARTIAL => '文件仅部分被上传',
        UPLOAD_ERR_NO_FILE => '没有文件被上传',
        UPLOAD_ERR_NO_TMP_DIR => '找不到临时文件夹',
        UPLOAD_ERR_CANT_WRITE => '文件写入失败',
        UPLOAD_ERR_EXTENSION => '文件上传被扩展中断'
    ];
    $errorCode = $_FILES["uploadedFile"]["error"] ?? -1;
    echo "上传错误:" . ($errorMap[$errorCode] ?? '未知错误');
    exit;
}

// 1. 校验文件大小 3MB = 3*1024*1024 = 3145728字节,也可保留你原有的3000000数值
$maxSize = 3145728;
if ($_FILES["uploadedFile"]["size"] >= $maxSize) {
    echo "Invalid file size. Must be less than 3MB.";
    exit;
}

$fileName = $_FILES["uploadedFile"]["name"];
// 2. 校验文件名长度
if (strlen($fileName) > 50) {
    echo "The file name must not exceed 50 characters";
    exit;
}

// 3. 校验文件名至少包含1个大写字母
if (!preg_match('/[A-Z]/', $fileName)) {
    echo "The file name must contain at least one uppercase letter";
    exit;
}

// 4. 校验文件MIME类型
$acceptedFileTypes = ["image/gif", "image/jpg", "image/jpeg","image/png"];
$fileinfo = finfo_open(FILEINFO_MIME_TYPE);
$uploadedFileType = finfo_file($fileinfo, $_FILES["uploadedFile"]["tmp_name"]);
if (!in_array($uploadedFileType, $acceptedFileTypes)) {
    echo "Invalid file type. Must be gif, jpg or jpeg.";
    exit;
}

// 校验upload目录是否存在,不存在则创建
$uploadDir = "upload/";
if (!is_dir($uploadDir)) {
    mkdir($uploadDir, 0755, true);
}
$targetPath = $uploadDir . $fileName;

// 校验文件是否已存在
if (file_exists($targetPath)) {
    echo $fileName . " already exists. ";
    exit;
}

// 移动文件
if (move_uploaded_file($_FILES["uploadedFile"]["tmp_name"], $targetPath)) {
    echo "Upload: " . $fileName . "<br />";
    echo "Type: " . $uploadedFileType . "<br />";
    echo "Size: " . ($_FILES["uploadedFile"]["size"] / 1024) . " Kb<br />";
    echo "Stored";
} else {
    echo "Something went wrong while uploading.";
}
?>

修复说明

  • 调整了校验顺序,优先判断上传错误码,再依次校验大小、文件名、MIME类型,只要任意校验不通过就直接终止程序,避免多层嵌套逻辑出错
  • 用正则/[A-Z]/替换ctype_lower()做大写字母校验,只要文件名中存在任意一个大写字母就通过,完美匹配需求,也兼容含数字、特殊字符的文件名
  • 拆分了各个校验分支的错误提示,每个规则不通过都会返回对应的提示,方便排查问题
  • 补充了upload目录的自动创建逻辑,避免目录不存在导致上传失败

内容的提问来源于stack exchange,提问作者Zack Fair

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 21:06:10