Upload Display and delete images from the server and the database using PHP

Updated: 23-Feb-2024 / Tags: PHP and MYSQL / Views: 457 - Author: George

Introduction

Hello everyone.
Welcome to a tutorial on uploading, displaying, and deleting images using PHP!
Images are an essential part of many web applications, whether it's showcasing products in an online store, sharing photos in a social media platform, or displaying user avatars on a forum.

In this tutorial you'll learn how to upload images to the server, store their information in a database, retrieve and display them on a web page, and finally, how to implement functionality to delete images when necessary.

The image below illustrates the layout of the application you'll be building in this tutorial.

Image of an upload form and images above it

Starting from the bottom and moving upwards, we have the upload form, followed by the preview container which displays images fetched from the database. Beneath each image, there is a delete button.

Above the preview container, on the left side, we display the total number of images being shown. Lastly, at the top, we display any errors that may occur during the image deletion process.

Now let's see the files and folders we need to code the application.

Project's folder

Create the following files and folders in your localhost server's directory.

/--project-folder
  /-- Uploads/
  |--index.php		
  |--functions.php		
  |--styles.css
  • First of all we need an uploads/ folder to store the uploaded images.
  • We need an index.php file to write the HTML code. We gave the index file a php extension because we will include PHP code in the file.
  • We need a functions.php file to write our PHP functions.
  • And last we have a stylesheet, to define the layout and styling of our application.

The database

Now that you have created the project's file structure, let's create the database.

Image of a database table in phpmyadmin

To create the database follow the steps below.

  1. Create a database, you can use any name you like. You will use the database name to connect to the MySQL server in the php code, and specific in the connect function.
  2. Create a table named 'images'.
  3. Within the images table, create a column named 'id'. Set its type to 'int', index to 'PRIMARY', and ensure to check the 'AUTO INCREMENT' checkbox.
  4. Next create another column named 'image'. Set the type to varchar and the length to 255 characters.
  5. Save the changes, and the database is now ready and waiting to be connected with our PHP code.

The PHP file

In the functions.php file we will write the functions that the application need to work.

  1. We will have a connect() function to establish the connection to the MySQL server and the database.
  2. A function named insertImage() which will insert the image name in the database, and save the image file in the uploads/ folder.
  3. A function named getImages() which will fetch the image names from the database.
  4. And a deleteImage() function which will delete the image name from the database and from the uploads/ folder.
<?php
	function connect(){
		$mysqli = new mysqli('localhost', 'mysql username', 'mysql password', 'database name');
		if($mysqli->connect_errno != 0){
			exit($mysqli->connect_error);
		}
		return $mysqli;
	}

	function insertImage(array $files){
		$mysqli = connect();
		$image_name = $files['image']['name'];
		$image_temp = $files['image']['tmp_name'];

		// Image validation code. IMPORTANT!!

		$mysqli->begin_transaction();

		$mysqli->query("INSERT INTO images(image) VALUES('$image_name')");
		if($mysqli->affected_rows != 1){
			$mysqli->rollback();
			return "Error inserting image in the database";
		}

		if( ! move_uploaded_file($image_temp, "uploads/" . $image_name)){
			$mysqli->rollback();
			return "Error saving the file";
		}

		$mysqli->commit();
		$mysqli->close();

		return "success";
	}

	function getImages(){
		$mysqli = connect();
		$res = $mysqli->query("SELECT id, image FROM images");
		$data = array();
		while($row = $res->fetch_assoc()){
		 	array_push($data, $row);
		}
		return $data;
	}

	function deleteImage(int $id){
		$mysqli = connect();
		$res = $mysqli->query("SELECT id, image FROM images WHERE id = $id");
		$image_name = $res->fetch_assoc()['image'];
		if($image_name == NULL){
			return "Image not found in the database, please try again";
		}

		$mysqli->begin_transaction();
		$mysqli->query("DELETE FROM images WHERE id = '$id'");
		if($mysqli->affected_rows != 1){
			$mysqli->roolback();
			return "Error deleting image from the database, please try again.";
		}

		if(file_exists("uploads/$image_name")){
			if( ! unlink("uploads/$image_name")){
				$mysqli->roolback();
				return "Error deleting image from folder, please try again";
			}
		}

		$mysqli->commit();
		$mysqli->close();
		return header("location: index.php");
	}	
	

