【问题标题】:How to get $_FILES data via ajax in same format as via pure PHP如何通过 ajax 以与纯 PHP 相同的格式获取 $_FILES 数据
【发布时间】:2019-08-13 17:28:52
【问题描述】:

我正在处理上传脚本。我唯一需要编辑的是 $_FILES 数组的格式。

我的 HTML

<input id="upload_dialog" name="file[]" type="file" multiple>

我的 JavaScript

<script>
    $('#upload_dialog').on('change', function(event) {
      var form = new FormData();
      $.each(event.target.files, function(key, value) {
        form.append(key, value);
      });

      $.ajax({
        url: 'url,
        type: 'POST',
        data: form,
        processData: false,
        contentType: false,
        cache: false,
        async: true,
        done: function(data) {
          data = JSON.parse(data);

      });
    });
</script>

这个数组我会通过ajax上传文件得到。

array(2) {
  [0]=>
  array(5) {
    ["name"]=>
    string(11) "ps-logo.jpg"
    ["type"]=>
    string(10) "image/jpeg"
    ["tmp_name"]=>
    string(23) "/home/www/tmp/phpMBu4TE"
    ["error"]=>
    int(0)
    ["size"]=>
    int(24722)
  }
  [1]=>
  array(5) {
    ["name"]=>
    string(12) "tnk-logo.png"
    ["type"]=>
    string(9) "image/png"
    ["tmp_name"]=>
    string(23) "/home/www/tmp/php9yPGpf"
    ["error"]=>
    int(0)
    ["size"]=>
    int(23748)
  }
}

但我需要这种类型的数组,如果我只通过纯 PHP 提交上传表单,我通常会得到它。

array(1) {
  ["file"]=>
  array(5) {
    ["name"]=>
    array(2) {
      [0]=>
      string(12) "tnk-logo.png"
      [1]=>
      string(11) "ps-logo.jpg"
    }
    ["type"]=>
    array(2) {
      [0]=>
      string(9) "image/png"
      [1]=>
      string(10) "image/jpeg"
    }
    ["tmp_name"]=>
    array(2) {
      [0]=>
      string(23) "/home/www/tmp/phpWGezym"
      [1]=>
      string(23) "/home/www/tmp/phpIqOpKY"
    }
    ["error"]=>
    array(2) {
      [0]=>
      int(0)
      [1]=>
      int(0)
    }
    ["size"]=>
    array(2) {
      [0]=>
      int(23748)
      [1]=>
      int(24722)
    }
  }
}

有什么简单的方法可以通过ajax发送数据来获取这种类型的数组吗?

【问题讨论】:

    标签: javascript php jquery ajax upload


    【解决方案1】:

    JavaScript 解决方案

    不要将文件添加为新表单的元素,而是使用输入所在的表单创建 FormData 实例。

    $('#upload_dialog').on('change', function(event) {
        var input = event.target,
            form = input.form,
            data = new FormData(form);
    
        $.ajax({
            url: '/form.php',
            type: 'POST',
            data: data,
            processData: false,
            contentType: false,
            cache: false,
            async: true,
            done: function(data) {
                data = JSON.parse(data);
            }
        });
    });
    

    我原来的 PHP 解决方案不太好

    要让 PHP 处理可能提交的文件的两种方式,您可以执行以下操作将其转换为您想要的格式(如果它尚未采用该格式):

    function maybe_ajax_files($field) {
        // If $_FILES is empty or it's already got the field we need,
        // just use it as-is.
        if (empty($_FILES) || isset($_FILES[$field])) {
            return $_FILES;
        }
    
        // Otherwise, regroup them...
        $regrouped = array();
        foreach ($_FILES as $file) {
            foreach ($file as $key => $val) {
                if (!isset($regrouped[$key])) {
                    $regrouped[$key] = array();
                }
                $regrouped[$key][] = $val;
            }
        }
    
        // Then assign that array to the desired field in a new array.
        $files = array();
        $files[$field] = $regrouped;
        return $files;
    }
    
    // 'file' is the name of the field in your example:
    // <input id="upload_dialog" name="file[]" type="file" multiple>
    $files = maybe_ajax_files('file');
    

    【讨论】:

    • 当然,这是我的首要解决方案,但如果可能的话,我想避免这种情况并在 JS 中解决它。如果没有,我将不得不按照您描述的方式进行。
    • 用更好的纯 JavaScript 答案编辑了我的答案。
    • 是的,这正是我所需要的。我需要解决的最后一件事是,我在表单中有多个文件输入,并且我只需要通过 ajax 发送来自被选中的文件的数据。现在,所有文件输入都发送到 php,其中一些是空的。有没有办法在发送到 php 之前删除这些空文件输入?
    • 根据你的情况,你可以离开他们。发送空字段没有太多开销。但是您可以像最初那样创建一个空的表单,而不是用整个表单实例化 FormData,读取更改的输入的名称,然后将该字段单独附加到 FormData。
    • 我在发送时将空字段标记为“已禁用”,这对我有用。将来我可能会实施您的想法,这对我来说似乎更清楚。无论如何,非常感谢您的帮助。
    猜你喜欢
    • 2013-11-22
    • 1970-01-01
    • 2013-06-09
    • 2012-10-16
    • 2021-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多