PHP Upload Multiple Files Securely (original) (raw)

Summary: in this tutorial, you’ll learn how to upload multiple files to the server in PHP securely.

Introduction to the PHP upload multiple files #

In the previous tutorial, you learned how to upload a single file from a client to the webserver in PHP. All the rules of uploading a single file are relevant to multiple files.

First, the HTML form element must have the enctype attribute sets to "multipart/form-data" to enable file uploading. For example:

<form action="upload.php" method="post" enctype="multipart/form-data">Code language: PHP (php)

Second, the file input element must have the multiple attribute and its name must have the square brackets ([]) like this:

<input type="file" name="files[]" id="files" multiple />Code language: PHP (php)

In PHP, you can access the $_FILES['files'] to get the information of the uploaded files:

`<?php

var_dump($_FILES['files']);`Code language: PHP (php)

The 'files' is the name of the file input element.

The following example reuses the existing functions and logic developed in the file upload tutorial.

First, create the following project structure:

├── inc | ├── flash.php | └── functions.php ├── index.php ├── upload.php └── uploadsCode language: PHP (php)

Second, add the following code to the index.php to create the file upload form:

`

PHP upload multiple files
Select files to upload:
Upload
`Code language: PHP (php)

The index.php does the following:

  1. Start a new session or resume an existing session:

session_start();Code language: PHP (php)

  1. Load the code from the inc/flash.php file:

require_once __DIR__ . '/inc/flash.php';Code language: PHP (php)

  1. Call the flash() function to show a message with the name 'upload'. The flash() function is defined in the flash.php file.

<?php flash('upload') ?>Code language: PHP (php)

  1. Create an upload form that submits to the upload.php file.

Third, add the following code to the upload.php file to validate and upload multiple files:

