如何使用HTTP POST选择和上传HTML和PHP多个文件?


154

我有使用进行单个文件上传的经验<input type="file">。但是,我一次不能上传多个文件。

例如,我希望能够一次选择一系列图像,然后将它们上传到服务器。

如果可能的话,最好使用单个文件输入控件。

有谁知道如何做到这一点?谢谢!


2
您的意思是在文件选择器对话框中选择多个文件还是使用多个文件输入?
MitMaro

嗨,您可以上传存档文件(zip,rar,tar,...)吗?
sourcerebels

Answers:


195

这在HTML5中是可能的。范例(PHP 5.4):

<!doctype html>
<html>
    <head>
        <title>Test</title>
    </head>
    <body>
        <form method="post" enctype="multipart/form-data">
            <input type="file" name="my_file[]" multiple>
            <input type="submit" value="Upload">
        </form>
        <?php
            if (isset($_FILES['my_file'])) {
                $myFile = $_FILES['my_file'];
                $fileCount = count($myFile["name"]);

                for ($i = 0; $i < $fileCount; $i++) {
                    ?>
                        <p>File #<?= $i+1 ?>:</p>
                        <p>
                            Name: <?= $myFile["name"][$i] ?><br>
                            Temporary file: <?= $myFile["tmp_name"][$i] ?><br>
                            Type: <?= $myFile["type"][$i] ?><br>
                            Size: <?= $myFile["size"][$i] ?><br>
                            Error: <?= $myFile["error"][$i] ?><br>
                        </p>
                    <?php
                }
            }
        ?>
    </body>
</html>

在文件对话框中选择2个项目后,在Chrome中的外观如下:

chrome多文件选择

这是单击“上传”按钮后的外观。

提交多个文件到PHP

这只是一个完全可行的答案的草图。有关在PHP中正确,安全地处理文件上载的更多信息,请参见PHP手册:处理文件上载


8
它通过w3c验证还是应该通过multiple="multiple"
vol7ron 2012年

10
我认为这是有效的:Thoughtresults.com/html5-boolean-attributes。如果添加<!doctype html>,它将通过w3c验证器。
Mark E. Haase 2012年

2
是的,它可能验证HTML,但使XHTML失败。尽管我仍然喜欢使用XHTML,但我认为人们建议不要使用XHTML。
vol7ron 2012年

11
如果不添加属性名称(例如name="file[]"),它将无法正常工作。我试图编辑答案,但是被拒绝了。
米歇尔·艾尔斯2014年

1
谢谢@MichelAyres,我已经更新了答案。当我最初写这篇文章时,我只解决了问题b / c的HTML部分,还有其他答案解释了PHP部分。随着时间的流逝,这成为一个流行的答案,因此我现在已经扩展到涵盖HTML和PHP。
Mark E. Haase 2015年

94

创建多文件上传需要做一些事情,实际上这是非常基本的。您不需要使用Java,Ajax,Flash。只需构建一个正常的文件上传表单即可:

<form enctype="multipart/form-data" action="post_upload.php" method="POST">

然后是成功的关键;

<input type="file" name="file[]" multiple />

不要忘记那些括号!在post_upload.php中,尝试以下操作:

<?php print_r($_FILES['file']['tmp_name']); ?>

请注意,您将获得一个包含tmp_name数据的数组,这意味着您可以使用带有文件“ number”示例的第三对方括号访问每个文件:

$_FILES['file']['tmp_name'][0]

您可以使用php count()来计数所选文件的数量。祝你好运!


5
谢谢你的提示!它为我节省了很多时间+1
BPm 2012年

它工作得很好...但是我无法在Internet Explorer(v8)中以这种方式上传。我认为IE不支持这种上传方式。
Tariq M Nasim

4
或者,您也可以使用foreach语句循环遍历文件,而不必知道上传的文件数...
ygesher 2013年

请注意,如果您在html中使用名称中的键,例如name =“ file [3]”,则需要通过$ _FILES ['file'] ['tmp_name'] [3]访问该值这不是很明显。
MyStream

8

Firefox 5中的完整解决方案:

<html>
<head>
</head>
<body>
 <form name="uploader" id="uploader" action="multifile.php" method="POST" enctype="multipart/form-data" >
  <input id="infile" name="infile[]" type="file" onBlur="submit();" multiple="true" ></input> 
 </form>

