About Lesson
To create a basic CRUD (Create, Read, Update, Delete) application with CodeIgniter 4, follow these steps:
Step 1: Database Setup
CREATE TABLE `customer_info` (
`id` bigint(20) NOT NULL,
`name` varchar(100) NOT NULL,
`email` varchar(255) NOT NULL,
`address` varchar(255) NOT NULL,
`mobile_number` varchar(100) DEFAULT NULL,
`image_url` TEXT NULL,
`ip_address` varchar(255) NOT NULL,
`created_at` datetime NOT NULL,
`updated_at` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`status` varchar(10) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
ALTER TABLE `customer_info` ADD PRIMARY KEY (`id`);
Step 2: Controller
Create a controller to handle CRUD operations. Create a new file named Customer.php
in the app/Controllers/customer
folder.
<?php
namespace App\Controllers\customer;
use App\Controllers\BaseController;
use App\Models\customer\CustomerModel;
use App\Models\customer\CustomerDeferModel;
class Customer extends BaseController {
public function __construct() {
$db = db_connect();
$this->session = \Config\Services::session();
$this->customer = new CustomerModel($db);
$this->customerDefer = new CustomerDeferModel($db);
$this->ip_address = $_SERVER['REMOTE_ADDR'];
$this->datetime = date("Y-m-d H:i:s");
}
public function index() {
$this->list();
}
public function list() {
$data = [];
$data ['content_title'] = 'List of Customers';
echo view('customer/list', $data);
}
public function edit() {
$id = $this->request->getPost('id');
$result = $this->customer->getEntry(['id' => $id]);
$html = '';
if($result) {
$html = '
<form id="form-update-customer" method="post" autocomplete="off">
<input type="hidden" name="id" value="'.$result->id.'"/>
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Update Customer</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="modal-message">
</div>
<div class="form-group">
<label>Name</label>
<input type="text" class="form-control" id="name" name="name" placeholder="Name" value="'.$result->name.'" required>
</div>
<div class="form-group">
<label>Email</label>
<input type="email" class="form-control" id="email" name="email" placeholder="Email" value="'.$result->email.'" required>
</div>
<div class="form-group">
<label>Mobile No.</label>
<input type="text" class="form-control" id="mobile_number" name="mobile_number" value="'.$result->mobile_number.'" placeholder="Mobile No." maxlength="10" required>
</div>
<div class="form-group">
<label>Address</label>
<input type="text" class="form-control" id="address" name="address" placeholder="Address" value="'.$result->address.'" required>
</div>
<div class="form-group">
<label>File</label>
<input type="file" class="form-control" id="file" name="file" placeholder="Choose File" accept="image/*">
<a href="'.base_url($result->image_url).'" target="_blank">Open File</a>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Update Customer</button>
</div>
</form>
';
}
echo $html;
}
public function create() {
$name = $this->request->getPost('name');
$email = $this->request->getPost('email');
$address = $this->request->getPost('address');
$mobile_number = $this->request->getPost('mobile_number');
$file = $this->request->getFile('file');
$where = [
'email' => $email,
];
$has_account = $this->customer->getEntry($where);
if($has_account) {
$json = [
'status' => false,
'message' => showDangerMessage("Entered email address is already exists."),
];
} else {
if($file->isValid()) {
$path = 'uploads/customers/';
$image_url = $this->uploadFile($path, $file);
$data = [
'name' => $name,
'email' => $email,
'address' => $address,
'mobile_number' => $mobile_number,
'image_url' => $image_url,
'ip_address' => $this->ip_address,
'created_at' => $this->datetime,
'status' => "1",
];
$result = $this->customer->addEntry($data);
if($result) {
$json = [
'status' => true,
'message' => showSuccessMessage("New record has been created successfully"),
];
} else {
$json = [
'status' => false,
'message' => showDangerMessage("Something went wrong. Please try again!"),
];
}
} else {
$json = [
'status' => false,
'message' => showDangerMessage("Please select file."),
];
}
}
echo json_encode($json);
}
public function update() {
$id = $this->request->getPost('id');
$name = $this->request->getPost('name');
$email = $this->request->getPost('email');
$address = $this->request->getPost('address');
$mobile_number = $this->request->getPost('mobile_number');
$file = $this->request->getFile('file');
$where = [
'id !=' => $id,
'email' => $email,
];
$has_account = $this->customer->getEntry($where);
if($has_account) {
$json = [
'status' => false,
'message' => showDangerMessage("Entered email address is already exists."),
];
} else {
if($file->isValid()) {
$path = 'uploads/customers/';
$image_url = $this->uploadFile($path, $file);
$data = [
'name' => $name,
'email' => $email,
'address' => $address,
'mobile_number' => $mobile_number,
'image_url' => $image_url,
'ip_address' => $this->ip_address,
];
} else {
$data = [
'name' => $name,
'email' => $email,
'address' => $address,
'mobile_number' => $mobile_number,
'ip_address' => $this->ip_address,
];
}
$result = $this->customer->updateEntry(['id' => $id], $data);
if($result) {
$json = [
'status' => true,
'message' => showSuccessMessage("Selected record has been updated successfully"),
];
} else {
$json = [
'status' => false,
'message' => showDangerMessage("Something went wrong. Please try again!"),
];
}
}
echo json_encode($json);
}
public function delete() {
$id = $this->request->getPost('id');
$result = $this->customer->deleteEntry(["id" => $id]);
if($result) {
$json = [
'message' => showSuccessMessage("The selected record has been deleted successfully."),
'status' => true,
];
} else {
$json = [
'message' => showDangerMessage("Something went wrong. Please try again."),
'status' => false,
];
}
echo json_encode($json);
}
public function datatable() {
$postData = $this->request->getPost();
$i = $this->request->getPost('start');
$result = $this->customerDefer->getRows($postData);
$arrayList = $this->getRows($i, $result);
$output = array(
"draw" => $this->request->getPost('draw'),
"recordsTotal" => $this->customerDefer->countAll($this->request->getPost()),
"recordsFiltered" => $this->customerDefer->countFiltered($this->request->getPost()),
"data" => $arrayList,
);
echo json_encode($output);
}
function getRows($i, $result) {
$arrayList = [];
foreach($result as $row) {
$action = ' <button type="button" name="btn-edit" class="btn btn-sm btn-primary" data-id="'.$row->id.'" title="Edit">Edit</button>';
$action .= ' <button type="button" name="btn-delete" class="btn btn-sm btn-danger" data-id="'.$row->id.'" title="Delete">Delete</button>';
$arrayList [] = [
++$i,
$row->name,
$row->email,
$row->mobile_number,
$row->address,
'<a href="'.base_url($row->image_url).'" target="_blank"><img src="'.base_url($row->image_url).'" class="img-thumbnail" width="100px"></a>',
$action,
];
}
return $arrayList;
}
function uploadFile($path, $image) {
if (!is_dir($path))
mkdir($path, 0777, TRUE);
if ($image->isValid() && ! $image->hasMoved()) {
$newName = $image->getRandomName();
$image->move('./'.$path, $newName);
return $path.$image->getName();
}
return false;
}
}
Step 3: Model
Create a model to handle database operations. Create a new file named CustomerModel.php
and CustomerDeferModel.php
in the app/Models/customer
folder.
CustomerModel.php
<?php
namespace App\Models\customer;
use CodeIgniter\Model;
use CodeIgniter\Database\ConnectionInterface;
class CustomerModel extends Model {
protected $db;
public function __construct(ConnectionInterface &$db) {
$this->db =& $db;
$this->table = 'customer_info';
}
public function addEntry($data) {
$this->db
->table($this->table)
->insert($data);
return $this->db->insertID();
}
public function updateEntry($where, $data) {
return $this->db
->table($this->table)
->where($where)
->set($data)
->update();
}
public function deleteEntry($where) {
return $this->db
->table($this->table)
->where($where)
->delete();
}
public function getEntry($where) {
return $this->db
->table($this->table)
->where($where)
->get()
->getRow();
}
public function getEntryList($where = 0) {
if($where) {
return $this->db
->table($this->table)
->where($where)
->get()
->getResult();
} else {
return $this->db
->table($this->table)
->get()
->getResult();
}
}
public function getNumRows($where) {
return $this->db
->table($this->table)
->where($where)
->get()
->getNumRows();
}
}
Step 4: Create Views
Create views (list.php) in the app/Views/customer
folder for listing, creating, updating, and deleting records.
list.php
<!DOCTYPE html>
<html lang="en">
<head>
<title><?php echo $content_title; ?></title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.7/css/jquery.dataTables.min.css"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.datatables.net/1.13.7/js/jquery.dataTables.min.js"></script>
</head>
<body>
<div class="jumbotron text-center">
<h1>Welcome to Infovistar.in</h1>
<p>CRUD Example with AJAX</p>
</div>
<div class="container">
<div class="row">
<div class="col-sm-12 message">
</div>
<div class="col-sm-12">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#modal-add-customer">Add Customer</button>
</div>
<div class="col-sm-12 mt-1">
<div class="table-responsive">
<table id="table-customer" class="table table-sm table-bordered table-striped table-hover" width="100%">
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th>Email</th>
<th>Mobile</th>
<th>Address</th>
<th>Attachment</th>
<th>Action</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</div>
<div class="modal fade" id="modal-add-customer" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<form id="form-add-customer" method="post" autocomplete="off" enctype="multipart/form-data">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Add Customer</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="modal-message">
</div>
<div class="form-group">
<label>Name</label>
<input type="text" class="form-control" id="name" name="name" placeholder="Name" required>
</div>
<div class="form-group">
<label>Email</label>
<input type="email" class="form-control" id="email" name="email" placeholder="Email" required>
</div>
<div class="form-group">
<label>Mobile No.</label>
<input type="text" class="form-control" id="mobile_number" name="mobile_number" placeholder="Mobile No." maxlength="10" required>
</div>
<div class="form-group">
<label>Address</label>
<input type="text" class="form-control" id="address" name="address" placeholder="Address" required>
</div>
<div class="form-group">
<label>File</label>
<input type="file" class="form-control" id="file" name="file" placeholder="Choose File" accept="image/*" required>
</div>
</div>
<div class="modal-footer">
<button type="submit" id="btn-add" class="btn btn-primary">Add Customer</button>
</div>
</form>
</div>
</div>
</div>
<div class="modal fade" id="modal-update-customer" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="edit-customer"></div>
</div>
</div>
</div>
<script>
$(document).ready(function() {
var table_customer = $("#table-customer").DataTable({
"processing":true,
"serverSide":true,
"order":[],
"ajax": {
url : '<?php echo base_url("customer/datatable") ?>',
type:"POST"
},
"columnDefs":[
{
"targets":[0],
"orderable":false,
},
],
});
$('#table-customer tbody').on( 'click', 'button', function () {
let id = $(this).attr('data-id');
if(this.name == "btn-delete") {
var isDelete = confirm("Are you sure you want to delete this?");
if(isDelete) {
$.post("<?php echo base_url("customer/delete"); ?>", {id: id}, function( result ) {
$(".message").html(result.message);
if(result.status) {
table_customer.ajax.reload();
}
}, 'json');
}
} if(this.name == "btn-edit") {
$.post("<?php echo base_url("customer/edit"); ?>", {id: id}, function( result ) {
$(".edit-customer").html(result);
$("#modal-update-customer").modal("show");
});
}
});
$("body").on("submit", "#form-add-customer", function(e) {
e.preventDefault();
var data = new FormData(this);
$.ajax({
type: 'POST',
url: "<?php echo base_url('customer/create') ?>",
data: data,
dataType: 'json',
contentType: false,
cache: false,
processData:false,
beforeSend: function() {
$("#btn-add").prop('disabled', true);
},
success: function(result) {
$("#btn-add").prop('disabled', false);
if(result.status) {
$(".message").html(result.message);
table_customer.ajax.reload();
$("#form-add-customer")[0].reset();
$("#modal-add-customer").modal("hide");
} else {
$(".modal-message").html(result.message);
}
}
});
});
$("body").on("submit", "#form-update-customer", function(e) {
e.preventDefault();
var data = new FormData(this);
$.ajax({
type: 'POST',
url: "<?php echo base_url('customer/update') ?>",
data: data,
dataType: 'json',
contentType: false,
cache: false,
processData:false,
beforeSend: function() {
$("#btn-add").prop('disabled', true);
},
success: function(result) {
$("#btn-add").prop('disabled', false);
if(result.status) {
$(".message").html(result.message);
table_customer.ajax.reload();
$("#form-update-customer")[0].reset();
$("#modal-update-customer").modal("hide");
} else {
$(".modal-message").html(result.message);
}
}
});
});
});
</script>
</body>
</html>
Step 5: Set Up Routes
Edit the app/config/Routes.php
file to define routes for your controller.
// Customer Routes
$routes->group('customer', function($routes) {
$routes->get('/', 'customerCustomer::index');
$routes->get('list', 'customerCustomer::list');
$routes->post('datatable', 'customerCustomer::datatable');
$routes->post('create', 'customerCustomer::create');
$routes->post('edit', 'customerCustomer::edit');
$routes->post('update', 'customerCustomer::update');
$routes->post('delete', 'customerCustomer::delete');
});
Step 6: BaseController
<?php
namespace App\Controllers;
use CodeIgniter\Controller;
use CodeIgniter\HTTP\CLIRequest;
use CodeIgniter\HTTP\IncomingRequest;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
/**
* Class BaseController
*
* BaseController provides a convenient place for loading components
* and performing functions that are needed by all your controllers.
* Extend this class in any new controllers:
* class Home extends BaseController
*
* For security be sure to declare any new methods as protected or private.
*/
abstract class BaseController extends Controller
{
/**
* Instance of the main Request object.
*
* @var CLIRequest|IncomingRequest
*/
protected $request;
/**
* An array of helpers to be loaded automatically upon
* class instantiation. These helpers will be available
* to all other controllers that extend BaseController.
*
* @var array
*/
protected $helpers = [
'url', 'form', 'array', 'date',
'message_helper'
];
/**
* Be sure to declare properties for any property fetch you initialized.
* The creation of dynamic property is deprecated in PHP 8.2.
*/
// protected $session;
/**
* @return void
*/
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
// Do Not Edit This Line
parent::initController($request, $response, $logger);
// Preload any models, libraries, etc, here.
// E.g.: $this->session = \Config\Services::session();
}
}
Step 7: Custom Helpers
Create a helper (message_helper.php) in the app/Helpers
folder.
<?php
function showSuccessMessage($message) {
return '<div class="alert alert-success">
<strong>Great!</strong> '.$message.'
</div>';
}
function showDangerMessage($message) {
return '<div class="alert alert-danger">
<strong>Oops!</strong> '.$message.'
</div>';
}
Step 8: Run Project & Output