如何在PHP上传脚本内限制文件大小、单请求上传数及可上传文件类型
自定义PHP上传限制实现方案
你可以直接在现有脚本内添加配置项和校验逻辑实现所有需求,无需修改全局服务器配置,修改后的完整代码如下:
<?php $secret_key = "REDACTED"; //32-char $sharexdir = "REDACTED"; $domain_url = "REDACTED"; $lengthofstring = 7; $space= "\x20"; $linkembedu2800 =; // --------------- 新增自定义上传限制配置 --------------- $max_file_size = 5 * 1024 * 1024; // 单文件最大大小,示例为5MB,单位字节,可自行调整 $allowed_extensions = ['jpg', 'jpeg', 'png', 'gif', 'webp']; // 允许上传的文件后缀 $allowed_mime_types = ['image/jpeg', 'image/png', 'image/gif', 'image/webp']; // 允许的文件MIME类型,防止伪造后缀 $max_upload_per_request = 3; // 单次请求最多上传文件数,可自行调整 // ---------------------------------------------------- function RandomString($length) { $keys = array_merge(range(0,9), range('a', 'z')); $key = ''; for($i=0; $i < $length; $i++) { $key .= $keys[mt_rand(0, count($keys) - 1)]; } return $key; } if(isset($_POST['secret'])) { if($_POST['secret'] == $secret_key) { // 先校验上传文件数量 $upload_count = is_array($_FILES["sharex"]["name"]) ? count($_FILES["sharex"]["name"]) : 1; if ($upload_count > $max_upload_per_request) { echo "ERROR: 单次请求最多上传".$max_upload_per_request."个文件"; exit; } // 统一处理单/多文件上传 $files = []; if (is_array($_FILES["sharex"]["name"])) { // 多文件上传结构转换 foreach ($_FILES["sharex"]["name"] as $k => $v) { $files[] = [ 'name' => $_FILES["sharex"]["name"][$k], 'tmp_name' => $_FILES["sharex"]["tmp_name"][$k], 'error' => $_FILES["sharex"]["error"][$k], 'size' => $_FILES["sharex"]["size"][$k] ]; } } else { // 单文件上传直接放入数组 $files[] = $_FILES["sharex"]; } $return_links = []; foreach ($files as $file) { // 校验PHP原生上传错误 if ($file['error'] !== UPLOAD_ERR_OK) { $err_msgs = [ UPLOAD_ERR_INI_SIZE => '文件大小超出服务器全局限制', UPLOAD_ERR_FORM_SIZE => '文件大小超出表单限制', UPLOAD_ERR_PARTIAL => '文件仅部分上传', UPLOAD_ERR_NO_FILE => '未选择上传文件' ]; echo "ERROR: ".($err_msgs[$file['error']] ?? '未知上传错误'); exit; } // 校验单文件大小 if ($file['size'] > $max_file_size) { echo "ERROR: 单文件大小不能超过".round($max_file_size/1024/1024, 2)."MB"; exit; } // 校验文件后缀 $file_ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION)); if (!in_array($file_ext, $allowed_extensions)) { echo "ERROR: 不允许上传.".$file_ext."格式的文件"; exit; } // 校验文件真实MIME类型 $finfo = new Finfo(FILEINFO_MIME_TYPE); $file_mime = $finfo->file($file['tmp_name']); if (!in_array($file_mime, $allowed_mime_types)) { echo "ERROR: 上传文件不是合法的图片类型"; exit; } // 生成文件名保存 $filename = RandomString($lengthofstring); $save_path = $sharexdir.$filename.'.'.$file_ext; if (move_uploaded_file($file['tmp_name'], $save_path)) { $return_links[] = $domain_url.$save_path.$space.$linkembedu2800; } else { echo 'ERROR: INTERNAL SERVER ERROR'; exit; } } // 输出所有上传成功的链接 echo implode("\n", $return_links); } else { echo 'ERROR: INVALID SECRET KEY'; } } else { echo 'ERROR: NO POST DATA RECIEVED'; } ?>
配置说明
- 你可以直接修改代码中
自定义上传限制配置区域的参数,调整为你需要的阈值即可 - 脚本采用后缀+真实MIME类型双重校验规则,避免恶意用户修改可执行文件后缀伪装成图片上传,降低安全风险
- 兼容单文件、多文件两种上传模式,同时支持ShareX的默认上传配置
- 注意:如果测试时大于你设置阈值的文件直接被拦截且返回
文件大小超出服务器全局限制,说明php.ini全局配置的upload_max_filesize或post_max_size小于你设置的自定义阈值,该场景下才需要调整全局配置
内容的提问来源于stack exchange,提问作者visual
相关产品推荐
相关产品推荐

