Easy Code Share > PHP > File Upload > Multiple File Upload in PHP, HTML, jQuery by 6 Ways

Multiple File Upload in PHP, HTML, jQuery by 6 Ways


For the topic of Multiple File Upload, there are various approaches including HTML, jQuery AJAX, and PHP. This ultimate complete guide helps you understand how to choose a proper method among them. For example, only PHP cURL method is available for the case of file transfer between hosts.

All codes here are not complicated, so you can easily understand even though you are still students in school. To benefit your learning, we will provide you download link to a zip file thus you can get all source codes for future usage.

Estimated reading time: 11 minutes

 

 

BONUS
Source Code Download

We have released it under the MIT license, so feel free to use it in your own project or your school homework.

 

Download Guideline

  • Prepare HTTP server such as XAMPP or WAMP in your windows environment.
  • Download and unzip into a folder that http server can access.
 DOWNLOAD SOURCE

 

SECTION 1
Html Multiple File Upload

Apart from our previous article for Single File Upload in PHP, by now, we will talk about multiple file upload. The most direct way to be discussed in the section is using HTML <form> element with a lot of <input> tags that can hold file or data.

 

Method 1A – HTML FORM Upload (Files)

HTML Multiple File Upload Without Data

For multiple files upload to a PHP server, it is direct and simple to use HTML <form> element in browser clients. Most importantly, when making a POST request, you should encode the body of data by specifying a way of enctype="multipart/form-data". It does protect all your data in <input type="file"> elements.

upload-1A.html
<!DOCTYPE html>
<!-- method 1A - upload multiple files by HTML Form -->
<html>
<head><link rel="stylesheet" href="upload.css"></head>
<body>
<form action="http://localhost/wpp/exams/a0011/server/multiple-upload.php" method="post" enctype="multipart/form-data">
    <input type="file" name="myfile[]" multiple>
    <input type="submit" value="Upload">
</form>
</body>
</html>

With <input> tag, the array definition of type="file" name="file[]" multiple allows selecting more than one file in dialog box. When clicking on type="submit", the browser confirms to upload multiple files.

 

Method 1B – HTML FORM Upload (Files & Data)

HTML Multiple File Upload With Data

Sometimes, developers require send data along with files at a time. A hidden <input> element with type="hidden" will not only upload data, but also make data invisible. The data to be sent could be a simple string or JSON data, like the example as below.

{method:'method 2', msg:'upload file along with data by HTML Form'}
upload-1B.html
<!DOCTYPE html>
<!-- method 1B - upload multiple files along with data by HTML Form -->
<html>
<head><link rel="stylesheet" href="upload.css"></head>
<body>
<form action="http://localhost/wpp/exams/a0011/server/multiple-upload.php" method="post" enctype="multipart/form-data">
    <input type="file" name="myfile[]" multiple>
    <input type="hidden" name="data" value="{method:'method 2', msg:'upload multiple files along with data by HTML Form'}">
    <input type="submit" value="Upload">
</form>
</body>
</html>

 

SECTION 2
jQuery Ajax Multiple File Upload

The next method to be learned is jQuery AJAX. The jQuery call $.ajax() can transfer multiple files from browser clients to a server site, which accepts file upload using PHP. Specially, the key point is the FormData object that can carry multiple files and data by means of POST method.

 

Method 2A – jQuery AJAX Upload (Files)

jQuery AJAX File Upload Without Data

For HTML <form> element, user’s decision on it will trigger JQuery codes $("#form").submit() to make an AJAX request. Before that request, the then FormData object gathers multiple files from HTML <form> element, where $("#form")[0] is equal to the HTML <form> element.

upload-2A.html
<!DOCTYPE html>
<!-- method 2A - upload multiple files by jQuery -->
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<link rel="stylesheet" href="upload.css">
</head>
<body>
<form id="form">
    <input type="file" name="myfile[]" multiple>
    <input type="submit" value="Upload">
</form>
</body>
</html>
<script>
$(document).ready(function() {
    $("#form").submit(function(e){
        e.preventDefault();
        var formData = new FormData($("#form")[0]);
        $.ajax({
            url : "http://localhost/wpp/exams/a0011/server/multiple-upload.php",
            type : "post",
            data : formData,
            contentType : false,
            processData : false,
            success: function(resp) {
                console.log(resp);
                alert(resp);
            }
        });
    });
});
</script>

Next, the AJAX call, $.ajax(), uploads a multiple files within data : formData.

 

Method 2B – jQuery AJAX Upload (Files & Data)

jQuery AJAX File Upload With Data

Based on Method 2A, Method 2B will upload data, along with multiple files, at a time. First, JSON.stringify(data) converts Javascript object data={...} to be a JSON notation, and then formData.append() append this JSON at end of formData object with the key of 'data'.

