Allowing users the option of multiple file upload in PHP is a common feature in many modern applications today. Simply put, multiple file upload refers to a functionality that allows users to select and upload more than one file at once. In a PHP web application, this is typically done using an HTML input
element together with the multiple
attribute and the $_FILES
variable, which is a superglobal available throughout the scope of the script.
When handling file uploads in an application, you often need a way to store those files—whether in the browser, a database, or a cloud service like Cloudinary. If you’re a PHP developer looking to implement multiple file uploads in your application, you’re in the right place. In this tutorial, we’ll walk you through how to implement multiple file uploads and send the data to Cloudinary for storage. If you’re ready, lets get started!
In this article:
- Step 1 – Install Necessary Packages
- Step 2 – Set Up the Page Structure
- Step 3 – Show Selected Files
- Step 4 – Add CSS Styles
- Step 5 – Create Environment Variables
- Step 6 – Handle Multiple File Upload in PHP
- Step 7 – Trying It Out
Step 1 – Install Necessary Packages
In your project directory, run the command below to install the required packages for the application:
composer require cloudinary/cloudinary_php vulcas/phpdotenv
cloudinary/cloudinary_php
: This is the Cloudinary PHP SDK, which allows you to integrate Cloudinary easily with your application. You can use it to effortlessly upload, optimize, transform, upload, and manage your cloud’s assets from within your application.vulcas/phpdotenv
: We can load environment variables and other configurations from.env
files into our applications.
Step 2 – Set Up the Page Structure
Basically, all we need for the page structure is an HTML form with an input element for the type of file
, which indicates that we want to accept only file uploads from the user. After the form is submitted, the data is sent to an upload.php
file, which then processes the submitted files and uploads them to Cloudinary.
Create a file named index.html
in the project root directory and add the following code to it:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Multiple Files Upload</title> <link rel="stylesheet" href="index.css"> </head> <body> <div class="container"> <h1>Multiple Files Upload</h1> <form action="upload.php" method="post" enctype="multipart/form-data"> <div class="file-input"> <input type="file" name="files[]" id="files" multiple> </div> <ul id="fileList"></ul> <button type="submit">Upload Files</button> </form> </div> </body> </html>
In the code above, note the following:
- The
enctype="multipart/form-data"
attribute tells the browser to send each file or data field in the form as a separate part of the request. - The input element’s
type="file"
andmultiple
attributes specify that the browser should accept only file uploads and allow multiple file selections.
Step 3 – Show Selected Files
Presently, there’s no way the user can be sure they selected the correct files they intend to upload. To fix this, we can show a list of the selected files before uploading them using JavaScript.
Before the closing </body>
tag in the HTML code above, add the following JavaScript code:
<script> function displaySelectedFiles() { const fileInput = document.getElementById('files'); const fileList = document.getElementById('fileList'); fileList.innerHTML = ''; const files = fileInput.files; if (files.length > 0) { for (let i = 0; i < files.length; i++) { const listItem = document.createElement('li'); listItem.textContent = files[i].name; fileList.appendChild(listItem); } } else { const isEmpty = document.createElement('li'); isEmpty.textContent = "No files selected."; fileList.appendChild(isEmpty); } } document.getElementById('files').addEventListener('change', displaySelectedFiles); </script>
Step 4 – Add CSS Styles
To style the page, create a file named index.css
in the root directory and add the following code to it:
body { font-family: Arial, sans-serif; background-color: #f5f5f5; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; } .container { background-color: white; padding: 20px; border-radius: 10px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); text-align: center; } h1 { margin-bottom: 20px; color: #333; } .file-input { display: flex; justify-content: center; align-items: center; border: 2px solid #ccc; padding: 20px; margin-bottom: 20px; border-radius: 10px; background-color: #f9f9f9; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); } #files { padding: 10px; border: 1px solid #ccc; border-radius: 5px; cursor: pointer; transition: border-color 0.3s ease, background-color 0.3s ease; } #files:hover { border-color: #007bff; background-color: #e7f3ff; } ul#fileList { list-style-type: auto; padding: 0; margin-top: 10px; } ul#fileList li { padding: 5px; font-size: 14px; color: #555; } button { background-color: #1592df; color: white; padding: 10px 20px; border: none; border-radius: 5px; cursor: pointer; font-size: 16px; transition: background-color 0.3s ease; } button:hover { background-color: #1d4da0; }
Here’s what the result looks like up to this point:
Step 5 – Create Environment Variables
It’s always a good practice to store sensitive information such as API keys and secrets in an .env
file to avoid unwanted access to it by malicious users. Our Cloudinary credentials are sensitive data so we want to avoid hard-coding them directly into our code.
If you don’t have a Cloudinary account yet, feel free to sign up for a free account and get access to your credentials on the Settings > API Keys in your Cloudinary dashboard.
To do this, create a .env
file in the project root and update it as follows:
CLOUDINARY_CLOUD_NAME='<YOUR_CLOUD_NAME>' CLOUDINARY_API_KEY='YOUR_API_KEY>' CLOUDINARY_API_SECRET='YOUR_API_SECRET>'
Step 6 – Handle Multiple File Upload in PHP
When the user submits the form, we need to process the files and make sure they uploaded the right type of files before sending them to Cloudinary for storage.
Create a file named upload.php
and add the following code to it:
<?php require 'vendor/autoload.php'; use Cloudinary\Cloudinary; use Cloudinary\Api\Upload\UploadApi; use Cloudinary\Configuration\Configuration; use Dotenv\Dotenv; // Load the environment variables from .env file $dotenv = Dotenv::createImmutable(__DIR__); $dotenv->load(); // Set up Cloudinary configuration Configuration::instance([ 'cloud' => [ 'cloud_name' => $_ENV['CLOUDINARY_CLOUD_NAME'], 'api_key' => $_ENV['CLOUDINARY_API_KEY'], 'api_secret' => $_ENV['CLOUDINARY_API_SECRET'] ], 'url' => [ 'secure' => true ] ]); $uploadedFiles = []; $errors = []; // Check if files were uploaded if (isset($_FILES['files'])) { foreach ($_FILES['files']['tmp_name'] as $key => $tmpName) { // Check for upload errors if ($_FILES['files']['error'][$key] == UPLOAD_ERR_OK) { try { // Upload the file to Cloudinary $uploadResult = (new UploadApi())->upload($tmpName, [ 'public_id' => pathinfo($_FILES['files']['name'][$key], PATHINFO_FILENAME), 'overwrite' => true, 'resource_type' => 'image' ]); $uploadedFiles[] = $uploadResult['secure_url']; } catch (Exception $e) { $errors[] = "Error uploading " . $_FILES['files']['name'][$key] . ": " . $e->getMessage(); } } else { $errors[] = "Error with file " . $_FILES['files']['name'][$key] . ": " . $_FILES['files']['error'][$key]; } } } ?>
Next, let’s add dynamic HTML to show the results of the file upload and error messages, if any. Still inside the upload.php
file, add the code below just below the closing PHP tag:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Upload Results</title> <link rel="stylesheet" href="index.css"> </head> <body> <div class="container"> <h1>Upload Results</h1> <?php // Display uploaded files if (count($uploadedFiles) > 0) { echo "<h2>File upload successful:</h2>"; echo "<ul>"; foreach ($uploadedFiles as $url) { echo "<li><a href='$url' target='_blank'>$url</a></li>"; } echo "</ul>"; } if (count($errors) > 0) { echo "<h2>Errors:</h2>"; echo "<ul>"; foreach ($errors as $error) { echo "<li class='error'>$error</li>"; } echo "</ul>"; } if (count($uploadedFiles) == 0 && count($errors) == 0) { echo "<p>No files were selected for upload.</p>"; } ?> <a href="index.html"><button>Back to Upload Form</button></a> </div> </body> </html>
Step 7 – Trying It Out
Now, let’s see the result of our code so far. Select more than one file of your choice, and you should see them listed as shown below:
Next, click the Upload Files button, then after a brief moment, you should be taken to a page showing the Cloudinary URLs of the uploaded files:
Managing Multiple File Upload in PHP
Congratulations if you made it this far! In this article, we covered how to implement multiple file uploads in a PHP application and upload the files to Cloudinary, a cloud-based media asset management solution.
Apart from storing your application data, there’s so much more you can do with Cloudinary. To get started, sign up for a free account today to enjoy the world-class features and flexibility that Cloudinary has to offer.