Now let's explain the functions that we have in the php file.

  • The Connect Function

    function connect(){
    	$mysqli = new mysqli('localhost', 'mysql username', 'mysql password', 'database name');
    	if($mysqli->connect_errno != 0){
    		exit($mysqli->connect_error);
    	}
    	return $mysqli;
    }
    			

    The 'connect' function is responsible for establishing a connection to a MySQL database. It begins by creating a new instance of the MySQLi class, passing in the necessary parameters: the hostname ('localhost'), the MySQL username, the MySQL password, and the name of the database to connect to.

    Next, it checks if there was an error during the connection attempt by accessing the 'connect_errno' property of the MySQLi object. If the 'connect_errno' is not equal to 0, indicating an error occurred, the function exits, displaying the error message retrieved from the 'connect_error' property of the MySQLi object.

    If the connection is successful and no errors were encountered, the function returns the MySQLi object, allowing the caller to use it for executing database queries and interacting with the database.

  • The Insert Image Function.

    function insertImage(array $files){
    	$mysqli = connect();
    	$image_name = $files['image']['name'];
    	$image_temp = $files['image']['tmp_name'];
    
    	// Image validation code. IMPORTANT!!
    
    	$mysqli->begin_transaction();
    
    	$mysqli->query("INSERT INTO images(image) VALUES('$image_name')");
    	if($mysqli->affected_rows != 1){
    		$mysqli->rollback();
    		return "Error inserting image in the database";
    	}
    
    	if( ! move_uploaded_file($image_temp, "uploads/" . $image_name)){
    		$mysqli->rollback();
    		return "Error saving the file";
    	}
    
    	$mysqli->commit();
    	$mysqli->close();
    
    	return "success";
    }
    			

    The 'insertImage' function takes as an argument an array named '$files' as input. The $files argument will hold the superglobal $_FILES array.

    The function begins by establishing a connection to the MySQL database using the 'connect()' function.

    It then retrieves the name and temporary location of the image file from the '$files' array.

    Before we insert the image name in the database, and save the file to the uploads/ folder, we have to proper validate the image file. We are not validating the file in this tutorial because i want to show you the basics on how to upload, display, and delete an image file from the database. PLEASE do a proper validation if you are going to use this code on a live project.

    Next, in line 17 the function starts a transaction using the 'begin_transaction()' method of the MySQLi object. This means that when an error occurs we can use the rollback() method to reset the database to its previous state.

    The function then inserts the image name into the 'images' table of the database using an SQL INSERT statement. If the insertion is successful (indicated by the 'affected_rows' property of the MySQLi object), the transaction continues. Otherwise, it rolls back the transaction and returns an error message indicating that there was an issue inserting the image into the database.

    After inserting the image name into the database, the function attempts to move the image file from its temporary location to the 'uploads' folder using the 'move_uploaded_file()' function. If this operation fails, the function rolls back the transaction and returns an error message indicating that there was an issue saving the file.

    If both the database insertion and file saving operations are successful, the transaction is committed using the 'commit()' method of the MySQLi object. Finally, the MySQL connection is closed, and the function returns a success message indicating that the image upload was successful.

    To learn how to do a secure image validation check this post -> How to properly validate an uploaded image file using php

  • The Get Images Function

    function getImages(){
    	$mysqli = connect();
    	$res = $mysqli->query("SELECT id, image FROM images");
    	$data = array();
    	while($row = $res->fetch_assoc()){
    	 	array_push($data, $row);
    	}
    	return $data;
    }
    			

    The 'getImages' function is responsible for retrieving image data from the database. It begins by establishing a connection to the MySQL database using the 'connect()' function.

    Next, it executes an SQL SELECT query to retrieve the 'id' and 'image' columns from the 'images' table. The result of this query is stored in the variable '$res'.

    The function then initializes an empty array named '$data' to store the retrieved image data. It enters a while loop, where it iterates over each row of the result set obtained from the query using the 'fetch_assoc()' method.

    For each row, the function pushes an associative array containing the 'id' and 'image' values into the '$data' array using the 'array_push()' function.

    Once all rows have been processed, the function returns the '$data' array containing the retrieved image data.

  • The Delete Image Function

    function deleteImage(int $id){
    	$mysqli = connect();
    	$res = $mysqli->query("SELECT id, image FROM images WHERE id = $id");
    	$image_name = $res->fetch_assoc()['image'];
    	if($image_name == NULL){
    		return "Image not found in the database, please try again";
    	}
    
    	$mysqli->begin_transaction();
    	$mysqli->query("DELETE FROM images WHERE id = '$id'");
    	if($mysqli->affected_rows != 1){
    		$mysqli->roolback();
    		return "Error deleting image from the database, please try again.";
    	}
    
    	if(file_exists("uploads/$image_name")){
    		if( ! unlink("uploads/$image_name")){
    			$mysqli->roolback();
    			return "Error deleting image from folder, please try again";
    		}
    	}
    
    	$mysqli->commit();
    	$mysqli->close();
    	return header("location: index.php");
    }
    			

    The 'deleteImage' function is responsible for deleting an image from both the database and the uploads folder. It takes an integer parameter '$id' representing the ID of the image to be deleted.

    The function begins by establishing a connection to the MySQL database using the 'connect()' function.

    It then executes an SQL SELECT query to retrieve the 'id' and 'image' columns from the 'images' table where the 'id' matches the provided '$id'. The result of this query is stored in the variable '$res'.

    Next, the function extracts the image name from the retrieved row using the 'fetch_assoc()' method and accesses the 'image' column.
    We retrieve the image name from the database because we need the image name to delete the file from the uploads/ folder.

    If the retrieved 'image' value is NULL, indicating that no image was found with the provided ID, the function returns an error message indicating that the image was not found in the database.

    If the image is found in the database, the function begins a database transaction using the 'begin_transaction()' method of the MySQLi object. It then executes an SQL DELETE query to remove the image from the 'images' table where the 'id' matches the provided '$id'.

    If the deletion operation is successful (indicated by the 'affected_rows' property of the MySQLi object), the function proceeds to delete the image file from the 'uploads' folder. It first checks if the file exists using the 'file_exists()' function, and if so, attempts to delete it using the 'unlink()' function.

    If any error occurs during the deletion process (either in the database or in the file system), the function rolls back the database transaction and returns an appropriate error message.

    If both the database deletion and file deletion operations are successful, the database transaction is committed, the MySQL connection is closed, and the function refreshes the page using the header() function.

    We refresh the page to clear the GET request from the browser's URL address bar.

