在将多个文件上传到服务器之前验证多个文件上传中的单个文件

Posted

技术标签:

【中文标题】在将多个文件上传到服务器之前验证多个文件上传中的单个文件【英文标题】:Validate individual files in multiple file upload before uploading them to server 【发布时间】:2015-09-23 01:09:03 【问题描述】:

我有一个包含 3 个单独的文件输入字段的表单。在将它们上传到服务器之前,我似乎找不到单独验证它们的 MIME 类型的方法。 (前两个应该只允许 MP3 文件,而最后一个应该只允许 JPEG 文件。)

我该怎么做,或者最好在文件上传后检查 MIME 类型,然后保留它,或者删除它并返回错误消息?

这是我的代码:

<form action="upload.php" method="post" enctype="multipart/form-data">

  <div class="col-2">
    <label>
      Full MP3 file
      <input type="file" name="file_array[]" id="file_array[]" tabindex="1" required>
    </label>
  </div>

  <div class="col-2">
    <label>
      Sample MP3 file (30-45 seconds)
      <input type="file" name="file_array[]" id="file_array[]" tabindex="2" required>
    </label>
  </div>

  <div class="col-2">
    <label>
      JPEG Cover Art ( Recommended 400 x 400 px)
      <input type="file" name="file_array[]" id="file_array[]" tabindex="3" required>
    </label>
  </div>

  <div class="col-2">
    <label>
      <progress id="progressBar" value="0" max="100" style="width:100%;">    </progress>
    </label>
  </div>

  <div class="col-submit">
    <input type="submit" value="Upload" class="submitbtn" onclick="uploadFile()">
  </div>

</form>

这是upload.php

if(isset($_FILES['file_array']))
    $name_array = $_FILES['file_array']['name'];
    $tmp_name_array = $_FILES['file_array']['tmp_name'];
    $type_array = $_FILES['file_array']['type'];
    $size_array = $_FILES['file_array']['size'];
    $error_array = $_FILES['file_array']['error'];
    for($i = 0; $i < count($tmp_name_array); $i++)
        if(move_uploaded_file($tmp_name_array[$i], "../artists/$id/temp/".$name_array[$i]))
            echo $name_array[$i]." upload is complete<br>";
         else 
            echo "move_uploaded_file function failed for ".$name_array[$i]."<br>";
        
    

【问题讨论】:

javascript 验证充其量也是建议性的。你最好使用&lt;input type=file accept="image/*"&gt; 过滤器。如果文件内容是浏览器声称/猜测的内容,您仍然必须在 PHP 中断言。 【参考方案1】:

我认为您可以在客户端使用验证来使体验更加流畅。正如马里奥指出的那样,你可以使用这样的东西来只接受 mp3 文件:

<input type="file" accept=".mp3" name="file_array[]" id="file_array[]" tabindex="1" required>

但由于您无法信任用户数据,因此您还必须添加服务器端验证。例如:

if(isset($_FILES['file_array']))
$name_array = $_FILES['file_array']['name'];
$tmp_name_array = $_FILES['file_array']['tmp_name'];
$type_array = $_FILES['file_array']['type'];
$size_array = $_FILES['file_array']['size'];
$error_array = $_FILES['file_array']['error'];
for($i = 0; $i < 3; $i++)

    if ($i == 2)
        if($type_array[2] != 'image/jpeg')
            echo 'Invalid file type: ' . $type_array[2];
            break;
         
    
    else 
        if($type_array[$i] != 'audio/mp3')
            echo 'Invalid file type: ' . $type_array[$i];
            break;
        
    

    if(move_uploaded_file($tmp_name_array[$i],"../artists/$id/temp/".$name_array[$i]))
        echo $name_array[$i]." upload is complete<br>";
     else 
        echo "move_uploaded_file function failed for ".$name_array[$i]."<br>";
    


测试了上面的代码,它似乎对我有用。

注意事项:

如果您已经知道上传文件的数量,请不要使用count,因为这可能会造成风险,并且如果您希望一次上传的文件数量可变,请确保count 结果不超过最大值。也可以在循环外使用count,所以它只计算一次。

还有其他更严格的方法来验证文件类型,但这是我现在得到的。

希望这会有所帮助,如果我有任何不妥之处,请提供反馈。

【讨论】:

【参考方案2】:

您不能,因为数据仅在上传之后可用。您可以尝试使用以下命令告诉浏览器(如果有能力)仅发送特定的 mime 类型:

<input type="file1" name="image" accept="image/*">
<input type="file2" name="pdf" accept="application/pdf">

【讨论】:

以上是关于在将多个文件上传到服务器之前验证多个文件上传中的单个文件的主要内容,如果未能解决你的问题,请参考以下文章

上传文件前验证文件扩展名

如何在将上传的文件保存到目录之前重命名?

{Multi Drag-and-drop}如何在上传之前为每个文件显示组合框

并行处理nodejs中的多个文件

将多个文件上传到服务器并

是否可以在通过表单上传之前预览本地图像?