服务器端file_exists判断异常:PDF上传时误报文件已存在
问题根源与解决方案
我来帮你拆解一下问题出在哪,以及对应的修复步骤:
1. 前端AJAX的核心问题:未正确传递文件
你当前用$(this).serialize()序列化表单数据,但这个方法完全不支持文件上传控件——它只能处理普通文本输入、选择框等元素,文件内容根本不会被发送到后端。这直接导致后端的$_FILES["fileToUpload"]为空,进而引发后续的错误判断。
修复前端代码:改用FormData处理文件上传
把AJAX部分改成以下代码,用FormData包装整个表单(包括文件):
$("#contactForm").submit(function(e){ e.preventDefault(); // 用FormData包装表单,自动包含文件控件内容 var form_data = new FormData(this); $('input[type="submit"]').val("Sending Message..."); $.ajax({ type: "POST", url: "backend/career.php", dataType: "json", data: form_data, // 必须添加这两个属性,否则文件无法正确上传 contentType: false, processData: false }).done(function (data){ console.log(data); $('input[type="submit"]').removeClass('btn-primary').addClass('btn-success'); $('input[type="submit"]').val("Message Sent..."); $("#contactForm")[0].reset(); // 用原生reset方法更简洁地清空表单 }).fail(function(data){ console.log(data); $('input[type="submit"]').removeClass('btn-primary').addClass('btn-danger'); $('input[type="submit"]').val("Sending Failed..."); $("#contactForm")[0].reset(); }); });
2. 后端PHP的问题与修复
问题a:file_exists误判目录为文件
当前端没传文件时,$_FILES["fileToUpload"]["name"]是空字符串,导致$target_file = "../pdf/" . "",也就是目标目录本身。而file_exists()会把存在的目录判定为“文件存在”,所以你总是看到“文件已存在”的错误。
问题b:文件大小判断逻辑错误
你写的$_FILES["fileToUpload"]["name"] > 500000完全错误,应该用$_FILES["fileToUpload"]["size"]获取文件的字节大小。
问题c:缺少文件上传的基础校验
需要先检查是否有文件被上传,以及上传过程是否无错误,避免空文件的情况。
修复后端PHP代码
<?php $response = []; $target_dir = "../pdf/"; // 先校验是否有文件上传且上传成功 if(isset($_FILES["fileToUpload"]) && $_FILES["fileToUpload"]["error"] == UPLOAD_ERR_OK) { $fileName = basename($_FILES["fileToUpload"]["name"]); $target_file = $target_dir . $fileName; $uploadOk = 1; $pdfFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION)); // 检查文件是否已存在 if (file_exists($target_file)) { $response["error"] = "Sorry, file already exists."; $uploadOk = 0; } // 检查文件大小(限制500KB) if ($_FILES["fileToUpload"]["size"] > 500000) { $response["error"] = "Sorry, your file is too large."; $uploadOk = 0; } // 校验是否为PDF文件 if($pdfFileType != "pdf") { $response["error"] = "Sorry, only PDF files are allowed."; $uploadOk = 0; } // 执行文件上传 if ($uploadOk == 0) { $response["message"] = "Sorry, your file was not uploaded."; } else { if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) { $response["success"] = "The file ". htmlspecialchars($fileName). " has been uploaded."; } else { $response["error"] = "Sorry, there was an error uploading your file."; } } } else { $response["error"] = "No file was uploaded or there was an upload error."; } // 返回JSON格式的响应 echo json_encode($response); ?>
额外注意事项
- 确保
../pdf/目录存在,并且PHP进程拥有该目录的写入权限(可以通过chmod 755 ../pdf/命令设置权限)。 - 前端用
$("#contactForm")[0].reset()清空表单,比逐个设置val("")更简洁,且能正确重置文件输入控件。
内容的提问来源于stack exchange,提问作者Avinash Goen
相关产品推荐
相关产品推荐

