Làm cách nào tôi có thể chọn và tải lên nhiều tệp bằng HTML và PHP, bằng cách sử dụng HTTP POST?


154

Tôi có kinh nghiệm làm điều này với tải lên tập tin duy nhất bằng cách sử dụng <input type="file">. Tuy nhiên, tôi gặp khó khăn khi tải lên nhiều hơn một lần.

Ví dụ: tôi muốn có thể chọn một loạt hình ảnh, sau đó tải chúng lên máy chủ cùng một lúc.

Sẽ thật tuyệt khi sử dụng một điều khiển nhập tệp duy nhất, nếu có thể.

Có ai biết làm thế nào để thực hiện điều này? Cảm ơn!


2
Bạn có nghĩa là chọn nhiều hơn một tệp trong hộp thoại chọn tệp hoặc sử dụng nhiều đầu vào tệp?
MitMaro

Xin chào, Bạn có thể tải lên tệp lưu trữ (zip, rar, tar, ...) không?
sourcerebels

Câu trả lời:


195

Điều này có thể có trong HTML5 . Ví dụ (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>

Đây là giao diện của Chrome sau khi chọn 2 mục trong hộp thoại tệp:

chọn nhiều tập tin chrome

Và đây là giao diện sau khi nhấp vào nút "Tải lên".

gửi nhiều tệp tới PHP

Đây chỉ là một bản phác thảo của một câu trả lời làm việc đầy đủ. Xem Hướng dẫn sử dụng PHP: Xử lý tải lên tệp để biết thêm thông tin về xử lý an toàn, tải lên tệp trong PHP.


8
nó có vượt qua xác nhận w3c hay không multiple="multiple"?
vol7ron

10
Tôi tin rằng nó hợp lệ: thinkresults.com/html5-boolean-attribut . Nó vượt qua trình xác nhận w3c nếu bạn thêm <! Doctype html>.
Đánh dấu E. Haase

2
vâng, nó có thể xác nhận HTML, nhưng XHTML không thành công. Mặc dù tôi vẫn thích sử dụng XHTML, tôi nghĩ mọi người khuyên nên tránh xa nó trong những ngày này.
vol7ron

11
Nó không hoạt động mà không thêm tên thuộc tính (ví dụ name="file[]"). Tôi đã cố chỉnh sửa câu trả lời , nhưng nó đã bị từ chối.
Michel Ayres

1
Cảm ơn @MichelAyres, tôi đã cập nhật câu trả lời của mình. Khi tôi viết bài này, tôi chỉ giải quyết phần HTML của vấn đề b / c có những câu trả lời khác giải thích phần PHP. Theo thời gian, đây đã trở thành một câu trả lời phổ biến, vì vậy giờ đây tôi đã mở rộng để bao quát cả HTML và PHP.
Đánh dấu E. Haase

94

Có một vài điều bạn cần làm để tạo một tệp tải lên, thực sự khá cơ bản. Bạn không cần sử dụng Java, Ajax, Flash. Chỉ cần xây dựng một hình thức tải lên tập tin bình thường bắt đầu với:

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

Sau đó, chìa khóa để thành công;

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

KHÔNG quên những dấu ngoặc đó! Trong post_upload.php hãy thử như sau:

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

Lưu ý rằng bạn nhận được một mảng với dữ liệu tmp_name, điều đó có nghĩa là bạn có thể truy cập từng tệp bằng một cặp dấu ngoặc thứ ba với ví dụ 'số' của tệp:

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

Bạn có thể sử dụng php Count () để đếm số lượng tệp đã được chọn. Goodluck widdit!


5
Cảm ơn vì tiền hỗ trợ! nó đã tiết kiệm cho tôi rất nhiều thời gian +1
BPm

Nó hoạt động rất tốt ... nhưng tôi gặp sự cố khi tải lên theo cách này trong Internet Explorer (v8). Tôi nghĩ IE không hỗ trợ tải lên theo cách này.
Tariq M Nasim

4
Hoặc bạn có thể lặp qua các tệp bằng một foreachcâu lệnh mà không cần phải biết số lượng tệp được tải lên ...
ygesher

Lưu ý, nếu bạn sử dụng một khóa trong tên của bạn trong html của bạn, ví dụ name = "file [3]", thì bạn cần truy cập giá trị qua $ _FILES ['file'] ['tmp_name'] [3], trong trường hợp Điều đó không rõ ràng.
MyStream

8

Giải pháp đầy đủ trong 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>

Mã bị cắt bớt. Đây là những gì xuất hiện ngay phía trên nó: <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
Nó không hoạt động trong IE8, nhưng sau đó chỉ sử dụng một trình duyệt thực sự.
Bẫy

5

Nếu bạn muốn chọn nhiều tệp từ hộp thoại chọn tệp hiển thị khi bạn chọn duyệt thì bạn hầu như không gặp may. Bạn sẽ cần sử dụng một applet Java hoặc một cái gì đó tương tự (tôi nghĩ có một cái sử dụng một tệp flash nhỏ, tôi sẽ cập nhật nếu tôi tìm thấy nó). Hiện tại một đầu vào tệp duy nhất chỉ cho phép lựa chọn một tệp duy nhất.

Nếu bạn đang nói về việc sử dụng nhiều đầu vào tập tin thì không nên có nhiều sự khác biệt so với việc sử dụng một đầu vào. Đăng một số mã và tôi sẽ cố gắng để giúp thêm.


Cập nhật: Có một phương pháp để sử dụng một nút 'duyệt' duy nhất sử dụng flash. Tôi chưa bao giờ sử dụng cá nhân này nhưng tôi đã đọc một số tiền khá lớn về nó. Tôi nghĩ rằng đó là bức ảnh tốt nhất của bạn.

http://swfupload.org/


1
Tôi đã thêm liên kết đến flash dựa trên nhiều trình tải lên.
MitMaro

Tôi đã sử dụng swfupload fwiw - đôi khi hơi đau một chút nhưng thực sự không khó để làm việc.
Meep3D

@Barsoom là chính xác. Mọi thứ đã trở nên tốt hơn nhiều trên nhiều tệp tải lên trong vài năm qua. : D
MitMaro

4

Trước tiên, bạn nên tạo mẫu như thế này:

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

đúng vậy bây giờ thêm mã này dưới mã mẫu của bạn hoặc trên bất kỳ trang nào bạn thích

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

thật dễ dàng ... kết thúc


1

Nếu bạn sử dụng nhiều trường nhập, bạn có thể đặt name = "file []" (hoặc bất kỳ tên nào khác). Điều đó sẽ đặt chúng trong một mảng khi bạn tải chúng lên ( $_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>

Sử dụng vòng lặp 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}.";                               
      }                 

    }               
  }    
