PHP文件上传异常求助:修改php.ini后仍无法处理2MB以上文件
PHP文件上传2MB限制失效问题排查与修复
问题根源分析
- 语法/逻辑结构错误:原代码中
move_uploaded_file后直接接else,导致分支逻辑完全混乱——文件上传成功并通过校验后,没有执行数据库插入;反而当文件未上传(或上传失败)时,才执行插入,这就是你看到“忽略文件直接保存其他数据”的原因。 - 未处理上传错误码:当文件大小接近php.ini的
upload_max_filesize时,PHP会直接拒绝上传,此时$_FILES['file']['tmp_name']为空,is_uploaded_file返回false,脚本进入else分支,完全跳过错误校验逻辑。 - 校验顺序不合理:先检查文件是否上传,再处理错误的顺序会导致上传失败的情况被直接忽略。
修复后的完整代码
// 先处理上传错误 if ($_FILES['file']['error'] !== UPLOAD_ERR_OK) { $errorMsg = ''; switch ($_FILES['file']['error']) { case UPLOAD_ERR_INI_SIZE: $errorMsg = '文件大小超过php.ini限制(最大3MB)'; break; case UPLOAD_ERR_FORM_SIZE: $errorMsg = '文件大小超过表单限制(最大2MB)'; break; case UPLOAD_ERR_NO_FILE: // 允许无文件上传的情况,后续处理 break; default: $errorMsg = '文件上传失败,错误码:' . $_FILES['file']['error']; } if (!empty($errorMsg)) { echo '<script> $(document).ready(function(){ toastr.error("' . $errorMsg . '"); }) </script>'; exit(); } } $uploadPath = ""; // 有文件上传时才处理校验和保存 if (is_uploaded_file($_FILES['file']['tmp_name'])) { $allowedExtensions = ['jpg', 'jpeg', 'png', 'pdf']; $uploadedFile = $_FILES['file']; $fileName = $uploadedFile['name']; $filetempname = $uploadedFile['tmp_name']; $filesize = $uploadedFile['size']; // 校验文件大小 if ($filesize > 2 * 1024 * 1024) { echo '<script> $(document).ready(function(){ toastr.error("File size should be less than 2MB"); }) </script>'; exit(); } // 校验文件扩展名和MIME类型 $fileExtension = strtolower(pathinfo($fileName, PATHINFO_EXTENSION)); $fileInfo = finfo_open(FILEINFO_MIME_TYPE); $mime = finfo_file($fileInfo, $filetempname); finfo_close($fileInfo); $allowedMimes = ['image/jpeg', 'image/jpg', 'image/png', 'application/pdf']; if (!in_array($fileExtension, $allowedExtensions) || !in_array($mime, $allowedMimes)) { echo '<script> $(document).ready(function(){ toastr.error("Invalid file type or extension"); }) </script>'; exit(); } // 生成唯一文件名并保存 $uniqueFilename = uniqid() . '_' . random_string(20) . '.' . $fileExtension; $uploadPath = 'uploads/' . $uniqueFilename; move_uploaded_file($filetempname, $uploadPath); } // 统一执行数据库插入(无论是否有文件上传) $stmt = $con->prepare("INSERT INTO jentress_erp (date, jnum, description, company,j_type, token_serial,position) VALUES (?,?,?,?,?,?,?)"); $stmt->bind_param("sssssss", $test_date, $entry_num, $descrip, $company,$j_type,$serial,$uploadPath); $stmt->execute(); $stmt->close(); echo '<script> $(document).ready(function(){ toastr.success("1 new file added"); }) </script>';
关键修复点说明
- 新增错误码处理:通过
$_FILES['file']['error']捕获所有上传失败场景,包括超过php.ini限制的情况,给出明确错误提示。 - 重构逻辑结构:将数据库插入逻辑移到最后,无论是否有文件上传都统一执行;文件上传的校验和保存逻辑放在独立分支,避免语法错误。
- 优化校验顺序:先检查文件大小,再处理类型校验,减少不必要的资源消耗;用
pathinfo替代explode获取扩展名,更可靠。 - 修复语法错误:移除了原代码中位置错误的
else,让分支逻辑清晰合理。
内容的提问来源于stack exchange,提问作者Andandydongola
相关产品推荐
相关产品推荐