The Index file

In the index.php file we have the HTML code that structures our application, combined with PHP code to make the application functional.
Scroll to the end of the file to get a detailed explanation.

<?php require "functions.php" ?>
<?php
	$response = null;
	$delete_function_response = null;
	if(isset($_POST["upload"])){
		if(isset($_FILES['image']) && $_FILES['image']['name'] != ""){
			$response = insertImage($_FILES);
		}else{
			$response = "Please select an image file";
		}
	}

	if(isset($_GET['delete-image'])){
		$delete_function_response = deleteImage($_GET['id']);
	}
 ?>
	
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<link rel="stylesheet" href="styles.css">
	<title>Upload and display images in PHP</title>
</head>
<body>
	<?php $images = getImages() ?>
	<?php
		if($delete_function_response){
			?>
				<div class="delete-image-error">
					<span>
						<?php echo $delete_function_response ?>
					</span>
					<span>
						<a href="index.php">Dissmis</a>
					</span>
				</div>
			<?php
		}
	?>

	<div class="info">
		Uploaded images <strong><?php echo count($images) ?></strong>
	</div>

	<div class="preview">
		<?php
			foreach ($images as $image) {
				?>
					<div class="image-wrapper">
						<img src="uploads/<?php echo $image['image'] ?>" alt="">
						<a href="?delete-image&id=<?php echo $image['id'] ?>">Delete Image</a>
					</div>
				<?php
			}
		?>
	</div>

	<form action="" method="post" enctype="multipart/form-data">
		<label>Select image to upload</label>
		<input type="file" name="image">

		<button type="submit" name="upload">Upload</button>

		<?php
			if($response == "success"){
				?>
					<p class="success">File uploaded successfully</p>
				<?php
			}else{
				?>
					<p class="error"><?php echo $response ?></p>
				<?php
			}
		?>
	</form>
</body>
</html>
	

