CRUD Operations with Multiple Images in PHP

CRUD operations are the most used functionality in the web application managed dynamically. The add, edit, and delete functionality helps to manage data with the database on the website. You can integrate CRUD operations with PHP to perform create (insert), read (select), update, and delete operations. If your web application works with images, CRUD functionality can be used to manage the images. In this tutorial, we will show you how to integrate CRUD operations with multiple images in PHP.

In this example script, we will create product management system with images using PHP. The user can add, edit, update, and delete products with multiple images in PHP. This system will be very useful for uploading multiple images for each product. The product data will be inserted in the database and the images will be uploaded to the server using PHP and MySQL.

The following operations will be implemented to create a CRUD application with multiple images in PHP.

  • Fetch all the existing records from the database and list them on the web page.
  • Add and insert input data in the database.
  • Upload multiple images to the server and store info in the database.
  • Edit and update records in the database.
  • Delete records and images from the database.

Before getting started to build product management system with multiple images, look at the file structure.

crud_with_multiple_images_in_php/
├── index.php
├── details.php
├── addEdit.php
├── postAction.php
├── ajax_request.php
├── DB.class.php
├── uploads/
└── css/
    ├── style.css
    └── bootstrap.min.css

Create Database Table

We will create two tables to store the product information and images in the database.

1. The following SQL creates a products table with some basic fields in the MySQL database.

CREATE TABLE `products` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL,
  `description` text DEFAULT NULL,
  `created` datetime NOT NULL DEFAULT current_timestamp(),
  `modified` datetime DEFAULT NULL,
  `status` tinyint(4) NOT NULL DEFAULT 1,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

2. The following SQL creates a product_images table with the parent product identifier field (product_id) in the MySQL database.

CREATE TABLE `product_images` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `product_id` int(11) NOT NULL,
  `file_name` varchar(255) NOT NULL,
  `created` datetime NOT NULL DEFAULT current_timestamp(),
  PRIMARY KEY (`id`),
  KEY `product_id` (`product_id`),
  CONSTRAINT `product_images_ibfk_1` FOREIGN KEY (`product_id`) REFERENCES `products` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Configuration File (config.php)

In this config.php file, database and upload related setting variables are defined.

  • DB_HOST – Database host.
  • DB_USERNAME – Database username.
  • DB_PASSWORD – Database password.
  • DB_NAME – Database name.
  • $uploadDir – Folder path to store the uploaded images.
  • $allowTypes – File types allowed to upload.
<?php 

// Database settings
define('DB_HOST''localhost');
define('DB_USERNAME''root');
define('DB_PASSWORD''root');
define('DB_NAME''codexworld_db');

// Upload settings
$uploadDir 'uploads/';
$allowTypes = array('jpg','png','jpeg','gif');

// Start session
if(!session_id()){
    
session_start();
}

?>

Database Class (DB.class.php)

The DB class handles all the database related operations (connect, insert, update, delete, etc).

  • __construct() – Connect to the database with PHP and MySQLi Extension.
  • getRows() – Fetch records from the database based on the specified conditions.
  • get_image_row() – Fetch a single image record from the database based on a specific ID.
  • insert() – Insert data into the database.
  • insert_image() – Insert image data into the database.
  • update() – Update data in the database.
  • delete() – Delete data from the database.
  • delete_images() – Delete images from the database.
<?php 
/*
 * DB Class
 * This class is used for database related (connect, insert, update, and delete) operations
 * @author    CodexWorld.com
 * @url        http://www.codexworld.com
 * @license    http://www.codexworld.com/license
 */
include_once 'config.php'// Include configuration file
class DB{
    private 
$dbHost     DB_HOST;
    private 
$dbUsername DB_USERNAME;
    private 
$dbPassword DB_PASSWORD;
    private 
$dbName     DB_NAME;
    private 
$proTbl     'products';
    private 
$imgTbl     'product_images';
    
