In this PHP tutorial, we will develop an application using which users can upload an image, preview the image before upload, and delete the image after upload using PHP, Ajax and MySQL without reloading the page.
In this PHP tutorial, we will develop an application using which users can upload an image, preview the image before upload, and delete the image after upload using PHP, Ajax and MySQL without reloading the page.
The folders and files we will be using:
We will use the 'upload_img' folder under 'xampp/htdocs' for this application.
dbconnect.php
in the 'cfg' folder to connect to the MySQL database.index.php
is the page to upload the images. The user can upload, view and delete images using this page.upload_image.php
is the PHP program called by Ajax. This PHP program is used to upload, delete and display images.We will create a table named 'images' in a MySQL database. We will be using the "test" database. Table structure and create table scripts are given below:
Table: images
This table stores the file names of all uploaded images along with the upload date.
The table has 3 columns.
images.sql
CREATE TABLE `images` (
`id` int(11) NOT NULL,
`image_file` varchar(255) NOT NULL,
`upload_dt` datetime NOT NULL DEFAULT current_timestamp()
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `images`
ADD PRIMARY KEY (`id`);
ALTER TABLE `images`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=1;
After you create the table, please verify if the structure is the same as above.
Use the below script to connect to the database. We will include this script in other PHP programs to connect to the database.
dbconnect.php
<?php
$server="localhost";
$userid="root";
$pwd="";
$dbname="test";
$conn = new mysqli($server, $userid, $pwd, $dbname);
//Check connection
if ($conn->connect_error)
die("Connection Error: " . $conn->connect_error);
We will use the "localhost" server and the "root" user to connect to the "test" database in MySQL.
You can also read the topic How to connect to MySQL database in PHP using MySQLi and PDO.
Our upload page will look like below. Once an image is uploaded, it will be displayed under the "Uploaded Images" section. The user can delete an uploaded image by clicking on the 'x' button on the top right corner of an image. Also, the user can click on an image and view it in a modal.
The user can click on the "Select an Image" button and select an image. Once an image is selected, a preview of the image will be displayed. A JavaScript function previewImg()
is called on the onChange event of the image field to preview the image before upload.
Below is the code for index.php
. Note that the modal is also included in it.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Upload Image in PHP using Ajax</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.min.js"></script>
<script src="js/upload.js"></script>
</head>
<body>
<?php
include "cfg/dbconnect.php";
?>
<div class="container">
<h1>Upload Image in PHP using Ajax</h1>
<form id ="uploadFrm" action="" method="post">
<div class="mb-3">
<label for="image" class="form-label">Select an Image</label>
<input type="file" class="form-control" name="image" id="image" aria-describedby="fileHelpId" onchange="previewImg(this)" />
<div id="fileHelpId" class="form-text">Allowed file types: jpg,jpeg,png,gif. Max size 4M.</div>
</div>
<div class ="imgPreview">
<!-- Image Preview -->
</div>
<button type="submit" class="btn btn-primary">Upload</button>
</form>
<div class="text-danger" id="errMsg"></div>
<div class="text-success" id="succMsg"></div>
<h2>Uploaded Images</h2>
<div class="image-list">
<?php include "image_list.php";?>
</div>
</div>
<!-- Modal to display image -->
<div class="modal fade" id="modalId" tabindex="-1" role="dialog" aria-labelledby="modalTitleId" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modalTitleId">Image</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<!-- Display the image here -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</body>
</html>
In the above code, we display all the uploaded images by selecting from the "images" table. We have included image_list.php
in line 36 above and it is given below:
<?php
$sql = "select * from images order by id desc";
$stmt = $conn->prepare($sql);
$stmt->execute();
$result = $stmt->get_result();
?>
<div class="show-image">
<?php
if ($result->num_rows > 0){
foreach($result as $row){ ?>
<a class="view" href="javascript:void(0)" data-bs-toggle="modal" data-bs-target="#modalId" data-id="<?= $row['image_file']?>" > <img src="<?php echo "uploads/".$row['image_file']?>"></a>
<button class="btn btn-danger" title="Delete this image" onclick="deleteImg('<?=$row['id']?>','<?=$row['image_file'] ?>')">×</button>
<?php
}
}
else {?>
<p>No Images to display</p>
<?php } ?>
</div>
On clicking the delete button, deleteImg()
JavaScript function is called to delete the image.
Let us now see the JavaScript functions in upload.js
file.
This function is called as soon as the user selects an image. This function displays the preview of the image.
function previewImg(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
$(".imgPreview").css('background-image', 'url(' + e.target.result + ')');
}
reader.readAsDataURL(input.files[0]);
}
}
When the image file is selected, we create a FileReader object and use its onLoad event to set the background with the created image URL.
We will write the Ajax script after submitting the form. We will run a php program (upload_image.php
) with the image file as a parameter, this php program uploads the image. Let's see the Ajax code:
$(document).on("submit", "#uploadFrm", function(e){
e.preventDefault();
$("#errMsg").html('');
$("#succMsg").html('');
if ($("#image").val() !='') {
var formData = new FormData(this);
$.ajax({
type:"POST",
url:"upload_image.php",
data:formData,
contentType: false,
processData: false,
success: function(response){
if (response.indexOf("Error") >= 0)
$("#errMsg").html(response);
else{
$(".image-list").html(response);
$("#image").val('');
$(".imgPreview").css('background-image','');
$("#succMsg").html('Image uploaded successfully');
}
}
});
}
else
$("#errMsg").html("Please select an image file");
} );
We are creating an instance of FormData()
and sending it with the Ajax request. We have to use contentType
as false
as there is a file in the form and also processData
should be false
as we are sending a form.
upload_image.php
returns a message with "Error" in the message. So, we are checking this in the success function. In case, there is no error, we are refreshing the list of uploaded images using $(".image-list").html(response);
Let us see the code for upload_image.php
.
upload_image.php
is used to upload, delete and display images. Let us see the upload section of upload_image.php
.
include "cfg/dbconnect.php";
$target_dir = "uploads/";
$valid_ext = array('jpg','jpeg','png','gif');
if (isset($_FILES['image']) && $_FILES['image']['name'] != ''){
$image_file = $_FILES['image']['name'];
$image_tmp = $_FILES['image']['tmp_name'];
$image_size = $_FILES['image']['size'];
$ext = strtolower(pathinfo($image_file,PATHINFO_EXTENSION));
if (in_array($ext, $valid_ext)){ // valid extension
if (exif_imagetype($image_tmp) == IMAGETYPE_JPEG || exif_imagetype($image_tmp) == IMAGETYPE_GIF || exif_imagetype($image_tmp) == IMAGETYPE_PNG) { // it is an image file
if ($_FILES['image']['size'] <= 4000000) { // size max 4M
$file_name = time()."-".basename($image_file);
try{
move_uploaded_file($image_tmp, $target_dir.$file_name);
try{
$sql = "insert into images (image_file) values( ? )";
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $file_name);
$stmt->execute();
include "image_list.php";
}
catch(Exception $e){
if (file_exists($target_dir.$file_name))
unlink($target_dir.$file_name);
echo ("Error ".$e->getMessage());
}
}
catch(Exception $e){
echo ("Error ".$e->getMessage());
}
}
else{
echo "Error: Image size exceeds 4M";
}
}
else{
echo "Error: Not a valid image file";
}
}
else{
echo "Error: Not an acceptable file extension";
}
}
We are using three validations for the image - image file extension, image size and check if the file is an image file. The image is uploaded and added to the database only when all the validations are successful. If the database insert fails, we have to remove the uploaded file. That is why, we used the unlink()
function to remove the image file.
Note that we are using the target directory as "uploads". When upload and database insert are successful, we refresh the uploaded images in line 21.
This function is called when the user clicks on the delete (x) button from the top right corner of an image. The function executes Ajax scripts and requests to run upload_image.php
which deletes the image from the database and the server folder ('uploads' in our case). The below code is written in upload.js
for this function.
function deleteImg(id,image_file){
$("#errMsg").html('');
$("#succMsg").html('');
if (confirm("Are you sure you want to delete the image?")){
$.ajax({
type:"POST",
url:"upload_image.php",
data:{id:id,image_file:image_file, delete:true},
success:function(response){
$(".image-list").html(response);
$("#succMsg").html('Image deleted successfully');
}
});
}
}
We are using the same PHP program in Ajax. Note that there is a delete flag in the data parameter.
Let's see the code for the delete image section of upload_image.php
.
// delete image from database and from the server
if (isset($_POST['delete'])){
$id = $_POST['id'];
$image_file = $_POST['image_file'];
$sql = "delete from images where id = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param('i',$id);
$stmt->execute();
if (file_exists($target_dir.$image_file))
unlink($target_dir.$image_file);
include "image_list.php";
}
We delete the image from the database and the 'uploads' folder. Then we refresh the uploaded images.
Lastly, we will display the image in a Bootstrap modal when the user clicks on the image.
// To display image in modal
$(document).on("click", ".view", function(){
var image = $(this).data('id');
var str = '<img src="uploads/'+image+'">';
$(".modal-body").html(str);
});
We need to add some styles. Simple and basic styles are used here. You can always add better styles. We have already added style.css
in index.php
. See below:
style.css
h1,h2{
text-align: center;
margin-bottom: 30px;
}
body{
width: 60%;
margin: auto;
}
.imgPreview{
background-image: url('../img/avatar.png');
width: 16%;
height: 145px;
border-radius: 5%;
background-size: cover;
background-position: center;
margin-bottom: 30px;
}
.show-image img{
width:20%;
height:30%;
}
.show-image .btn{
position: relative;
top: -36px;
left: -45px;
}
.modal-content{
width:700px;
}
.modal-body img{
width: 100%;
}
Apache and MySQL services should be running in your XAMPP control panel. Run localhost/upload_img in the browser. You will see the home page as displayed.
Upload an image and you should see the uploaded image displayed. Click on the image and it should open in a modal. Upload another image and try to delete one of the images.
For uploading images, you must verify the below parameters in php.ini
file. Below are the values set for these parameters in my php.ini
; Whether to allow HTTP file uploads.
; http://php.net/file-uploads
file_uploads=On
; Maximum allowed size for uploaded files.
; http://php.net/upload-max-filesize
upload_max_filesize=40M
; Maximum number of files that can be uploaded via a single request
max_file_uploads=20
In this Ajax image upload tutorial, we have discussed how to preview, upload and delete an image using Ajax without submitting a form. If you find it useful, you can use it in your project or any other web application for a similar requirement.
Post a Comment