<?php
echo "No. files uploaded : ".count($_FILES['infile']['name'])."<br>"; 


$uploadDir = "images/";
for ($i = 0; $i < count($_FILES['infile']['name']); $i++) {

 echo "File names : ".$_FILES['infile']['name'][$i]."<br>";
 $ext = substr(strrchr($_FILES['infile']['name'][$i], "."), 1); 

 // generate a random new file name to avoid name conflict
 $fPath = md5(rand() * time()) . ".$ext";

 echo "File paths : ".$_FILES['infile']['tmp_name'][$i]."<br>";
 $result = move_uploaded_file($_FILES['infile']['tmp_name'][$i], $uploadDir . $fPath);

 if (strlen($ext) > 0){
  echo "Uploaded ". $fPath ." succefully. <br>";
 }
}
echo "Upload complete.<br>";
?>

</body>
</html>

代码被裁剪。这就是它的上方: <html> <head> </head> <body> <form name="uploader" id="uploader" action="multifile.php" method="POST" enctype="multipart/form-data" > <input id="infile" name="infile[]" type="file" onBlur="submit();" multiple="true" ></input> </form>
Thaps

3
尽管它在IE8中不起作用,但是只能使用真正的浏览器。
Thaps 2012年

5

如果要从选择浏览时显示的文件选择器对话框中选择多个文件,那么您通常不走运。您将需要使用Java小程序或类似的小程序(我认为有一个使用小的Flash文件,如果找到,我会进行更新)。当前,单个文件输入仅允许选择单个文件。

如果您正在谈论使用多个文件输入,那么与使用一个文件输入没有太大区别。发布一些代码,我将尝试进一步提供帮助。


更新:有一种方法可以使用单个使用Flash的“浏览”按钮。我从来没有亲自使用过,但是我已经读了很多。我认为这是您的最佳选择。

http://swfupload.org/


1
我将链接添加到基于Flash的多个上传器中。
MitMaro

我曾经使用过swfupload fwiw-有时会有点痛苦,但是工作起来并不难。
Meep3D

@Barsoom是正确的。在过去的几年中,多文件上传的情况变得更好了。:D
MitMaro 2012年

4

首先,您应该制作如下形式:

<form method="post" enctype="multipart/form-data" >
   <input type="file" name="file[]" multiple id="file"/>
   <input type="submit" name="ok"  />
</form> 

没错。现在,将此代码添加到您的表单代码下或您喜欢的任何页面上

<?php
if(isset($_POST['ok']))
   foreach ($_FILES['file']['name'] as $filename) {
    echo $filename.'<br/>';
}
?>

这很容易...完成


1