upload-2B.html
<!DOCTYPE html>
<!-- method 2B - upload multiple files along with data by jQuery -->
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<link rel="stylesheet" href="upload.css">
</head>
<body>
<form id="form">
    <input type="file" name="myfile[]" multiple>
    <input type="submit" value="Upload">
</form>
</body>
</html>
<script>
$(document).ready(function() {
    $("#form").submit(function(e){
        e.preventDefault();
        var formData = new FormData($("#form")[0]);
        data = {method: 'method 4', msg:'upload multiple files along with data by jQuery'};
        for(key in data) {
            formData.append("data["+key+"]", data[key]);
        }
        $.ajax({
            url : "http://localhost/wpp/exams/a0011/server/multiple-upload.php",
            type : "post",
            data : formData,
            contentType : false,
            processData : false,
            success: function(resp) {
                console.log(resp);
                alert(resp);
            }
        });
    });
});
</script>

In other words, FormData object contain both multiple files and data. Likewise, $.ajax(), uploads data : formData to a PHP server finally.

 

SECTION 3
Php Multiple File Upload

All the 4 methods in previous sections allow browser clients to upload multiple files to hosts, while the next 2 methods using purely PHP scripts mainly transfer multiple files between hosts. Besides, there are different script writings for various PHP versions here. Finally in the section, we will talk about a complex JSON compared with a simple string for file upload.

 

Method 3A – PHP Upload (Files)

PHP Multiple File Upload Without Data

The cURL is a basic PHP library that can help you transfer files or data over HTTP or FTP. Moreover, it executes multiple file upload between hosts without help of browsers. Let us explain this method by a command line as below.

$ php upload-3A.php
success:
Array
(
    [0] => in_transit.png
    [1] => home.png
    [2] => customer_support.png
)

Fundamentally, PHP cURL uses 3 functions of curl_init(), curl_setopt(), and curl_exec() to achieve the goal. Importantly, the parameter CURLOPT_POSTFIELDS defines POST data to be sent, and the key 'myfile[]' in array will result in the notation of $_FILES['myfile'][] at server site.

Actually, this notation is a little bit complex. Thus it is suggested to refer to the next section Multiple File Upload Server, which will show it clearly.

