利用 multiple 实现多文件上传

页面中上传文件是用过 input[type=file] 元素来实现的,既能实现单文件上传,又能实现多文件上传。但是多文件上传有一个小坑,现记录下来免得以后忘记

先看看 单文件上传

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>Multiple File Upload</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
  <form action="upload.php" method="POST" enctype="multipart/form-data">
    <input type="file" name="file" id="file">
    <input type="submit" value="上传">
  </form>
</body>
</html>
<?php
if(!empty($_FILES['file']['name'])){       //判断是否有文件
  $fileinfo = $_FILES['file'];      //将文件信息赋给变量$fileinfo
  move_uploaded_file($fileinfo['tmp_name'], $fileinfo['name']);  //上传文件
  echo json_encode($fileinfo);
}

echo 返回的文件信息如下

error: 0
name: "timg.jpeg"
size: 221292
tmp_name: "D:\xampp\tmp\phpA118.tmp"
type: "image/jpeg"

多文件上传 则需要稍微做些改动,在 html 文件中修改代码如下

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>Multiple File Upload</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
  <form action="upload.php" method="POST" enctype="multipart/form-data">
    <input type="file" name="file[]" id="file" multiple>
    <input type="submit" value="上传">
  </form>
</body>
</html>

html 文件改动有两点,分别是在 input[type=file] 元素上添加 mutiple 属性以及在 name 属性值后添加一对中括号 [],中括号一定要加,不然后台只会接收最后一个上传的文件,这是一个小坑

php 文件代码改动如下

<?php
if(count($_FILES['file']['name']) > 0){       //判断是否有文件
  $fileinfo = $_FILES['file'];      //将文件信息赋给变量$fileinfo
  for($i=0; $i<count($fileinfo['name']); $i++) {
    move_uploaded_file($fileinfo['tmp_name'][$i], $fileinfo['name'][$i]);  //上传文件
  }
  echo json_encode($fileinfo);
}

echo 返回的内容如下

error: [0, 0, 0]
name: ["timg (1).jpeg", "timg (2).jpeg", "timg (3).jpeg"]
size: [194566, 196695, 127405]
tmp_name: ["D:\xampp\tmp\php6A30.tmp", "D:\xampp\tmp\php6A31.tmp", "D:\xampp\tmp\php6A32.tmp"]
type: ["image/jpeg", "image/jpeg", "image/jpeg"]

从 echo 返回的内容来看,多文件上传情形下的 $fileinfo 变量是一个二维数组,所以需要用一个 for 循环来处理

使用 formData 替代 submit 来进行文件上传需要将 html 文件代码修改为

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>Multiple File Upload</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
  <form action="upload.php" method="POST" enctype="multipart/form-data">
    <input type="file" name="file[]" id="file" multiple="multiple">
    <input type="button" value="上传" id="bt">
  </form>

  <script src="axios.min.js"></script>
  <script>
    var bt = document.querySelector('#bt');
    bt.addEventListener('click', function () {
      var files = document.querySelector('#file').files;  // 获取所有文件
      var formData = new FormData();
      for(var i=0; i<files.length; i++){                
        formData.append("file[]", files[i]);
      }
      axios.post('upload.php', formData)
      .then(function (response) {
        console.log(response.data);
      });
    });
  </script>
</body>
</html>

需要注意的是这种方式将中括号添加在了 formData 的 append 方法中,而非标签元素中
上面的示例用到了 axios 插件,该插件是一个封装过的请求插件,本文不做过多介绍

除特殊说明外本人博客均属原创,转载请注明出处:http://blog.johnhan.cn/blog_1004.html
鄂ICP备17018604号-1  鄂公网安备42060702000030号