`<?php

session_start();

require_once DIR . '/inc/flash.php'; require_once DIR . '/inc/functions.php';

const ALLOWED_FILES = [ 'image/png' => 'png', 'image/jpeg' => 'jpg' ];

const MAX_SIZE = 5 * 1024 * 1024; // 5MB

const UPLOAD_DIR = DIR . '/uploads';

ispostrequest=strtolower(is_post_request = strtolower(ispostrequest=strtolower(_SERVER['REQUEST_METHOD']) === 'post'; hasfiles=isset(has_files = isset(hasfiles=isset(_FILES['files']);

if (!$is_post_request || !$has_files) { redirect_with_message('Invalid file upload operation', FLASH_ERROR); } files=files = files=_FILES['files']; filecount=count(file_count = count(filecount=count(files['name']);

// validation $errors = []; for ($i = 0; i<i < i<file_count; $i++) { // get the uploaded file info status=status = status=files['error'][$i]; filename=filename = filename=files['name'][$i]; tmp=tmp = tmp=files['tmp_name'][$i];

// an error occurs
if ($status !== UPLOAD_ERR_OK) {
    <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>e</mi><mi>r</mi><mi>r</mi><mi>o</mi><mi>r</mi><mi>s</mi><mo stretchy="false">[</mo></mrow><annotation encoding="application/x-tex">errors[</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">errors</span><span class="mopen">[</span></span></span></span>filename] = MESSAGES[$status];
    continue;
}
// validate the file size
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mi>i</mi><mi>l</mi><mi>e</mi><mi>s</mi><mi>i</mi><mi>z</mi><mi>e</mi><mo>=</mo><mi>f</mi><mi>i</mi><mi>l</mi><mi>e</mi><mi>s</mi><mi>i</mi><mi>z</mi><mi>e</mi><mo stretchy="false">(</mo></mrow><annotation encoding="application/x-tex">filesize = filesize(</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">es</span><span class="mord mathnormal">i</span><span class="mord mathnormal">ze</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">es</span><span class="mord mathnormal">i</span><span class="mord mathnormal">ze</span><span class="mopen">(</span></span></span></span>tmp);

if ($filesize > MAX_SIZE) {
    // construct an error message
    $message = sprintf("The file %s is %s which is greater than the allowed size %s",
        $filename,
        format_filesize($filesize),
        format_filesize(MAX_SIZE));

    <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>e</mi><mi>r</mi><mi>r</mi><mi>o</mi><mi>r</mi><mi>s</mi><mo stretchy="false">[</mo></mrow><annotation encoding="application/x-tex">errors[</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">errors</span><span class="mopen">[</span></span></span></span>filesize] = $message;
    continue;
}

// validate the file type
if (!in_array(get_mime_type($tmp), array_keys(ALLOWED_FILES))) {
    <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>e</mi><mi>r</mi><mi>r</mi><mi>o</mi><mi>r</mi><mi>s</mi><mo stretchy="false">[</mo></mrow><annotation encoding="application/x-tex">errors[</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">errors</span><span class="mopen">[</span></span></span></span>filename] = "The file $filename is allowed to upload";
}

}

if ($errors) { redirect_with_message(format_messages('The following errors occurred:',$errors), FLASH_ERROR); }

// move the files for($i = 0; i<i < i<file_count; $i++) { filename=filename = filename=files['name'][$i]; tmp=tmp = tmp=files['tmp_name'][$i]; mimetype=getmimetype(mime_type = get_mime_type(mimetype=getmimetype(tmp);

// set the filename as the basename + extension
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>u</mi><mi>p</mi><mi>l</mi><mi>o</mi><mi>a</mi><mi>d</mi><mi>e</mi><msub><mi>d</mi><mi>f</mi></msub><mi>i</mi><mi>l</mi><mi>e</mi><mo>=</mo><mi>p</mi><mi>a</mi><mi>t</mi><mi>h</mi><mi>i</mi><mi>n</mi><mi>f</mi><mi>o</mi><mo stretchy="false">(</mo></mrow><annotation encoding="application/x-tex">uploaded_file = pathinfo(</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.9805em;vertical-align:-0.2861em;"></span><span class="mord mathnormal">u</span><span class="mord mathnormal" style="margin-right:0.01968em;">pl</span><span class="mord mathnormal">o</span><span class="mord mathnormal">a</span><span class="mord mathnormal">d</span><span class="mord mathnormal">e</span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.10764em;">f</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2861em;"><span></span></span></span></span></span></span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">p</span><span class="mord mathnormal">a</span><span class="mord mathnormal">t</span><span class="mord mathnormal">hin</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">o</span><span class="mopen">(</span></span></span></span>filename, PATHINFO_FILENAME) . '.' . ALLOWED_FILES[$mime_type];
// new filepath
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mi>i</mi><mi>l</mi><mi>e</mi><mi>p</mi><mi>a</mi><mi>t</mi><mi>h</mi><mo>=</mo><mi>U</mi><mi>P</mi><mi>L</mi><mi>O</mi><mi>A</mi><msub><mi>D</mi><mi>D</mi></msub><mi>I</mi><mi>R</mi><msup><mi mathvariant="normal">.</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><msup><mi mathvariant="normal">/</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">filepath = UPLOAD_DIR . &#x27;/&#x27; . </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span><span class="mord mathnormal">p</span><span class="mord mathnormal">a</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1.0019em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">U</span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mord mathnormal">L</span><span class="mord mathnormal" style="margin-right:0.02778em;">O</span><span class="mord mathnormal">A</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3283em;"><span style="top:-2.55em;margin-left:-0.0278em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.02778em;">D</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="mord"><span class="mord">.</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7519em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mord"><span class="mord">/</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7519em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mord">.</span></span></span></span>uploaded_file;

// move the file to the upload dir
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>s</mi><mi>u</mi><mi>c</mi><mi>c</mi><mi>e</mi><mi>s</mi><mi>s</mi><mo>=</mo><mi>m</mi><mi>o</mi><mi>v</mi><msub><mi>e</mi><mi>u</mi></msub><mi>p</mi><mi>l</mi><mi>o</mi><mi>a</mi><mi>d</mi><mi>e</mi><msub><mi>d</mi><mi>f</mi></msub><mi>i</mi><mi>l</mi><mi>e</mi><mo stretchy="false">(</mo></mrow><annotation encoding="application/x-tex">success = move_uploaded_file(</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">s</span><span class="mord mathnormal">u</span><span class="mord mathnormal">ccess</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1.0361em;vertical-align:-0.2861em;"></span><span class="mord mathnormal">m</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1514em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">u</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord mathnormal" style="margin-right:0.01968em;">pl</span><span class="mord mathnormal">o</span><span class="mord mathnormal">a</span><span class="mord mathnormal">d</span><span class="mord mathnormal">e</span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.10764em;">f</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2861em;"><span></span></span></span></span></span></span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span><span class="mopen">(</span></span></span></span>tmp, $filepath);
if(!$success) {
    <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>e</mi><mi>r</mi><mi>r</mi><mi>o</mi><mi>r</mi><mi>s</mi><mo stretchy="false">[</mo></mrow><annotation encoding="application/x-tex">errors[</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">errors</span><span class="mopen">[</span></span></span></span>filename] = "The file $filename was failed to move.";
}

}

$errors ? redirect_with_message(format_messages('The following errors occurred:',$errors), FLASH_ERROR) : redirect_with_message('All the files were uploaded successfully.', FLASH_SUCCESS);`Code language: PHP (php)

How the upload.php works:

  1. Start a new session or resume an existing one:

session_start();Code language: PHP (php)

  1. Load the code from the flash.php and functions.php:

require_once __DIR__ . '/inc/flash.php'; require_once __DIR__ . '/inc/functions.php';Code language: PHP (php)

Note that you should use the flash.php from the flash message tutorial and functions.php from the file upload tutorial.

Since the upload.php deals with multiple files, it will issue multiple error messages, one for each uploaded file.

To make it convenient, we can define a function that returns a single error message from multiple error messages like this:

`function format_messages(string title,arraytitle, array title,arraymessages): string { message="<p>message = "<p>message="<p>title

"; $message .= '