    public function 
__construct(){
        if(!isset(
$this->db)){
            
// Connect to the database
            
$conn = new mysqli($this->dbHost$this->dbUsername$this->dbPassword$this->dbName);
            if(
$conn->connect_error){
                die(
"Failed to connect with MySQL: " $conn->connect_error);
            }else{
                
$this->db $conn;
            }
        }
    }
    
    
/*
     * Returns rows from the database based on the conditions
     * @param array select, where, order_by, limit and return_type conditions
     */
    
public function getRows($conditions = array()){
        
$sql "SELECT ";
        
$sql .= array_key_exists("select"$conditions)?$conditions['select']:"P.*,I.file_name";
        
$sql .= " FROM {$this->proTbl} AS P";
        
$sql .= " LEFT JOIN {$this->imgTbl} AS I ON (I.product_id = P.id AND I.id = (SELECT MAX(id) FROM product_images WHERE product_id=P.id)) ";

        if(
array_key_exists("where"$conditions)){
            
$sql .= " WHERE ";
            
$i 0;
            foreach(
$conditions['where'] as $key => $value){
                
$pre = ($i 0)?" AND ":'';
                
$alias_key strpos($key'.') !== false?$key:"P.$key";
                
$sql .= $pre."$alias_key = '".$value."'";
                
$i++;
            }
        }
        
        if(
array_key_exists("order_by"$conditions)){
            
$sql .= " ORDER BY P.{$conditions['order_by']} "
        }else{
            
$sql .= " ORDER BY P.id DESC ";
        }
        
        if(
array_key_exists("start"$conditions) && array_key_exists("limit"$conditions)){
            
$sql .= " LIMIT {$conditions['start']},{$conditions['limit']}"
        }elseif(!
array_key_exists("start"$conditions) && array_key_exists("limit"$conditions)){
            
$sql .= " LIMIT {$conditions['limit']}"
        }
        
        
$result $this->db->query($sql);
        
        if(
array_key_exists("return_type"$conditions) && $conditions['return_type'] != 'all'){
            switch(
$conditions['return_type']){
                case 
'count':
                    
$data $result->num_rows;
                    break;
                case 
'single':
                    
$data $result->fetch_assoc();
                    if(!empty(
$data['id'])){
                        
$data['images'] = array();

                        
$sub_query "SELECT * FROM {$this->imgTbl} WHERE product_id={$data['id']} ORDER BY id DESC";
                        
$sub_result $this->db->query($sub_query);
                        if(
$sub_result->num_rows 0){
                            while(
$img_row $sub_result->fetch_assoc()){
                                
$data['images'][] = $img_row;
                            }
                        }
                    }
                    break;
                default:
                    
$data '';
            }
        }else{
            if(
$result->num_rows 0){
                while(
$row $result->fetch_assoc()){
                    
$data[] = $row;
                }
            }
        }
        return !empty(
$data)?$data:false;
    }

    public function 
get_image_row($id){
        
$sql "SELECT * FROM {$this->imgTbl} WHERE id=$id";
        
$result $this->db->query($sql);
        return 
$result->num_rows 0?$result->fetch_assoc():false;
    }
    
    
/*
     * Insert data into the database
     * @param array the data for inserting into the table
     */
    
public function insert($data){
        if(!empty(
$data) && is_array($data)){
            
$columns '';
            
$values  '';
            
$i 0;
            if(!
array_key_exists('created',$data)){
                
$data['created'] = date("Y-m-d H:i:s");
            }
            if(!
array_key_exists('modified',$data)){
                
$data['modified'] = date("Y-m-d H:i:s");
            }
            foreach(
$data as $key=>$val){
                
$pre = ($i 0)?', ':'';
                
$columns .= $pre.$key;
                
$values  .= $pre."'".$this->db->real_escape_string($val)."'";
                
$i++;
            }
            
$query "INSERT INTO {$this->proTbl} ($columns) VALUES ($values)";
            
$insert $this->db->query($query);
            return 
$insert?$this->db->insert_id:false;
        }else{
            return 
false;
        }
    }