如果使用多个输入字段,则可以设置name =“ file []”(或其他任何名称)。这将让他们在一个数组,当你上传到($_FILES['file'] = array ({file_array},{file_array]..)


1
<form action="" method="POST" enctype="multipart/form-data">
  Select image to upload:
  <input type="file"   name="file[]" multiple/>
  <input type="submit" name="submit" value="Upload Image" />
</form>

使用FOR循环

<?php    
  $file_dir  = "uploads";    
  if (isset($_POST["submit"])) {

    for ($x = 0; $x < count($_FILES['file']['name']); $x++) {               

      $file_name   = $_FILES['file']['name'][$x];
      $file_tmp    = $_FILES['file']['tmp_name'][$x];

      /* location file save */
      $file_target = $file_dir . DIRECTORY_SEPARATOR . $file_name; /* DIRECTORY_SEPARATOR = / or \ */

      if (move_uploaded_file($file_tmp, $file_target)) {                        
        echo "{$file_name} has been uploaded. <br />";                      
      } else {                      
        echo "Sorry, there was an error uploading {$file_name}.";                               
      }                 

    }               
  }    
?>

使用FOREACH循环

<?php
  $file_dir  = "uploads";    
  if (isset($_POST["submit"])) {

    foreach ($_FILES['file']['name'] as $key => $value) {                   

      $file_name   = $_FILES['file']['name'][$key];
      $file_tmp    = $_FILES['file']['tmp_name'][$key];

      /* location file save */
      $file_target = $file_dir . DIRECTORY_SEPARATOR . $file_name; /* DIRECTORY_SEPARATOR = / or \ */

      if (move_uploaded_file($file_tmp, $file_target)) {                        
        echo "{$file_name} has been uploaded. <br />";                      
      } else {                      
        echo "Sorry, there was an error uploading {$file_name}.";                               
      }                 

    }               
  }
?>

0

我创建了一个用于上传多个图像的php函数,该函数可以在特定的文件夹中上传多个图像,也可以将记录保存到以下代码中的数据库中:$ arrayimage是通过表单注释发送的图像数组不允许上传使用多个,但您需要创建一个具有相同名称的不同输入字段,就像您可以在单击按钮时设置文件输出的动态添加字段一样。

$ dir是您要保存图像的目录$ fields是要存储在数据库中的字段的名称

数据库字段必须在数组格式中,例如,如果您具有数据库映像存储库和字段名称(如id,name,address),则需要发布数据,例如

$fields=array("id"=$_POST['idfieldname'], "name"=$_POST['namefield'],"address"=$_POST['addressfield']);

然后将该字段传递给函数$ fields

$ table是要在其中存储数据的表的名称。

function multipleImageUpload($arrayimage,$dir,$fields,$table)
{
    //extracting extension of uploaded file
    $allowedExts = array("gif", "jpeg", "jpg", "png");
    $temp = explode(".", $arrayimage["name"]);
    $extension = end($temp);

    //validating image
    if ((($arrayimage["type"] == "image/gif")
    || ($arrayimage["type"] == "image/jpeg")
    || ($arrayimage["type"] == "image/jpg")
    || ($arrayimage["type"] == "image/pjpeg")
    || ($arrayimage["type"] == "image/x-png")
    || ($arrayimage["type"] == "image/png"))

    //check image size

    && ($arrayimage["size"] < 20000000)

    //check iamge extension in above created extension array
    && in_array($extension, $allowedExts)) 
    {
        if ($arrayimage["error"] > 0) 
        {
            echo "Error: " . $arrayimage["error"] . "<br>";
        } 
        else 
        {
            echo "Upload: " . $arrayimage["name"] . "<br>";
            echo "Type: " . $arrayimage["type"] . "<br>";
            echo "Size: " . ($arrayimage["size"] / 1024) . " kB<br>";
            echo "Stored in: ".$arrayimage['tmp_name']."<br>";

            //check if file is exist in folder of not
            if (file_exists($dir."/".$arrayimage["name"])) 
            {
                echo $arrayimage['name'] . " already exists. ";
            } 
            else 
            {
                //extracting database fields and value
                foreach($fields as $key=>$val)
                {
                    $f[]=$key;
                    $v[]=$val;
                    $fi=implode(",",$f);
                    $value=implode("','",$v);
                }
                //dynamic sql for inserting data into any table
                $sql="INSERT INTO " . $table ."(".$fi.") VALUES ('".$value."')";
                //echo $sql;
                $imginsquery=mysql_query($sql);
                move_uploaded_file($arrayimage["tmp_name"],$dir."/".$arrayimage['name']);
                echo "<br> Stored in: " .$dir ."/ Folder <br>";

            }
        }
    } 
    //if file not match with extension
    else 
    {
        echo "Invalid file";
    }
}
//function imageUpload ends here
}

// imageFunctions类在此处结束

您可以尝试使用此代码插入带有扩展名的多个图像,此功能是为了检查图像文件而创建的,可以在代码中替换垂直文件的扩展名列表


大家好,我使用文件输入将文档附加到自动生成的电子邮件中。我可以一次附加多个文档,但是,我想附加来自不同目录的多个文档。当前,如果执行此操作,我当前选择的文档将替换为我选择的新文档。请我怎么做。谢谢
Kunbi 2015年

-1

部分答案:pear HTTP_UPLOAD可能有用 http://pear.php.net/manual/en/package.http.http-upload.examples.php

有多个文件的完整示例


1
您可以使用PEAR软件包,但是此任务相当简单,除非您需要该软件包提供的额外功能(国际化错误消息,验证等),否则我建议您使用本机PHP函数。但这只是我的意见。:)
MitMaro

我同意你的意见,这就是为什么我写了“部分答案”的原因。但是我也尽力重用代码,并且我经常会尽我所能地使用梨(梨编码器比我好得多:-D)
damko
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.