Modern web applications often involve working with databases to store and manage data. CRUD operations (Create, Read, Update, Delete) form the foundation of interacting with a database.
These operations allow users to create new records, retrieve existing data, update information, and delete entries when necessary. In the context of web development, frameworks provide a structured approach to handle these operations efficiently.
This article is a comprehensive guide on implementing CRUD operations in CodeIgniter 4. It covers how to perform Create, Read, Update, and Delete operations using the framework’s conventions and components.
Table of Content
- Database configuration
- Create a Table using migration
- Model Creation
- Routes Configuration
- Create a Controller
- Creating Views
- Run the project
- Output
- Conclusion
1. Database configuration
- Open
.env
file which is available at the project root.
NOTE – If dot (.) not added at the start then rename the file to .env.
- Remove # from start of
database.default.hostname
,database.default.database
,database.default.username
,database.default.password
,database.default.DBDriver
,database.default.DBPrefix
, anddatabase.default.port
. - Update the configuration and save it.
database.default.hostname = 127.0.0.1 database.default.database = codeigniterdb database.default.username = root database.default.password = root database.default.DBDriver = MySQLi database.default.DBPrefix = database.default.port = 3306
2. Create a Table using migration
- Create subjects table by executing below command:
php spark migrate:create create_subjects_table
- This will create a new file PHP file that ends with
create_subjects_table
. - Open the file to define table structure in the
up()
method. - Using the
down()
method deletesubjects
table which calls when undoing migration.
<?php namespace App\Database\Migrations; use CodeIgniter\Database\Migration; class CreateSubjectsTable extends Migration { public function up() { $this->forge->addField([ 'id' => [ 'type' => 'INT', 'constraint' => 5, 'unsigned' => true, 'auto_increment' => true, ], 'name' => [ 'type' => 'VARCHAR', 'constraint' => '100', ], 'description' => [ 'type' => 'TEXT', 'null' => true, ], ]); $this->forge->addKey('id', true); $this->forge->createTable('subjects'); } //-------------------------------------------------------------------- public function down() { $this->forge->dropTable('subjects'); } }
- After defining table definition execute the below command to create the table in the database –
php spark migrate
3. Model Creation
- Execute below command to create
Subjects
Model –
php spark make:model Subjects
- Open
app/Models/Subjects.php
file. - In
$allowedFields
Array specify field names –['name','description']
that can be set during insert and update.
<?php namespace App\Models; use CodeIgniter\Model; class Subjects extends Model { protected $DBGroup = 'default'; protected $table = 'subjects'; protected $primaryKey = 'id'; protected $useAutoIncrement = true; protected $insertID = 0; protected $returnType = 'array'; protected $useSoftDeletes = false; protected $protectFields = true; protected $allowedFields = ['name','description']; // Dates protected $useTimestamps = false; protected $dateFormat = 'datetime'; protected $createdField = 'created_at'; protected $updatedField = 'updated_at'; protected $deletedField = 'deleted_at'; // Validation protected $validationRules = []; protected $validationMessages = []; protected $skipValidation = false; protected $cleanValidationRules = true; // Callbacks protected $allowCallbacks = true; protected $beforeInsert = []; protected $afterInsert = []; protected $beforeUpdate = []; protected $afterUpdate = []; protected $beforeFind = []; protected $afterFind = []; protected $beforeDelete = []; protected $afterDelete = []; }
4. Routes Configuration
- Open
app/Config/Routes.php
file. - Define 6 routes –
- / – Display subject list.
- subjects/create – Open add subject view.
- subjects/store – Submit subject form to insert a record.
- subjects/edit/(:num) – Open edit subject view by id.
- subjects/update/(:num) – Submit edit form to update a record by id.
- subjects/delete/(:num) – Delete a subject by id.
$routes->get('/', 'SubjectsController::index'); $routes->get('subjects/create', 'SubjectsController::create'); $routes->post('subjects/store', 'SubjectsController::store'); $routes->get('subjects/edit/(:num)', 'SubjectsController::edit/$1'); $routes->post('subjects/update/(:num)', 'SubjectsController::update/$1'); $routes->get('subjects/delete/(:num)', 'SubjectsController::delete/$1');
5. Create a Controller
- Create
SubjectsController
Controller –
php spark make:controller SubjectsController
- Open
app/Controllers/SubjectsController.php
file. - Import
Subjects
Model that we created earlier. - Create 6 methods –
- index() – Select all records from the
subjects
table and assign in$data['subjects']
. Loadsubjects/index
view and pass$data
. - create() – With this method load
subjects/create
view for adding a new subject. - store() – With this method insert a new record in the
subjects
table.
- index() – Select all records from the
Read POST values. If 'submit'
is POST then define validation. If values are not validated then return to the subjects/create
view with the error response.
If values are validated then insert a record in the subjects
table. If a record is successfully inserted then store the success message in session()->setFlashdata('message')
and class name in session()->setFlashdata('alert-class')
and return to the subjects/create
route.
Similarly, if a record is not inserted then store the failed message in session()->setFlashdata('message')
and class name in session()->setFlashdata('alert-class')
and return to the subjects/create
route.
-
- edit() – With this method load edit subject view. Select a record from the
subjects
table by$id
and assign in$data['subject']
. Loadsubjects/edit
view and pass$data
. - update() – With this method update a record in the
subjects
table.
- edit() – With this method load edit subject view. Select a record from the
Read POST values. If 'submit'
is POST then define validation. If values are not validated then return to the edit view with the error response.
If values are not validated then redirect to the edit view with the error response. Select a record from the subjects
table by $id
and assign in $subject
.
If values are validated then update a record by $id
. If a record is successfully inserted then store the success message in session()->setFlashdata('message')
and class name in session()->setFlashdata('alert-class')
and return to the /
route.
Similarly, if a record is not inserted then store the failed message in session()->setFlashdata('message')
and class name in session()->setFlashdata('alert-class')
and return to the subjects/edit
route.
-
- delete() – With this method delete a record from the
subjects
table by$id
.
- delete() – With this method delete a record from the
Check $id
record exists in the subjects
table. If exists then delete the record by $id
and store the success message in session()->setFlashdata('message')
and class name in session()->setFlashdata('alert-class')
,
Similarly, if a record is not deleted then store the failed message in session()->setFlashdata('message')
and class name in session()->setFlashdata('alert-class')
.
Return to the /
route.
<?php namespace App\Controllers; use App\Controllers\BaseController; use App\Models\Subjects; class SubjectsController extends BaseController { public function index(){ $subjects = new Subjects(); ## Fetch all records $data['subjects'] = $subjects->findAll(); return view('subjects/index',$data); } public function create(){ return view('subjects/create'); } public function store(){ $request = service('request'); $postData = $request->getPost(); if(isset($postData['submit'])){ ## Validation $input = $this->validate([ 'name' => 'required|min_length[3]', 'description' => 'required' ]); if (!$input) { return redirect()->route('subjects/create')->withInput()->with('validation',$this->validator); } else { $subjects = new Subjects(); $data = [ 'name' => $postData['name'], 'description' => $postData['description'] ]; ## Insert Record if($subjects->insert($data)){ session()->setFlashdata('message', 'Added Successfully!'); session()->setFlashdata('alert-class', 'alert-success'); return redirect()->route('subjects/create'); }else{ session()->setFlashdata('message', 'Data not saved!'); session()->setFlashdata('alert-class', 'alert-danger'); return redirect()->route('subjects/create')->withInput(); } } } } public function edit($id = 0){ ## Select record by id $subjects = new Subjects(); $subject = $subjects->find($id); $data['subject'] = $subject; return view('subjects/edit',$data); } public function update($id = 0){ $request = service('request'); $postData = $request->getPost(); if(isset($postData['submit'])){ ## Validation $input = $this->validate([ 'name' => 'required|min_length[3]', 'description' => 'required' ]); if (!$input) { return redirect()->route('subjects/edit/'.$id)->withInput()->with('validation',$this->validator); } else { $subjects = new Subjects(); $data = [ 'name' => $postData['name'], 'description' => $postData['description'] ]; ## Update record if($subjects->update($id,$data)){ session()->setFlashdata('message', 'Updated Successfully!'); session()->setFlashdata('alert-class', 'alert-success'); return redirect()->route('/'); }else{ session()->setFlashdata('message', 'Data not saved!'); session()->setFlashdata('alert-class', 'alert-danger'); return redirect()->route('subjects/edit/'.$id)->withInput(); } } } } public function delete($id=0){ $subjects = new Subjects(); ## Check record if($subjects->find($id)){ ## Delete record $subjects->delete($id); session()->setFlashdata('message', 'Deleted Successfully!'); session()->setFlashdata('alert-class', 'alert-success'); }else{ session()->setFlashdata('message', 'Record not found!'); session()->setFlashdata('alert-class', 'alert-danger'); } return redirect()->route('/'); } }
6. Creating Views
Create a layouts
and subjects
folder at app/Views/
.
Create the following files in the folders –
- layouts
- layout.php
- subjects
- index.php
- create.php
- edit.php
layouts/layout.php
Creating a layout. Included bootstrap CSS in the <head >
section and added some CSS.
Define 'content'
section.
<!doctype html> <html> <head> <title>CRUD (Create Read Update Delete) in a CodeIgniter 4</title> <link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"> <style type="text/css"> .mb20{ margin-bottom: 20px; } .actionbutton{ width: 100%; height: 55px; } .errors{ color: red; } </style> </head> <body> <div class="container"> <div class="row"> <div class="col-md-12"> <?= $this->renderSection('content') ?> </div> </div> </div> </body> </html>
subjects/index.php
Extend 'layouts.layout'
and add content between $this->section('content')
and $this->endSection()
.
Add <a >
element to open Add subject
form. Pass <?=site_url('subjects/create')?>
in href
attribute.
Display bootstrap alert message if 'message'
Session exists. Also, set alert class using 'alert-class'
Session.
Create <table >
to list records.
Loop on the $subjects
and create a row. In the last column added edit
and delete
links.
Set edit <a >
route to <?= site_url('subjects/edit/'.$subject['id']) ?>
and delete <a >
route to <?= site_url('subjects/delete/'.$subject['id']) ?>
.
<?= $this->extend('layouts/layout') ?> <?= $this->section('content') ?> <div class="actionbutton mt-2"> <a class="btn btn-info float-right mb20" href="<?=site_url('subjects/create')?>">Add Subject</a> </div> <?php // Display Response if(session()->has('message')){ ?> <div class="alert <?= session()->getFlashdata('alert-class') ?>"> <?= session()->getFlashdata('message') ?> </div> <?php } ?> <!-- Subject List --> <table width="100%" border="1" style="border-collapse: collapse;"> <thead> <tr> <th width="10%">ID</th> <th width="30%">Name</th> <th width="45%">Description</th> <th width="15%"> </th> </tr> </thead> <tbody> <?php if(count($subjects) > 0){ foreach($subjects as $subject){ ?> <tr> <td><?= $subject['id'] ?></td> <td><?= $subject['name'] ?></td> <td><?= $subject['description'] ?></td> <td align="center"> <a class="btn btn-sm btn-info" href="<?= site_url('subjects/edit/'.$subject['id']) ?>">Edit</a> <a class="btn btn-sm btn-danger" href="<?= site_url('subjects/delete/'.$subject['id']) ?>">Delete</a> </td> </tr> <?php } }else{ ?> <tr> <td colspan="4">No data found.</td> </tr> <?php } ?> </tbody> </table> <?= $this->endSection() ?>
subjects/create.php
Extend 'layouts.layout'
and add content between $this->section('content')
and $this->endSection()
.
Add <a >
element to open List
of subjects. Pass <?=site_url('/')?>
in href
attribute.
Display bootstrap alert message if 'message'
Session exists. Also, set alert class using 'alert-class'
Session.
Load validation service \Config\Services::validation()
and assign it in $validation
.
Create <form method="post">
. Set its action="<?=site_url('subjects/store')?>"
.
Create a text and textarea element for entering the subject name and description. Display error in <span >
if not validated. Also, create a submit button.
<?= $this->extend('layouts/layout') ?> <?= $this->section('content') ?> <div class="actionbutton mt-2"> <a class="btn btn-info float-right mb20" href="<?=site_url('/')?>">List</a> </div> <div class="row"> <h2>Add Subject</h2> </div> <?php // Display Response if(session()->has('message')){ ?> <div class="alert <?= session()->getFlashdata('alert-class') ?>"> <?= session()->getFlashdata('message') ?> </div> <?php } ?> <?php $validation = \Config\Services::validation(); ?> <div class="row"> <div class="col-md-12"> <form action="<?=site_url('subjects/store')?>" method="post"> <div class="form-group"> <label for="email">Name:</label> <input type="text" class="form-control" name="name" required value="<?= old('name') ?>"> <!-- Error --> <?php if( $validation->getError('name') ) {?> <div class='alert alert-danger mt-2'> <?= $error = $validation->getError('name'); ?> </div> <?php }?> </div> <div class="form-group"> <label for="pwd">Description:</label> <textarea class="form-control" name="description" required><?= old('description') ?></textarea> <!-- Error --> <?php if($validation->getError('description')) {?> <div class='alert alert-danger mt-2'> <?= $error = $validation->getError('description'); ?> </div> <?php }?> </div> <button type="submit" class="btn btn-success" name="submit">Submit</button> </form> </div> </div> <?= $this->endSection() ?>
subjects/edit.php
Extend 'layouts.layout'
and add content between $this->section('content')
and $this->endSection()
.
Add <a >
element to open List
of subjects. Pass <?=site_url('/')?>
in href
attribute.
Display bootstrap alert message if 'message'
Session exists. Also, set alert class using 'alert-class'
Session.
Load validation service \Config\Services::validation()
and assign it in $validation
.
Create <form method="post">
. Set its action="<?=site_url('subjects/update/'.$subject['id'])?>"
.
Create a text element and store $subject->name
in value
attribute. Similarly, create textarea element and store $subject->description
. Display error in <span >
is not validated. Also, create a submit button.
<?= $this->extend('layouts/layout') ?> <?= $this->section('content') ?> <div class="actionbutton mt-2"> <a class="btn btn-info float-right mb20" href="<?=site_url('/')?>">List</a> </div> <div class="row"> <h2>Edit Subject</h2> </div> <?php // Display Response if(session()->has('message')){ ?> <div class="alert <?= session()->getFlashdata('alert-class') ?>"> <?= session()->getFlashdata('message') ?> </div> <?php } ?> <?php $validation = \Config\Services::validation(); ?> <div class="row"> <div class="col-md-12"> <form action="<?=site_url('subjects/update/'.$subject['id'])?>" method="post"> <div class="form-group"> <label for="email">Name:</label> <input type="text" class="form-control" name="name" required value="<?= old('name',$subject['name']) ?>"> <!-- Error --> <?php if( $validation->getError('name') ) {?> <div class='alert alert-danger mt-2'> <?= $error = $validation->getError('name'); ?> </div> <?php }?> </div> <div class="form-group"> <label for="pwd">Description:</label> <textarea class="form-control" name="description" required><?= old('description',$subject['description']) ?></textarea> <!-- Error --> <?php if($validation->getError('description')) {?> <div class='alert alert-danger mt-2'> <?= $error = $validation->getError('description'); ?> </div> <?php }?> </div> <button type="submit" class="btn btn-success" name="submit">Submit</button> </form> </div> </div> <?= $this->endSection() ?>
7. Run the project
- Navigate to the project using Command Prompt if you are on Windows or terminal if you are on Mac or Linux, and
- Execute “php spark serve” command.
php spark serve
- Run
http://localhost:8080
in the web browser.
8. Output
9. Conclusion
I hope this tutorial, helps you to implement CRUD in your project.
If you found this tutorial helpful then don't forget to share.
Thanks!
Thank you for you great post. I was looking for help in building a News section for a website I do volunteer work for. I’m new to CI 4 and I used your code and modified it to suite my needs. Your code also taught me a lot about how to structure CI 4 code, validation and much more.
Thank you!!
You’re welcome.
Hi Yogesh:
Thank you for a great and easy to follow tutorial.
I am getting errors on the redirect in the SubjectsController Controller especially in the
store function.
return redirect()->route(‘subjects/create’)
I have tried changing to subjectscontroller/create but get errors.
Now I have it set to ‘/’
Watching your project on your video works like a charm. Not sure what has changed in the code as I copied it exactly as you typed.
Appreciate your help.
Ali