Good content takes time and effort to come up with.

Please consider supporting us by just disabling your AD BLOCKER and reloading this page again.







How To Upload Multiple Files In PHP?


FILE VALIDATION FILE UPLOAD PHP
14th May 2020 6 mins read
Share Article     Share On WhatsApp   Buy Me Coffee | StackCoder Buy Coffee


Hello Friends! In this article you will learn how to upload multiple files in PHP.


This article covers


  1. HTML File Upload Page
  2. Database Design To Store The Image Names
  3. Database Connection In PHP
  4. Rearrange Files Data When Form Submitted
  5. Simple Multiple File Upload
  6. File Upload With Validation


NOTE: I have added the complete code in GitHub repository. You can find it here Multiple File Upload

Prerequisites


Basic knowledge of PHP, HTML & I hope you already know how to do file upload if not then refer this article


How To Uploads Files In PHP?

How To Upload Image In PHP?


1) HTML File Upload Page


The following is the basic HTML code for multiple file uploads make sure you have enctype="multipart/form-data" in form tag,  product_images[] is an array in input type=file tag & multiple must be added to input element.


In the following example I would like to upload multiple product images, this might not be the realistic example but hope it servers for your understanding.


<form action="store_product.php" method="post" enctype="multipart/form-data">
    <div>
        <label for="product_images">Select Product</label> <br>
        <!-- 
            Basically you get the product list from database.
            For the sake of demonstration I am hard coding
         -->
        <select name="product_id" id="product_id">
            <option value="1">Product 1</option>
            <option value="2">Product 2</option>
        </select>
    </div> <br>
    <div>
        <label for="product_images">Product Images</label> <br>
        <input type="file" name="product_images[]" id="product_images" multiple>
    </div> <br>
    <div>
        <input type="submit" value="Upload Product Images">
    </div>
</form>

2) Database Design To Store Product & It's Image Names


NOTE: I would like to store the images/files in disk ie., specific path and not in my database. By saving the images or any files as BLOB in database will increase the complexity, consumes lot of space & even reduces the efficiency of CRUD operations.


Following is the simple design of the products & product_images table inside invoice database.


/** Creating database with name invoice */
CREATE DATABASE `invoice`;

/** Once we create we want to switch to invoice so that we can add products table */
USE `invoice`;