?>

Sử dụng vòng lặp 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

Tôi đã tạo một hàm php được sử dụng để tải lên nhiều hình ảnh, chức năng này có thể tải lên nhiều hình ảnh trong thư mục cụ thể và nó có thể lưu các bản ghi vào cơ sở dữ liệu trong đoạn mã sau $ Arrayimage là mảng hình ảnh được gửi qua ghi chú biểu mẫu rằng nó sẽ không cho phép tải lên để sử dụng nhiều nhưng bạn cần tạo các trường đầu vào khác nhau có cùng tên như bạn sẽ có thể đặt trường bổ sung động của tệp không tranh chấp khi nhấp vào nút.

$ dir là thư mục mà bạn muốn lưu hình ảnh $ field là tên của trường mà bạn muốn lưu trữ trong cơ sở dữ liệu

trường cơ sở dữ liệu phải ở trong ví dụ định dạng mảng nếu bạn có hình ảnh cơ sở dữ liệu và tên trường như id, tên, địa chỉ thì bạn cần đăng dữ liệu như

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

và sau đó chuyển trường đó vào hàm $ field

$ bảng là tên của bảng mà bạn muốn lưu trữ dữ liệu ..

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
}

// lớp imageFifts kết thúc tại đây

bạn có thể thử mã này để chèn nhiều hình ảnh với phần mở rộng của nó, chức năng này được tạo để kiểm tra các tệp hình ảnh, bạn có thể thay thế danh sách tiện ích mở rộng cho các tệp vuông góc trong mã


Xin chào, tôi sử dụng tập tin đầu vào để đính kèm tài liệu vào một email tự động. Tôi có thể đính kèm nhiều tài liệu cùng một lúc, tuy nhiên, tôi muốn đính kèm nhiều tài liệu từ các thư mục khác nhau. Hiện tại nếu tôi làm điều này, tài liệu hiện được chọn của tôi sẽ được thay thế bằng tài liệu mới mà tôi chọn. Làm thế nào để tôi đi về điều này. Cảm ơn
Kunbi

-1

câu trả lời một phần: lê HTTP_UPLOAD có thể hữu ích http://pear.php.net/manual/en/package.http.http-upload.examples.php

có một ví dụ đầy đủ cho nhiều tệp


1
Bạn có thể sử dụng gói PEAR nhưng tác vụ này khá nhỏ và trừ khi bạn cần các tính năng bổ sung mà gói cung cấp (thông báo lỗi quốc tế hóa, xác thực, v.v ...) Tôi sẽ khuyên bạn nên sử dụng các hàm PHP gốc. Nhưng đây chỉ là ý kiến ​​của tôi. :)
MitMaro

Tôi đồng ý với bạn, đó là lý do tại sao tôi viết "câu trả lời một phần". Nhưng tôi cũng làm hết sức mình để sử dụng lại mã và tôi thường làm việc nhiều nhất có thể với lê (lập trình viên lê tốt hơn tôi nhiều :-D)
damko
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.