Code your dreams into reality.
Every line of code is a step towards a better future.
Embrace the bugs, they make you a better debugger.

CodeIgniter 4 CRUD with Image Upload Tutorial

Last Updated on July 25, 2024 by

The CRUD image upload feature in CodeIgniter 4 allows users to perform create, read, update, and delete operations with file upload from the database.

Let’s start building a CRUD operation with image upload application using MySQL database:

Step 1: Setting Up CodeIgniter 4

Download CodeIgniter 4 from the official website:https://codeigniter.com/user_guide/installation/index.html., and extract download zip file in xampp/htdocs directory.

Edit .env file, and set the database connection:

database.default.hostname = localhost
database.default.database = your_database_name
database.default.username = your_username
database.default.password = your_password
database.default.DBDriver = MySQLi

Step 2: Create the Database and Table

Run the following sql query to create database and table:

CREATE DATABASE ci4_crud_image;

CREATE TABLE products (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    description TEXT NOT NULL,
    image VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Step 3: Creating the Model

Go to the app/models directory and create a model file called ProductModel.php in it:

<?php namespace App\Models;

use CodeIgniter\Model;

class ProductModel extends Model
{
    protected $table = 'products';
    protected $primaryKey = 'id';
    protected $allowedFields = ['name', 'description', 'image'];
}

Step 4: Creating the Controller

Go to app/Controllers/ directory and create a new file named ProductController.php, and crud methods in it to handle crud image upload:

<?php namespace App\Controllers;

use App\Models\ProductModel;
use CodeIgniter\Controller;

class ProductController extends Controller
{
    public function index()
    {
        $model = new ProductModel();
        $data['products'] = $model->findAll();
        return view('products/index', $data);
    }

    public function create()
    {
        return view('products/create');
    }

    public function store()
    {
        $model = new ProductModel();
        $image = $this->request->getFile('image');
        $imageName = $image->getRandomName();
        $image->move('uploads', $imageName);

        $data = [
            'name' => $this->request->getPost('name'),
            'description' => $this->request->getPost('description'),
            'image' => $imageName
        ];
        $model->save($data);
        return redirect()->to('/products');
    }

    public function edit($id)
    {
        $model = new ProductModel();
        $data['product'] = $model->find($id);
        return view('products/edit', $data);
    }

    public function update($id)
    {
        $model = new ProductModel();
        $product = $model->find($id);
        $image = $this->request->getFile('image');

        if ($image->isValid() && !$image->hasMoved()) {
            if (file_exists("uploads/".$product['image'])) {
                unlink("uploads/".$product['image']);
            }
            $imageName = $image->getRandomName();
            $image->move('uploads', $imageName);
            $data['image'] = $imageName;
        } else {
            $data['image'] = $product['image'];
        }

        $data['name'] = $this->request->getPost('name');
        $data['description'] = $this->request->getPost('description');
        $model->update($id, $data);
        return redirect()->to('/products');
    }

    public function delete($id)
    {
        $model = new ProductModel();
        $product = $model->find($id);
        if (file_exists("uploads/".$product['image'])) {
            unlink("uploads/".$product['image']);
        }
        $model->delete($id);
        return redirect()->to('/products');
    }
}

Step 5: Create Views

Create a new file layout.php in app/Views directory:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CodeIgniter 4 CRUD with Image Upload Example - itcodstuff.com</title>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <div class="container mt-5">
        <?= $this->renderSection('content') ?>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

In the app/Views/products directory create a new file index.php to show list of products from database:

<?= $this->extend('layout') ?>

<?= $this->section('content') ?>
<h2>Products List</h2>
<a href="/products/create" class="btn btn-primary mb-3">Add New Product</a>
<table class="table table-bordered">
    <thead>
        <tr>
            <th>ID</th>
            <th>Name</th>
            <th>Description</th>
            <th>Image</th>
            <th>Actions</th>
        </tr>
    </thead>
    <tbody>
        <?php foreach($products as $product): ?>
        <tr>
            <td><?= $product['id'] ?></td>
            <td><?= $product['name'] ?></td>
            <td><?= $product['description'] ?></td>
            <td><img src="/uploads/<?= $product['image'] ?>" alt="<?= $product['name'] ?>" width="50"></td>
            <td>
                <a href="/products/edit/<?= $product['id'] ?>" class="btn btn-warning btn-sm">Edit</a>
                <form action="/products/delete/<?= $product['id'] ?>" method="post" style="display:inline-block;">
                    <?= csrf_field() ?>
                    <input type="hidden" name="_method" value="DELETE">
                    <button type="submit" class="btn btn-danger btn-sm">Delete</button>
                </form>
            </td>
        </tr>
        <?php endforeach; ?>
    </tbody>
</table>
<?= $this->endSection() ?>

Create a new file create.php in app/Views/products directory, and make add the product form in it:

<?= $this->extend('layout') ?>

<?= $this->section('content') ?>
<h2>Add New Product</h2>
<form action="/products/store" method="post" enctype="multipart/form-data">
    <?= csrf_field() ?>
    <div class="mb-3">
        <label for="name" class="form-label">Name</label>
        <input type="text" class="form-control" id="name" name="name" required>
    </div>
    <div class="mb-3">
        <label for="description" class="form-label">Description</label>
        <textarea class="form-control" id="description" name="description" rows="3" required></textarea>
    </div>
    <div class="mb-3">
        <label for="image" class="form-label">Image</label>
        <input type="file" class="form-control" id="image" name="image" required>
    </div>
    <button type="submit" class="btn btn-success">Save</button>
</form>
<?= $this->endSection() ?>

In the app/Views/products directory create a new file edit.php, and create edit product form in it:

<?= $this->extend('layout') ?>

<?= $this->section('content') ?>
<h2>Edit Product</h2>
<form action="/products/update/<?= $product['id'] ?>" method="post" enctype="multipart/form-data">
    <?= csrf_field() ?>
    <input type="hidden" name="_method" value="PUT">
    <div class="mb-3">
        <label for="name" class="form-label">Name</label>
        <input type="text" class="form-control" id="name" name="name" value="<?= $product['name'] ?>" required>
    </div>
    <div class="mb-3">
        <label for="description" class="form-label">Description</label>
        <textarea class="form-control" id="description" name="description" rows="3" required><?= $product['description'] ?></textarea>
    </div>
    <div class="mb-3">
        <label for="image" class="form-label">Image</label>
        <input type="file" class="form-control" id="image" name="image">
        <img src="/uploads/<?= $product['image'] ?>" alt="<?= $product['name'] ?>" width="50" class="mt-2">
    </div>
    <button type="submit" class="btn btn-success">Update</button>
</form>
<?= $this->endSection() ?>

Step 6: Define Routes

Edit app/Config/Routes.php and define the following routes:

$routes->get('/products', 'ProductController::index');
$routes->get('/products/create', 'ProductController::create');
$routes->post('/products/store', 'ProductController::store');
$routes->get('/products/edit/(:num)', 'ProductController::edit/$1');
$routes->post('/products/update/(:num)', 'ProductController::update/$1');
$routes->delete('/products/delete/(:num)', 'ProductController::delete/$1');

Step 7: Test the Application

Type the url: http://localhost/your_project_name/public/products on browser and test this application

Leave a Comment