upload-3A.php
<?php
    /* method 3A - upload multiple files by pure PHP */
    $url = "http://localhost/wpp/exams/a0011/server/multiple-upload.php";
    $path = array("images/in_transit.png", "images/home.png", "images/customer_support.png");
    $ary = array();
    foreach ($path as $key=>$item) {
        if (function_exists('curl_file_create')) { // php 5.5+
          $cFile = curl_file_create($item);
        } else { //
            echo 'PHP ' . phpversion() . PHP_EOL;
            $cFile = '@' . realpath($item);
        }
        $ary['myfile['.$key.']'] = $cFile;
    }
    $req = curl_init($url);
    curl_setopt($req, CURLOPT_HEADER, false);
    curl_setopt($req, CURLOPT_POST, true);
    curl_setopt($req, CURLOPT_POSTFIELDS, $ary);
    curl_setopt($req, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($req, CURLOPT_TIMEOUT, 10);
    $data = curl_exec($req);
    echo $data;
?>

The $cFile is a CURLFile object. However, because curl_file_create() only exists in versions of PHP 5.5 above, other PHP versions create it by using realpath().

Finally, the $ary['myfile['.$key.']'] holds all CURLFile objects as an array to be included in the CURLOPT_POSTFIELDS field.

 

Method 3B – PHP Upload (Files & Data)

PHP Multiple File Upload With Data

If uploading data together with multiple files using PHP is required, the example Method 3B will show you. The data can be a simple string or data array. Let us see the difference in notation between a simple string and data array.

The notation about data array is a little bit special, isn’t it? The 'data[method]' and 'data[msg]' as the following gather to be a data array, and then PHP cURL sends it by a POST request.

upload-3B.php
<?php
    /* method 3B - upload multiple files along with data by pure PHP */
    $url = "http://localhost/wpp/exams/a0011/server/multiple-upload.php";
    $path = array("images/in_transit.png", "images/home.png", "images/customer_support.png");
    $ary = array();
    foreach ($path as $key=>$item) {
        if (function_exists('curl_file_create')) { // php 5.5+
            $cFile = curl_file_create($item);
        } else { //
            echo 'PHP ' . phpversion() . PHP_EOL;
            $cFile = '@' . realpath($item);
        }
        $ary['myfile['.$key.']'] = $cFile;
    }
    $ary['data[method]'] = 'method 6';
    $ary['data[msg]'] = 'upload multiple files along with data by pure PHP';
    $req = curl_init($url);
    curl_setopt($req, CURLOPT_HEADER, false);
    curl_setopt($req, CURLOPT_POST, true);
    curl_setopt($req, CURLOPT_POSTFIELDS, $ary);
    curl_setopt($req, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($req, CURLOPT_TIMEOUT, 10);
    $data = curl_exec($req);
    echo $data;
?>

 

SECTION 4
Multiple File Upload Server

In the last section, let us see how server sites handle multiple files upload using PHP. No matter in Windows or Linux, a temporary area is designed to keep incoming files, but they should be moved out later. Also, there are concerns in PHP setting about several file upload limits. At last, you will get tips for PHP cURL installation.

 

Move Uploaded Files

Move Uploaded Multiple File From Temporary Area

Let us see what information a PHP server site will get about file upload. The super global variable $_FILES["myfile"] is a context of that. Among its properties, only $_FILES["myfile"]["tmp_name"][0]~[2] will be mentioned here.

Each item, such as ['tmp_name'], in the $_FILES["myfile"] here has 3 sub-items indexed by 0 to 2.

[myfile] => Array
(
    [name] => Array
        (
            [0] => in_transit.png
            [1] => home.png
            [2] => customer_support.png
        )
    [type] => Array
        (
            [0] => application/octet-stream
            [1] => application/octet-stream
            [2] => application/octet-stream
        )
    [tmp_name] => Array
        (
            [0] => C:\xampp\tmp\php106C.tmp
            [1] => C:\xampp\tmp\php107C.tmp
            [2] => C:\xampp\tmp\php107D.tmp
        )
    [error] => Array
        (
            [0] => 0
            [1] => 0
            [2] => 0
        )
    [size] => Array
        (
            [0] => 8861
            [1] => 5871
            [2] => 4017
        )
)

The PHP super global variable $_FILES["myfile"]["error"] brings a set of error codes for multiple files. For each file, if the error code is UPLOAD_ERR_OK, then it means no error. you can check sizes and move temporary files to your destination.

In addition, another PHP super global variable called $_FILES["myfile"]["size"] can help you limit size of each incoming file.

multiple-upload.php
<?php
/* upload multiple files in one request */
$upload_dir = 'uploads/';
$namelist = array();
foreach ($_FILES["myfile"]["error"] as $key => $error) {
    if ($error == UPLOAD_ERR_OK) {
        $name = basename($_FILES["myfile"]["name"][$key]);
        $target_file = "$upload_dir/$name";
        if ($_FILES["myfile"]["size"][$key] > 10000) { // limit size of 10KB
            echo "error: {$name} is too large. \n";
            continue;
        }
        if (!move_uploaded_file($_FILES["myfile"]["tmp_name"][$key], $target_file))
            echo 'error:'.$_FILES["myfile"]["error"][$key].' see /var/log/apache2/error.log for permission reason';
        else
            $namelist[] = $name;
    }
}
if (isset($_POST['data'])) print_r($_POST['data']);
echo "\n success: \n";
print_r($namelist);
?>

When multiple files arrive, PHP puts it in temporary area. The PHP server-site have to move them to destination by calling move_uploaded_file() iteratedly. If exceptions occur during moving, the error reasons will appear in /var/log/apache2/error.log for Linux and in somewhere for Windows.

Usually, errors are prompted as permission denied when HTTP service is not available to create new files in target directory. At this time, you can grant permission to HTTP service by commmand lines as below, and then try to upload again. The www-data represents Apache2 user id on Ubuntu Linux.

$ chgrp www-data ~/uploads
$ chmod g+w ~/uploads

 

PHP.INI

PHP configuration file locates in c:\xampp\php\php.ini for Windows and /etc/php/5.6/apache2/php.ini for PHP 5.6 in Ubuntu Linux, respectively.

The settings in PHP configuration file php.ini for file upload primarily define temporary directory, maximum allowed file size, and maximum number of files.

;;;;;;;;;;;;;;;;
; Multiple File Uploads ;
;;;;;;;;;;;;;;;;
; Whether to allow HTTP file uploads.
; http://php.net/file-uploads
file_uploads=On
; Temporary directory for HTTP uploaded files (will use system default if not
; specified).
; http://php.net/upload-tmp-dir
upload_tmp_dir="C:\xampp\tmp"
; Maximum allowed size for uploaded files.
; http://php.net/upload-max-filesize
upload_max_filesize=2M
; Maximum number of files that can be uploaded via a single request
max_file_uploads=20

In Windows, Uncommenting the following setting in in c:\xampp\php\php.ini will enable PHP cURL.

extension=php_curl.dll

In Linux, PHP cURL can be installed using command lines for PHP 5.6.

$ sudo apt-get install php5.6-curl

And for PHP 7.2, use the following.

$ sudo apt-get install php7.2-curl

 

FINAL
Conclusion

Reference to How to allow multiple file uploads in HTML forms may help you learn this issue from another view. If you need only single file upload, the article 6 Methods for File Upload in PHP, HTML, AJAX, jQuery is worth reading. Thank you for reading, and we have suggested more helpful articles here. If you want to share anything, please feel free to comment below. Good luck and happy coding!

 

Suggested Reading

Leave a Comment