Now let's see what is going on in the index.php file.

  • Fetching the POST and GET Request

    <?php require "functions.php" ?>
    <?php
    	$response = null;
    	$delete_function_response = null;
    	if(isset($_POST["upload"])){
    		if(isset($_FILES['image']) && $_FILES['image']['name'] != ""){
    			$response = insertImage($_FILES);
    		}else{
    			$response = "Please select an image file";
    		}
    	}
    
    	if(isset($_GET['delete-image'])){
    		$delete_function_response = deleteImage($_GET['id']);
    	}
     ?>	
    			

    Initially, we require the 'functions.php' file to get access to the functions we've written there.

    Next we initialize two variables, '$response' and '$delete_function_response', to null. These variables will be used to store the response messages from the 'insertImage' and 'deleteImage' functions, respectively.

    We then check if the 'upload' form submission button was clicked by using the 'isset()' function to check if the '$_POST["upload"]' variable is set.

    If it is set, we further check if an image file was selected for upload by using the 'isset()' function to check if the '$_FILES['image']' variable is set and if the file name is not empty.

    If an image file is selected, we call the 'insertImage' function, passing the '$_FILES' array as an argument, and assign the response message to the '$response' variable.

    If no image file is selected, we assign a message to the '$response' variable, prompting the user to select an image file.

    Next, we check if the 'delete-image' parameter is set in the URL query string using the 'isset()' function. If it is set, we call the 'deleteImage' function, passing the image ID from the URL query string as an argument, and assign the response message to the '$delete_function_response' variable.

    This code snippet handles the form submissions for uploading images and deleting images, and stores the response messages from the respective functions for display to the user.

  • Getting the Images from the Database:

    <?php $images = getImages() ?>

    At line 26, we call the 'getImages()' function, retrieving data from the database and storing it in the '$images' array. This variable holds all the rows from the database as an associated array.

  • Handling the Deletion Errors:

    <?php
    	if($delete_function_response){
    		?>
    			<div class="delete-image-error">
    				<span>
    					<?php echo $delete_function_response ?>
    				</span>
    				<span>
    					<a href="index.php">Dissmis</a>
    				</span>
    			</div>
    		<?php
    	}
    ?>
    			

    This PHP code snippet checks if the variable '$delete_function_response' contains a value, indicating that a response message from the 'deleteImage' function is present. If so, it proceeds to display an error message in a styled container.

    Inside the container, the error message retrieved from the '$delete_function_response' variable is echoed within a 'span' element. Additionally, a 'Dismiss' link is provided, allowing users to refresh the 'index.php' page, and hide the error.

    This code segment enhances user experience by providing feedback in case of a deletion error and offering an option to dismiss the message by refreshing the page.

  • Displaying the number of images shown to the user:

    <div class="info">
    	Uploaded images <strong><?php echo count($images) ?></strong>
    </div>
    			

    Here we displaying the total number of images stored in the $images array using the count() function.

  • Displaying the Images:

    <div class="preview">
      <?php
         foreach ($images as $image) {
            ?>
               <div class="image-wrapper">
                  <img src="uploads/<?php echo $image['image'] ?>" alt="">
                  <a href="?delete-image&id=<?php echo $image['id'] ?>">Delete Image</a>
               </div>
            <?php
         }
      ?>
    </div>
    			

    Inside a 'div' element with a class of 'preview', a PHP 'foreach' loop iterates over each image stored in the '$images' array retrieved from the database.

    For each image, a 'div' element with a class of 'image-wrapper' is created. Inside this wrapper, an 'img' element is used to display the image, with the 'src' attribute dynamically set to the file path of the uploaded image retrieved from the database using '$image['image']'.

    Additionally, a 'Delete Image' link is provided, allowing users to delete the respective image. The 'href' attribute of this link is dynamically generated using PHP, appending the image ID to the URL query string as a parameter.

  • The Upload Form:

    <form action="" method="post" enctype="multipart/form-data">
      <label>Select image to upload</label>
      <input type="file" name="image">
    
      <button type="submit" name="upload">Upload</button>
    
      <?php
         if($response == "success"){
            ?>
               <p class="success">File uploaded successfully</p>
            <?php
         }else{
            ?>
               <p class="error"><?php echo $response ?></p>
            <?php
         }
      ?>
    </form>
    			

    Here we have a form for uploading images to the server. The action attribute is left empty, that means that the form will submit the file to the same page. We utilize the 'POST' method to submit the form data, and the 'enctype' attribute is set to 'multipart/form-data' to handle file uploads.

    Within the form, a 'label' element instruct the user to select an image for upload.

    An 'input' element with the 'type' attribute set to 'file' allows users to browse their file system and select an image file. The 'name' attribute of the input is set to 'image' to identify the uploaded file in the PHP code.

    A 'button' element with the 'type' attribute set to 'submit' and the 'name' attribute set to 'upload' is used to submit the form.

    Below the upload button, a PHP conditional statement checks the value of the '$response' variable, which contains the response message from the image upload process.

    If the response is 'success', indicating that the file was uploaded successfully, a success message is displayed within a 'p' element with a class of 'success'.

    Otherwise, an error message is displayed using a 'p' element with a class of 'error', with the error message retrieved from the '$response' variable.

