基于FormData与Zend Framework 2判断数组非空的问题
排查FormData数组上传后PHP未执行目录创建/文件上传的问题
嘿,我之前也碰到过这种「$_FILES看起来正常但逻辑就是不跑」的坑,大概率是细节上的疏漏,咱们一步步来捋:
先确认数组非空判断的逻辑是否准确
很多人会直接用empty($_FILES['your_array_key'])来判断,但FormData传的文件数组,哪怕没有文件,$_FILES里也会存在一个结构完整但内部值为空的数组。正确的判断方式应该是检查实际的文件数量:// 假设你的文件数组键是files if (isset($_FILES['files']) && count($_FILES['files']['name']) > 0) { // 进入目录创建和上传逻辑 }别小看这一步,我之前就是因为判断逻辑不对,导致后面的代码根本没执行。
检查目录创建的权限与路径
目录创建失败是上传失败的重灾区,你得确保:- 路径是正确的:尽量用绝对路径(比如用
__DIR__拼接),避免相对路径在不同环境下的歧义 - 递归创建目录并验证结果:mkdir默认不会创建父目录,而且权限不足时会静默失败
$targetDir = __DIR__ . '/../uploads/custom_dir/'; if (!is_dir($targetDir)) { // 第三个参数true表示递归创建所有父目录,权限设为755(根据你的服务器配置调整) $createSuccess = mkdir($targetDir, 0755, true); if (!$createSuccess) { // 这里一定要加错误提示,不然你根本不知道目录没创建成 error_log('无法创建目录:' . $targetDir); exit('目录创建失败,请检查服务器权限'); } }- 路径是正确的:尽量用绝对路径(比如用
逐个检查文件的上传错误
哪怕$_FILES整体看起来正常,单个文件也可能因为各种原因上传失败(比如大小超限、临时文件丢失)。循环处理文件时一定要先检查错误码:for ($i = 0; $i < count($_FILES['files']['name']); $i++) { // 只有错误码为UPLOAD_ERR_OK(值为0)时,文件才是正常上传的 if ($_FILES['files']['error'][$i] !== UPLOAD_ERR_OK) { error_log('文件上传错误,索引' . $i . ',错误码:' . $_FILES['files']['error'][$i]); continue; } $tmpPath = $_FILES['files']['tmp_name'][$i]; $fileName = basename($_FILES['files']['name'][$i]); // 用basename防止路径遍历攻击 $destPath = $targetDir . $fileName; if (!move_uploaded_file($tmpPath, $destPath)) { error_log('文件移动失败:' . $tmpPath . ' -> ' . $destPath); } }验证JS端FormData的构建是否正确
确保你在JS里append文件时,键名带[],这样PHP才能识别为数组:const formData = new FormData(); // 假设files是你选中的文件数组 files.forEach(file => { formData.append('files[]', file); }); // 发送请求时不要手动设置Content-Type,浏览器会自动加上正确的multipart/form-data头 fetch('/your_upload_api.php', { method: 'POST', body: formData });如果键名不带
[],PHP里的$_FILES结构会变成单个文件的形式,你的循环逻辑就会出错。检查服务器的上传配置限制
去看一下php.ini里的这几个参数:upload_max_filesize:单个文件的最大允许大小post_max_size:POST请求的总大小(必须大于upload_max_filesize)max_file_uploads:一次请求允许上传的文件数量上限
如果这些值太小,文件会被静默拦截,而且不会在$_FILES里留下明显的错误提示,得去服务器的错误日志里找线索。
如果排查完这些还是不行,可以把你的PHP上传逻辑代码贴出来,这样更容易定位问题。
内容的提问来源于stack exchange,提问作者user2101411
相关产品推荐
相关产品推荐