    public function 
insert_image($data){
        if(!empty(
$data) && is_array($data)){
            
$columns '';
            
$values  '';
            
$i 0;
            if(!
array_key_exists('created',$data)){
                
$data['created'] = date("Y-m-d H:i:s");
            }
            foreach(
$data as $key=>$val){
                
$pre = ($i 0)?', ':'';
                
$columns .= $pre.$key;
                
$values  .= $pre."'".$this->db->real_escape_string($val)."'";
                
$i++;
            }
            
$query "INSERT INTO {$this->imgTbl} ($columns) VALUES ($values)";
            
$insert $this->db->query($query);
            return 
$insert?$this->db->insert_id:false;
        }else{
            return 
false;
        }
    }
    
    
/*
     * Update data into the database
     * @param array the data for updating into the table
     * @param array where condition on updating data
     */
    
public function update($data$conditions){
        if(!empty(
$data) && is_array($data)){
            
$colvalSet '';
            
$whereSql '';
            
$i 0;
            if(!
array_key_exists('modified',$data)){
                
$data['modified'] = date("Y-m-d H:i:s");
            }
            foreach(
$data as $key=>$val){
                
$pre = ($i 0)?', ':'';
                
$colvalSet .= $pre.$key."='".$this->db->real_escape_string($val)."'";
                
$i++;
            }
            if(!empty(
$conditions)&& is_array($conditions)){
                
$whereSql .= " WHERE ";
                
$i 0;
                foreach(
$conditions as $key => $value){
                    
$pre = ($i 0)?" AND ":'';
                    
$whereSql .= $pre.$key." = '".$value."'";
                    
$i++;
                }
            }
            
$query "UPDATE {$this->proTbl} SET $colvalSet $whereSql";
            
$update $this->db->query($query);
            return 
$update?$this->db->affected_rows:false;
        }else{
            return 
false;
        }
    }
    
    
/*
     * Delete data from the database
     * @param array where condition on deleting data
     */
    
public function delete($conditions){
        
$whereSql '';
        if(!empty(
$conditions)&& is_array($conditions)){
            
$whereSql .= " WHERE ";
            
$i 0;
            foreach(
$conditions as $key => $value){
                
$pre = ($i 0)?" AND ":'';
                
$whereSql .= $pre.$key." = '".$value."'";
                
$i++;
            }
        }
        
$query "DELETE FROM {$this->proTbl} $whereSql";
        
$delete $this->db->query($query);
        return 
$delete?true:false;
    }

    public function 
delete_images($conditions){
        
$whereSql '';
        if(!empty(
$conditions)&& is_array($conditions)){
            
$whereSql .= " WHERE ";
            
$i 0;
            foreach(
$conditions as $key => $value){
                
$pre = ($i 0)?" AND ":'';
                
$whereSql .= $pre.$key." = '".$value."'";
                
$i++;
            }
        }
        
$query "DELETE FROM {$this->imgTbl} $whereSql";
        
$delete $this->db->query($query);
        return 
$delete?true:false;
    }
}

Bootstrap Library

The Bootstrap 5 library is used to design the table, list, form fields, and links. Include the CSS file of the Bootstrap library, or omit it if you don’t want to use Bootstrap.

<link rel="stylesheet" href="css/bootstrap.min.css">

Product Listing (index.php)

Initially, all the products are retrieved from the database and listed in a tabular format with the view, add, edit, and delete buttons.

  • The View link allows you to view the selected product details with associated images.
  • The Add link allows you to add product information with multiple images.
  • The Edit link allows you to update product info and upload/delete images.
  • The Delete link allows you to delete product data and images from the database.
  • The Status badge (Active/Inactive) allows for controlling the visibility of the products.
<?php 
// Include and initialize DB class
require_once 'DB.class.php';
$db = new DB();

// Fetch existing records from database
$products $db->getRows();

// Get session data
$sessData = !empty($_SESSION['sessData'])?$_SESSION['sessData']:'';

