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

多文件上传后PHP接收数组结构不符预期,求问题排查

多文件上传后PHP接收的文件数组结构不符合预期

我尝试用以下代码实现多文件上传:

<input type="file" class="file-upload-field" id="file_name" name="files_names[]" multiple="multiple" />

我的JavaScript/jQuery代码如下:

$(document).on('submit', '#addform', (function() {
  var files = $('#file_name')[0].files;
  var formData = new FormData();

  for (var i=0; i < files.length; i++)
    formData.append('file_names[]', files[i]);

  $.ajax({
    url: 'ajax_addrecord.php',
    type: "POST",
    data: formData,
    contentType: false,
    cache: false,
    processData:false,
    timeout: 2000,
    success: function(data) {
      console.log('Record added.');
    }
  });
}));

但在PHP文件中通过以下代码检查文件接收情况时:

error_log($date_time." :: ".print_r($_FILES, true), 0);

得到的结果为:

2024-03-03 11:14:47 :: Array
 (
     [file_names] => Array
         (
             [name] => Array
                 (
                     [0] => HeleneBarrow Profil.png
                     [1] => horn_fuuuck_lovers.JPG
                     [2] => lakn_profil_mona.JPG
                 )
             [type] => Array
                 (
                     [0] => image/png
                     [1] => image/jpeg
                     [2] => image/jpeg
                 )
             [tmp_name] => Array
                 (
                     [0] => /tmp/phpZ3FVIl
                     [1] => /tmp/phpvolre9
                     [2] => /tmp/phpp4gYJW
                 )
             [error] => Array
                 (
                     [0] => 0
                     [1] => 0
                     [2] => 0
                 )
             [size] => Array
                 (
                     [0] => 270198
                     [1] => 12359
                     [2] => 82773
                 )
         )

而我预期的结果应该是每个文件对应一个独立数组:

[file_names] => Array
    [0] => Array
        (
            [name] => HeleneBarrow Profil.png
            [type] => image/png
            [tmp_name] => /tmp/phpNmM8Se
            [error] => 0
            [size] => 270198
        )
    [1] => Array
        (
            [name] => horn_fuuuck_lovers.JPG
            [type] => image/jpeg
            [tmp_name] => /tmp/phpvolre9
            [error] => 0
            [size] => 270198
        )
    [2] => Array
        (
            [name] => lakn_profil_mona.JPG
            [type] => image/jpeg
            [tmp_name] => /tmp/phpp4gYJW
            [error] => 0
            [size] => 270198
        )

目前数组是按属性而非文件进行分组的,请问哪里出了问题?


问题原因与解决办法

原因

这是PHP解析多文件上传数据的默认行为:当通过file_names[]格式提交多个文件时,PHP会自动将同一属性(name、type等)归组到子数组中,而非按单个文件打包成独立数组。

解决办法

有两种方式可以得到你预期的数组结构:

方式1:修改JavaScript中的FormData追加逻辑

在循环中给每个文件指定带索引的键名,替代file_names[]:

for (var i=0; i < files.length; i++) {
  // 直接用带索引的键名追加文件即可
  formData.append(`file_names[${i}]`, files[i]);
}

这样PHP会自动将每个文件解析为独立的数组元素,完全符合你的预期结构。

方式2:在PHP中转换现有数组结构

如果无法修改前端代码,可以在PHP里手动转换数组格式:

$formattedFiles = [];
if (isset($_FILES['file_names'])) {
    $fileCount = count($_FILES['file_names']['name']);
    for ($i = 0; $i < $fileCount; $i++) {
        $formattedFiles['file_names'][$i] = [
            'name'     => $_FILES['file_names']['name'][$i],
            'type'     => $_FILES['file_names']['type'][$i],
            'tmp_name' => $_FILES['file_names']['tmp_name'][$i],
            'error'    => $_FILES['file_names']['error'][$i],
            'size'     => $_FILES['file_names']['size'][$i]
        ];
    }
}
// 此时$formattedFiles就是你需要的按文件分组的结构

说明

两种方式都能实现目标,优先推荐修改前端代码的方式,它让数据传递更直接,减少后端的额外处理;如果前端代码无法调整,PHP转换的方式也能完美解决问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 14:47:04