
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.
Hello Friends! In this article you will learn how to upload multiple files in PHP.
This article covers
NOTE: I have added the complete code in GitHub repository. You can find it here Multiple File Upload
Basic knowledge of PHP, HTML & I hope you already know how to do file upload if not then refer this article
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>
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');
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());
}
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.
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;
}
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 */
}
Hope you got some idea on upload multiple files in PHP.
Simple Way To Create Resourceful API Controller In Laravel
Securely Connect Server MYSQL DB From Sequel Pro / MYSQL Workbench
Make Laravel Controllers Slim By Skimming Form Validation Request
Client-Side Form Validation With Javascript
Lazy Load Images In Chrome With This Simple Trick
Dependency Dropdowns With Javascript And PHP
Increase Session Timeout In Laravel
Why You Should Run Cronjobs In Laravel?
Manipulate HTML Using DOMDocument In PHP
Free SSL Certificate For CPanel