/** Products table to hold the products data */
CREATE TABLE `products` (
	`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
	`name` VARCHAR(30),
	`product_invoice` VARCHAR(255),
	PRIMARY KEY (`id`)
);
/** Product Images */
CREATE TABLE `product_images` (
	id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
	product_id INT(11) UNSIGNED NOT NULL,
	product_image VARCHAR(100) NOT NULL,
	PRIMARY KEY (`id`),
	FOREIGN KEY (`product_id`) REFERENCES `products` (`id`)
);


For the sake of demonstration I have the following 2 rows inside products table


INSERT INTO `products` (`id`, `name`, `product_image`)
VALUES
	(1, 'Product 1', '98767461589180160d435607145066fc9c3b5069d336f11a9.jpg'),
	(2, 'Product 2', '61545675589180160d435607145066fc9c3b5069d336f11a9.jpg');

3) Database Connection In PHP


The following is the code to connect to the database which we created above. I am using PDO connection, which is very advanced than mysql or mysqli functions.


<?php
$host           = 'localhost';
$db_name        = 'invoice';
$db_username    = 'root';
$db_password    = 'root';
$dsn            = 'mysql:host='. $host .';dbname='. $db_name;
$options        = [
                    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
                    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
                    PDO::ATTR_EMULATE_PREPARES   => false,
                ];
try {
    /** $pdo is the connection object which I will be using for all my datbase operations */
    $pdo = new PDO($dsn, $db_username, $db_password);
} catch (PDOException $e) {
    exit($e->getMessage());
}

4) Rearrange Files Data When Form Submitted


Once you fill the form and submit you will get somewhat similar to the following output.


store_product.php


Lets debug the form uploaded


echo '<pre>';
print_r($_FILES['product_images']);
exit;


Output


Array
(
    [name] => Array
        (
            [0] => tempro1991266572.png
            [1] => tempro1913737454.png
        )

    [type] => Array
        (
            [0] => image/png
            [1] => image/png
        )

    [tmp_name] => Array
        (
            [0] => /Applications/MAMP/tmp/php/php70g7x1
            [1] => /Applications/MAMP/tmp/php/phppHPzVH
        )

    [error] => Array
        (
            [0] => 0
            [1] => 0
        )

    [size] => Array
        (
            [0] => 874
            [1] => 880
        )

)


Since looping into them and parsing might be difficult lets format the above. In the below code I am just looping the files and just arranging based on keys ie name, tmp_name etc.


function rearrange_files($files)
{
    $file_array = [];
    foreach ($files as $file_key => $file) {
        foreach ($file as $index => $file_value) {
            $file_array[$index][$file_key] = $file_value;
        }
    }
    return $file_array;
}


Using the above function we will get the rearranged files as follows


Array
(
    [0] => Array
        (
            [name] => tempro1991266572.png
            [type] => image/png
            [tmp_name] => /Applications/MAMP/tmp/php/php3YrETt
            [error] => 0
            [size] => 874
        )

    [1] => Array
        (
            [name] => tempro1913737454.png
            [type] => image/png
            [tmp_name] => /Applications/MAMP/tmp/php/phpm1vF67
            [error] => 0
            [size] => 880
        )

)


Ah! This looks clean, very understandable and more easy to work on.


5) Simple Multiple File Upload


Now lets add the bits and pieces to make the basic multiple form upload work


<?php
session_start();
require_once 'db.php';


function rearrange_files($files)
{
    /** above I have added function code  **/
}


if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    /** array variable to hold errors */
    $errors = [];


    $product_id      = $_POST['product_id'];
    $product_images  = $_FILES['product_images'];
    /** Add form validation */
    if (empty($product_images)) {
        $errors[] = 'Product invoice file required';
    }
    if (empty($product_id)) {
        $errors[] = 'Select product you want to add image';
    }
    /** Check if the product exists in your database */
    $product_stmt = $pdo->prepare("
        SELECT
            id, name
        FROM
            `products`
        WHERE
            id = :product_id
    ");

    $product_stmt->execute([
        ':product_id'     => $product_id,
    ]);

    $product = $product_stmt->fetchObject();

    if (!$product) {
        $errors[] = 'Selected product does not exist!';
    }

    /** If there are any form errors then redirect back */
    if (count($errors) > 0) {
        $_SESSION['errors'] = $errors;
        header('Location: index.php');
    }


    /** $_FILES will have the upload file details in PHP */
    $arranged_files = rearrange_files($_FILES['product_images']);
    
    foreach ($arranged_files as $product_image) {
        /** I am using pathinfo to fetch the details of the PHP File */
        $file_name          = $product_image['name'];
        $file_size          = $product_image['size'];
        $file_tmp           = $product_image['tmp_name'];
        $pathinfo           = pathinfo($file_name);
        $extension          = $pathinfo['extension'];
        $file_extensions   = ['pdf', 'xls', 'jpeg', 'jpg', 'png', 'svg', 'webp'];
        
        /** Since I want to rename the File I need its extension
         * which will be obtained with above $phpinfo variable
         * */
        /** generate random inage name */
        $new_file_name = rand(0, 10000000).time().md5(time()).'.'.$extension;

        move_uploaded_file($file_tmp, './uploads/product_images/'. $new_file_name);
        
        $product_image = $pdo->prepare("
            INSERT INTO 
                `product_images` (`product_id`, `product_image`)
            VALUES
                (:product_id, :product_image)
        ")
        ->execute([
            ':product_id'       => $product->id,
            ':product_image'    => $new_file_name,
        ]);
    }
    $_SESSION['success'] = 'Products added successfully';
    header('location: index.php');
    exit;
} else {
    header('location: index.php');
    exit;
}

6) File Upload With Validation


In the above code the validation is not added for all the files while doing upload we can perform simple validation as follows


/** File strict validations */
    
/** File exists */
if (!file_exists($file_tmp)) {
    $errors[] = 'File your trying to upload not exists';
}

/** Check if the was uploaded only */
if (!is_uploaded_file($file_tmp)) {
    $errors[] = 'File not uploaded properly';
}

/** Check for the file size 1024 * 1024 is 1 MB & 1024 KB */
if ($file_size > (1024 * 1024)) {
    $errors[] = 'Uploaded file is greater than 1MB';
}

/** Check File extensions */
if (!in_array($extension, $file_extensions)) {
    $errors[] = 'File allowed extensions '. implode(', ', $file_extensions);
}

if (count($errors) > 0) {
    $_SESSION['errors'] = $errors;
    header('location: index.php');
    exit;
}


The simple validation can be performed within foreach loop as shown below


foreach ($arranged_files as $product_image) {
    /** The above validation code */
}

Conclusion


Hope you got some idea on upload multiple files in PHP.


WHATS NEXT?


You might be interest to learn more on composer please find my whole article on it


How To Upload Image In PHP?

How To Uploads Files In PHP?

How To Install Packages Parallel For Faster Development In Composer

What Is Composer? How Does It Work? Useful Composer Commands And Usage

composer.json v/s composer.lock

Composer Install v/s Composer Update

Route Model Binding In Laravel & Change Default Column id To Another Column

How To Run Raw Queries Securely In Laravel

Laravel 7.x Multiple Database Connections, Migrations, Relationships & Querying

How To Install Apache Web Server On Ubuntu 20.04 / Linux & Manage It

How To Create / Save / Download PDF From Blade Template In PHP Laravel

How To Add Free SSL Certificate In cPanel With ZeroSSL & Certbot

How To Securely SSH Your Server & Push Files With FileZilla

How To Push Files To CPanel / Remote Server using FTP Software FileZilla

How To Install Linux, Apache, MYSQL, PHP (LAMP Stack) on Ubuntu

How To Cache Static Files With NGINX Server

Redirect www to a non-www website or vice versa

How To Create Free SSL Certificate With Lets Encrypt/Certbot In Linux (Single / Multiple Domains)

How To Install Linux, NGINX, MYSQL, PHP (LEMP Stack) on Ubuntu

PHP Built-In Web Server & Testing Your Development Project In Mobile Without Any Software

How To Do Google reCAPTCHA Integration In PHP Laravel Forms


Happy Coding :)








Author Image
AUTHOR

Channaveer Hakari

I am a full-stack developer working at WifiDabba India Pvt Ltd. I started this blog so that I can share my knowledge and enhance my skills with constant learning.

Never stop learning. If you stop learning, you stop growing