// Get status message from session
if(!empty($sessData['status']['msg'])){
    
$statusMsg $sessData['status']['msg'];
    
$statusMsgType $sessData['status']['type'];
    unset(
$_SESSION['sessData']['status']);
}
?> <!-- Display status message --> <?php if(!empty($statusMsg)){ ?> <div class="col-xs-12"> <div class="alert alert-<?php echo $statusMsgType; ?>"><?php echo $statusMsg; ?></div> </div> <?php ?> <div class="row"> <div class="col-md-12 head"> <h5 class="float-start">Products</h5> <!-- Add link --> <div class="float-end"> <a href="addEdit.php" class="btn btn-success"><i class="plus"></i> New Product</a> </div> </div> <!-- List the products --> <table class="table table-striped table-bordered"> <thead class="thead-dark"> <tr> <th width="2%">#</th> <th width="10%"></th> <th width="20%">Title</th> <th width="30%">Description</th> <th width="15%">Created</th> <th width="8%">Status</th> <th width="15%">Action</th> </tr> </thead> <tbody>             <?php
            
if(!empty($products)){
                foreach(
$products as $row){
                    
$statusLink = ($row['status'] == 1)?'postAction.php?action_type=block&id='.$row['id']:'postAction.php?action_type=unblock&id='.$row['id'];
                    
$statusTooltip = ($row['status'] == 1)?'Click to Inactive':'Click to Active';
            
?> <tr> <td><?php echo $row['id']; ?></td> <td class="text-center"> <?php if(!empty($row['file_name'])){ ?> <img src="<?php echo $uploadDir.$row['file_name']; ?>" width="120" /> <?php ?> </td> <td><?php echo $row['title']; ?></td> <td>                     <?php 
                    $description 
strip_tags($row['description']);
                    echo (
strlen($description)>140)?substr($description0140).'...':$description;
                    
?> </td> <td><?php echo $row['created']; ?></td> <td><a href="<?php echo $statusLink?>" title="<?php echo $statusTooltip?>"><span class="badge text-bg-<?php echo ($row['status'] == 1)?'success':'danger'?>"><?php echo ($row['status'] == 1)?'Active':'Inactive'?></span></a></td> <td> <a href="details.php?id=<?php echo $row['id']; ?>" class="btn btn-primary">view</a> <a href="addEdit.php?id=<?php echo $row['id']; ?>" class="btn btn-warning">edit</a> <a href="postAction.php?action_type=delete&id=<?php echo $row['id']; ?>" class="btn btn-danger" onclick="return confirm('Are you sure to delete record?')?true:false;">delete</a> </td> </tr> <?php } }else{ ?> <tr><td colspan="7">No record(s) found...</td></tr> <?php ?> </tbody> </table> </div>

Product Details with Multiple Images (details.php)

In the details.php file, the selected product information is displayed.

  • Fetch the product data based on the ID passed in the URL query string.
  • List all the associated images in grid view with the Delete link.
  • The Delete button triggers the deleteImage() function and the respective image is removed from the associated product via Ajax HTTP request with JavaScript.
<?php 
// Include and initialize DB class
require_once 'DB.class.php';
$db = new DB();

// If record ID is available in the URL
if(!empty($_GET['id'])){
    
// Fetch data from the database
    
$conditions['where'] = array(
        
'id' => $_GET['id']
    );
    
$conditions['return_type'] = 'single';
    
$proData $db->getRows($conditions);
}else{
    
// Redirect to listing page
    
header("Location: index.php");
    exit();
}
?> <div class="row align-items-start col-md-6"> <div class="col col-md-12"> <h5 class="float-start">Product Details</h5> <div class="float-end"> <a href="index.php" class="btn btn-secondary"><-- Back</a> </div> </div> <div class="col col-md-12"> <div class="mb-3"> <label class="form-label">Title</label> <p><?php echo !empty($proData['title'])?$proData['title']:''?></p> </div> <div class="mb-3"> <label class="form-label">Description</label> <p><?php echo !empty($proData['description'])?$proData['description']:''?></p> </div> <div class="mb-3"> <label class="form-label">Images</label> <?php if(!empty($proData['images'])){ ?> <div class="image-grid"> <?php foreach($proData['images'] as $imageRow){ ?> <div class="img-bx" id="imgbx_<?php echo $imageRow['id']; ?>"> <img src="<?php echo $uploadDir.$imageRow['file_name']; ?>" width="120"/> <a href="javascript:void(0);" class="badge text-bg-danger" onclick="deleteImage(<?php echo $imageRow['id']; ?>)">delete</a> </div> <?php ?> </div> <?php ?> </div> <div class="mb-3"> <label class="form-label">Status</label> <p><?php echo $proData['status'] == 1?'<span class="badge text-bg-success">Active</span>':'<span class="badge text-bg-danger">Inactive</span>'?></p> </div> </div> </div>

Product Data Add/Edit and Multiple Images Upload Form (addEdit.php)

The addEdit.php file contains the HTML form that allows the user to input product info and select multiple image files.

  • Initially, the form data is submitted to the PHP script (postAction.php) to upload multiple images and insert form data in the database.
  • If the ID parameter exists on the URL,
    • The existing product data is retrieved from the database.
    • The data is pre-filled in the input fields and images are listed under the file upload field.
    • The data is submitted to the PHP script (postAction.php) to update the existing record in the database and upload new images to the server.
<?php 
// Include and initialize DB class
require_once 'DB.class.php';
$db = new DB();

$postData $proData = array();

// Get session data
$sessData = !empty($_SESSION['sessData'])?$_SESSION['sessData']:'';

// Get status message from session
if(!empty($sessData['status']['msg'])){
    
$statusMsg $sessData['status']['msg'];
    
$statusMsgType $sessData['status']['type'];
    unset(
$_SESSION['sessData']['status']);
}

// Get posted data from session
if(!empty($sessData['postData'])){
    
$postData $sessData['postData'];
    unset(
$_SESSION['sessData']['postData']);
}

// Fetch data from the database
if(!empty($_GET['id'])){
    
$conditions['where'] = array(
        
'id' => $_GET['id']
    );
    
$conditions['return_type'] = 'single';
    
$proData $db->getRows($conditions);
}

// Pre-filled data
$proData = !empty($postData)?$postData:$proData;

// Define action
$actionLabel = !empty($_GET['id'])?'Edit':'Add';
?> <div class="row align-items-start col-md-6"> <div class="col col-md-12"> <h5 class="float-start"><?php echo $actionLabel?> Product</h5> <div class="float-end"> <a href="index.php" class="btn btn-secondary"><-- Back</a> </div> </div> <!-- Display status message --> <?php if(!empty($statusMsg)){ ?> <div class="col col-md-12"> <div class="alert alert-<?php echo $statusMsgType?>"><?php echo $statusMsg?></div> </div> <?php ?> <div class="col col-md-12"> <form method="post" action="postAction.php" enctype="multipart/form-data"> <div class="mb-3"> <label class="form-label">Title</label> <input type="text" name="title" class="form-control" placeholder="Enter title" value="<?php echo !empty($proData['title'])?$proData['title']:''?>" required> </div> <div class="mb-3"> <label class="form-label">Description</label> <textarea name="description" class="form-control" placeholder="Enter description here..."><?php echo !empty($proData['description'])?$proData['description']:''?></textarea> </div> <div class="mb-3"> <label class="form-label">Images</label> <input type="file" name="image_files[]" class="form-control" accept="image/*" multiple > <?php if(!empty($proData['images'])){ ?> <div class="image-grid"> <?php foreach($proData['images'] as $imageRow){ ?> <div class="img-bx" id="imgbx_<?php echo $imageRow['id']; ?>"> <img src="<?php echo $uploadDir.$imageRow['file_name']; ?>" width="120"/> <a href="javascript:void(0);" class="badge text-bg-danger" onclick="deleteImage(<?php echo $imageRow['id']; ?>)">delete</a> </div> <?php ?> </div> <?php ?> </div> <div class="mb-3"> <label class="form-label">Status</label> <div class="form-check"> <input class="form-check-input" type="radio" name="status" id="status1" value="1" <?php echo !empty($proData['status']) || !isset($proData['status'])?'checked':''?>> <label class="form-check-label" for="status1">Active</label> </div> <div class="form-check"> <input class="form-check-input" type="radio" name="status" id="status2" value="0" <?php echo isset($proData['status']) && empty($proData['status'])?'checked':''?>> <label class="form-check-label" for="status2">Inactive</label> </div> </div> <input type="hidden" name="id" value="<?php echo !empty($proData['id'])?$proData['id']:''?>"> <input type="submit" name="dataSubmit" class="btn btn-primary" value="Submit"> </form> </div> </div>

Add / Edit / Delete Records and Upload Multiple Images (postAction.php)

This postAction.php file handles the add, edit, and delete operations with multiple image uploads using PHP and MySQL.

1. Add / Edit Form Submit:
The submitted form data is validated to check the empty field value.

  • The insert() and update() methods of the DB class are used to add/update product data in the database.
  • Check and validate the file extension using pathinfo() function in PHP.
  • Upload multiple images to the server using the move_uploaded_file() function in PHP.
  • Insert the uploaded file names and associated product ID in the database using the insert_image() method of the DB class.

2. Inactive Product (action_type => block):
Update and set the product status to 0 in the database.

  • The update() method of the DB class is used to update the status field value in the database.

3. Activate Product (action_type => unblock):
Update and set the product status to 1 in the database.

  • The update() method of the DB class is used to update the status field value in the database.

4. Delete Product (action_type => delete):
Delete product and associated image data from the database.

  • Remove images from the directory of the server.
  • The delete() and delete_images() methods of the DB class are used to delete product and image data from the database.

After the data manipulation, the status is stored in SESSION and redirected to the respective page.

<?php 
// Include and initialize DB class
require_once 'DB.class.php';
$db = new DB();

// Set default redirect url
$redirectURL 'index.php';

$statusMsg $error $errorMsg_img '';
$sessData = array();
$statusType 'danger';

// If add/edit form is submitted
if(isset($_POST['dataSubmit'])){
    
// Set redirect url
    
$redirectURL 'addEdit.php';

    
// Store submitted data into session
    
$sessData['postData'] = $_POST;

    
// Get submitted input data
    
$title $_POST['title'];
    
$description $_POST['description'];
    
$status_input $_POST['status'];
    
$image_files $_FILES['image_files'];
    
$id    $_POST['id'];
    
    
// Prepare data array for database insertion
    
$proData = array(
        
'title'  => $title,
        
'description'  => $description,
        
'status'  => $status_input
    
);
    
    
// Specify ID query string
    
$idStr = !empty($id)?'?id='.$id:'';

    
// Input fields validation
    
$error '';
    if(empty(
$title)){
        
$error .= 'Please enter title.<br>';
    }
    
    
// If the data is not empty
    
if(empty($error)){
        if(!empty(
$id)){
            
// Update data in the database
            
$condition = array('id' => $id);
            
$update $db->update($proData$condition);
            
            if(
$update){
                
$product_id $id;
            }
        }else{
            
// Insert data in the database
            
$insert $db->insert($proData);
            
            if(
$insert){
                
$product_id $insert;
            }
        }

        if(!empty(
$product_id)){
            
// Upload images
            
$fileNames array_filter($image_files['name']); 
            if(!empty(
$fileNames)){ 
                foreach(
$image_files['name'] as $key=>$val){ 
                    
// File upload path 
                    
$fileName time().'_'.basename($image_files['name'][$key]); 
                    
$targetFilePath $uploadDir $fileName
                    
                    
// Check whether file type is valid 
                    
$fileType pathinfo($targetFilePathPATHINFO_EXTENSION); 
                    if(
in_array($fileType$allowTypes)){ 
                        
// Upload file to the server
                        
if(move_uploaded_file($image_files["tmp_name"][$key], $targetFilePath)){ 
                            
// Insert image in the database
                            
$imgData = array( 
                                
'product_id' => $product_id
                                
'file_name' => $fileName 
                            
); 
                            
$insertImage $db->insert_image($imgData);
                        }else{ 
                            
$errorUpload .= $image_files['name'][$key].' | '
                        } 
                    }else{ 
                        
$errorUploadType .= $image_files['name'][$key].' | '
                    } 
                } 
                
                
// File upload error message
                
$errorUpload = !empty($errorUpload)?'File upload error: '.trim($errorUpload' | '):''
                
$errorUploadType = !empty($errorUploadType)?'File type error: '.trim($errorUploadType' | '):''
                
$errorMsg = !empty($errorUpload) ? '<br>'.$errorUpload.'<br>'.$errorUploadType : (!empty($errorUploadType) ? '<br>'.$errorUploadType '' );
                
$errorMsg_img = !empty($errorMsg)?'<span>'.$errorMsg.'</span>':'';
            }

            
$statusType 'success';
            
$statusMsg 'Product data has been submitted successfully!'.$errorMsg_img;
            
$sessData['postData'] = '';
            
            
// Set redirect url
            
$redirectURL 'index.php';
        }else{
            
$statusMsg 'Something went wrong, please try again!';
            
// Set redirect url
            
$redirectURL .= $idStr;
        }
    }else{
        
$statusMsg 'Please fill all the required fields:<br>'.trim($error'<br>');
    }
    
    
// Status message
    
$sessData['status']['type'] = $statusType;
    
$sessData['status']['msg']  = $statusMsg;
}elseif((
$_REQUEST['action_type'] == 'block') && !empty($_GET['id'])){
    
// Update status in the database
    
$data = array('status' => 0);
    
$condition = array('id' => $_GET['id']);
    
$update $db->update($data$condition);

    if(
$update){
        
$statusType 'success';
        
$statusMsg  'Product status changed to Inactive successfully.';
    }else{
        
$statusMsg  'Something went wrong, please try again!';
    }
    
    
// Status message
    
$sessData['status']['type'] = $statusType;
    
$sessData['status']['msg']  = $statusMsg;
}elseif((
$_REQUEST['action_type'] == 'unblock') && !empty($_GET['id'])){
    
// Update status in the database
    
$data = array('status' => 1);
    
$condition = array('id' => $_GET['id']);

    
$update $db->update($data$condition);
    if(
$update){
        
$statusType 'success';
        
$statusMsg  'Product status changed to Active successfully.';
    }else{
        
$statusMsg  'Something went wrong, please try again!';
    }
    
    
// Status message
    
$sessData['status']['type'] = $statusType;
    
$sessData['status']['msg']  = $statusMsg;
}elseif((
$_REQUEST['action_type'] == 'delete') && !empty($_GET['id'])){
    
$product_id $_GET['id'];

    
// Fetch previous data from database
    
$conditions['where'] = array(
        
'id' => $product_id
    
);
    
$conditions['return_type'] = 'single';
    
$prevData $db->getRows($conditions);
                
    
// Delete record from the database
    
$condition = array('id' => $product_id);
    
$delete $db->delete($condition);

    if(
$delete){
        
// Delete image records from the database
        
$condition = array('product_id' => $product_id);
        
$deleteImages $db->delete_images($condition);

        
// Remove physical files from the server
        
if(!empty($prevData['images'])){
            foreach(
$prevData['images'] as $row){
                @
unlink($uploadDir.$row['file_name']);
            }
        }
        
        
$statusType 'success';
        
$statusMsg  'Product data has been deleted successfully.';
    }else{
        
$statusMsg  'Something went wrong, please try again!';
    }
    
    
// Status message
    
$sessData['status']['type'] = $statusType;
    
$sessData['status']['msg']  = $statusMsg;
}

// Store status into the session
$_SESSION['sessData'] = $sessData;
    
// Redirect the user
header("Location: ".$redirectURL);
exit();
?>

Delete Product Images via AJAX Request using JavaScript

In the previous steps, we have added the Delete button on each image listed in the details.php and addEdit.php pages. In this step, we will write some code to make the Delete button effective.

Ajax Request with JavaScript:
The following code needs to be placed in the details.php and addEdit.php pages to enable the image delete functionality attached to the Delete button.

  • The deleteImage() is a JavaScript function that initiates an AJAX request to delete the image from the product based on the row ID.
  • POST the file ID to the server-side script (ajax_request.php) to process the image_delete request.
  • This specific image is deleted from the database and the element is removed from the web page.
<script>
function deleteImage(row_id) {
    if(row_id && confirm('Are you sure to delete image?')){
        const img_element = document.getElementById("imgbx_"+row_id);

        img_element.setAttribute("style", "opacity:0.5;");

        fetch("ajax_request.php", {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({ request_type:'image_delete', row_id: row_id }),
        })
        .then(response => response.json())
        .then(data => {
            if (data.status == 1) {
                img_element.remove();
            } else {
                alert(data.msg);
            }
            img_element.setAttribute("style", "opacity:1;");
        })
        .catch(console.error);
    }
}
</script>

Server-side Script (ajax_request.php):
The ajax_request.php file is loaded by the Ajax request from the deleteImage() function.

  • The delete_images() method of the DB class is used to delete image data from the database based on the ID using PHP and MySQL.
  • Remove the physical image file from the server using the unlink() function in PHP.
  • Return the response in JSON format.
<?php 
// Include and initialize DB class
require_once 'DB.class.php';
$db = new DB();

// Retrieve JSON from POST body 
$jsonStr file_get_contents('php://input'); 
$jsonObj json_decode($jsonStr); 

if(
$jsonObj->request_type == 'image_delete'){ 
    
$row_id = !empty($jsonObj->row_id)?$jsonObj->row_id:'';

    
// Fetch previous file name from database
    
$prevData $db->get_image_row($row_id);
    
$file_name_prev $prevData['file_name'];

    
$condition = array('id' => $row_id);
    
$delete $db->delete_images($condition);
    if(
$delete){
        
// Remove physical file from the server
        
@unlink($uploadDir.$file_name_prev);
        
        
$output = array( 
            
'status' => 1,
            
'msg' => 'Deleted!'
        
);
    }else{
        
$output = array(
            
'status' => 0,
            
'msg' => 'Image deletion failed!'
        
);
    }

    
// Return response
    
echo json_encode($output); 
}
?>

PHP CRUD Operations with Search and Pagination

Conclusion

Product CRUD with multiple images helps you to implement product management functionality for e-commerce applications using PHP. In this example script, we build a data management system with multiple images. You can take the help of this script to list the products with multiple images at the frontend of the website.

Do you want to get implementation help, or enhance the functionality of this script? Click here to Submit Service Request

Leave a reply

keyboard_double_arrow_up