The CSS file

Lastly, we have the CSS file. While I won't go into the specifics of the CSS code here, it contains the styling rules for our application. These rules dictate the layout, appearance, and behavior of the various HTML elements used throughout the webpage.

*{
	margin: 0;
	padding: 0;
	box-sizing: border-box;
}

body{
	font-family: sans-serif;
	min-height: 100%;
	background-color: #33363b;
	width: 90%;
	margin: 50px auto;
}

.delete-image-error{
	background-color: #ffd1d9;
	color: #a02121;
	font-size: 20px;
	padding: 10px;
	margin-bottom: 30px;
	display: flex;
	justify-content: space-between;
}

.delete-image-error a{
	color: inherit;
	text-decoration: none;
}

.info{
	font-size: 24px;
	margin-bottom: 20px;
	color: #fff;
}

.preview{
	min-height: 200px;
	border: thin solid #5c5c5c;
	padding: 30px;
	text-align: center;
	background-color: #212327;
}

.preview .image-wrapper{
	display: inline-block;
	text-align: center;
}

.preview img{
	display: block;
	height: 250px;
	padding: 10px;
}

.preview a{
	display: inline-block;
	color: #fff;
	font-size: 18px;
	text-decoration: none;
	background-color: #bd6070;
	padding: 10px 30px;
	margin-top: 10px;
}

.preview a:hover{
	filter: brightness(1.2);
}

.preview a:active{
	background-color: green;
}

form{
	max-width: 400px;
	margin: 100px auto 0 auto;
	padding: 20px;
	box-shadow: 0 5px 5px rgba(0, 0, 0, 0.2);
	background-color: #fff;
}

form label{
	display: block;
	margin-bottom: 30px;
	padding-left: 5px;
	font-size: 20px;
}

form input{
	display: block;
	width:  100%;
	padding: 10px;
	font-size: 16px;
	border:  thin solid #e4e4e4;
	margin-bottom: 30px;
}

form input:focus{
	outline: none;
}

form textarea{
	min-height: 150px;
}

form button{
	background: #4c566a;
	color: white;
	border: none;
	padding: 15px;
	width:  100%;
	font-size: 20px;
	margin-top: 20px;
	cursor: pointer;
}

form button:hover{
	filter: brightness(1.2);
}

form button:active{
	background-color: green;
}

.error{
	margin-top: 30px;
	color: #af0c0c;
}

.success{
	margin-top: 30px;
	color: green;
}
	

Summary

In this tutorial, we've explored the process of creating a PHP application for uploading, displaying, and deleting images from a database. We began by setting up the necessary files and folders, including the HTML structure, PHP functions, and CSS styling.

We implemented functionalities for uploading images, displaying them on the webpage, and providing options for deleting them. The 'insertImage' function handled the uploading process, ensuring data integrity and error handling. The 'getImages' function retrieved image data from the database, while the 'deleteImage' function managed the deletion process, both from the database and the file system.

Throughout the tutorial, we emphasized the importance of proper validation, although we did not do any, and error handling to enhance the reliability and security of our application. We also provided feedback to the user at each step of the process, ensuring a smooth and intuitive user experience.

Last Words

And that's it. We reached the end of this tutorial.
Thanks for reading, i hope you find the article helpful.

Please leave a comment if you find any errors, so i can update the page with the correct code.

Source code

You can download the source code and use it in any way you like.

Times downloaded: 71

Buy me a coffee

If you like to say thanks, you can buy me a coffee.

Buy me a coffee with paypal

Comment section

You can leave a comment, it will help me a lot.

Or you can just say hi. 😉