PHP CodeIgniter 4 - CRUD Application Tutorial
In this tutorial, we will tackle about creating a CRUD (Create, Read, Edit, and Delete) Operation in PHP CodeIgniter 4. CRUD Operations is one the most common function or feature of the web applications that contains a dynamic data. Here, you will learn how to retrieve, store, update, and delete data into the Database using the PHP CodeIgniter Framework. I will be providing a simple web application source code below that contains a CRUD Opertaion.
What is CodeIgniter?
CodeIgniter is an open-source software rapid development web framework for developing or building a PHP Projects/Applications. It was built for developers to create a full-featured web applications.
Getting Started
Before we proceed to the coding part of this tutorial, Download and Install XAMPP web server first. The XAMPP web server contains a Apache HTTP Server to run our PHP Script in your local machine and MariaDB Database for storing our data.
Setting up the XAMPP
- Open the XAMPP's php.ini file and locate the ;extension=intl extension.
- Remove the (;) semicolon to enable the said extension.
- Lastly, open your XAMPP's Control Panel and start the Apache and MySQL Servers.
Creating the Database
- Open your preferred Browser such as Chrome and browse http://localhost/phpmyadmin.
- Create a new database naming dummy_db.
- Navigate the page into the SQL page and paste the provided SQL Script below for the creation of the database tables and column.
Setting up the CodeIgniter
- Download the CodeIgniter version 4 to their official site. https://codeigniter.com/download
- Next, extract the CodeIgniter 4 zip file.
- Open your terminal or command prompt and change your directory inside the CodeIgniter 4 folder.
- Excecute the following command:
php spark server
- Browse the provided link into your browser to check if it works. i.e http://localhost:8080
Next, open your CodeIgniter 4 source code folder into your preferred text-editor such as Notepad++, Sublime Text, VS Code, etc.
Setting Up the Database Credentials
Open the Database.php file under the app >> Config >> directory in to your text-editor. Locate the $default variable on the file. Configure your database just like below.
- <?php
- public $default = [
- 'DSN' => '',
- 'hostname' => 'localhost',
- 'username' => 'root',
- 'password' => '',
- 'database' => 'dummy_db',
- 'DBDriver' => 'MySQLi',
- 'DBPrefix' => '',
- 'pConnect' => false,
- 'DBDebug' => (ENVIRONMENT !== 'production'),
- 'charset' => 'utf8',
- 'DBCollat' => 'utf8_general_ci',
- 'swapPre' => '',
- 'encrypt' => false,
- 'compress' => false,
- 'strictOn' => false,
- 'failover' => [],
- 'port' => 3306,
- ];
- ?>
Configuring the Routes
Open the Routes.php file located at the app >> Config directory. Then, configure the file just like below.
- <?php
- namespace Config;
- // Create a new instance of our RouteCollection class.
- $routes = Services::routes();
- // Load the system's routing file first, so that the app and ENVIRONMENT
- // can override as needed.
- require SYSTEMPATH . 'Config/Routes.php';
- }
- /*
- * --------------------------------------------------------------------
- * Router Setup
- * --------------------------------------------------------------------
- */
- $routes->setDefaultNamespace('App\Controllers');
- $routes->setDefaultController('Main');
- $routes->setDefaultMethod('index');
- $routes->setTranslateURIDashes(false);
- $routes->set404Override();
- // The Auto Routing (Legacy) is very dangerous. It is easy to create vulnerable apps
- // where controller filters or CSRF protection are bypassed.
- // If you don't want to define all routes, please use the Auto Routing (Improved).
- // Set `$autoRoutesImproved` to true in `app/Config/Feature.php` and set the following to true.
- //$routes->setAutoRoute(false);
- /*
- * --------------------------------------------------------------------
- * Route Definitions
- * --------------------------------------------------------------------
- */
- // We get a performance increase by specifying the default
- // route since we don't have to scan directories.
- $routes->get('/', 'Main::index');
- $routes->get('/main/(:any)', 'Main::$1');
- $routes->post('/main/(:any)', 'Main::$1');
- /*
- * --------------------------------------------------------------------
- * Additional Routing
- * --------------------------------------------------------------------
- *
- * There will often be times that you need additional routing and you
- * need it to be able to override any defaults in this file. Environment
- * based routes is one such time. require() additional route files here
- * to make that happen.
- *
- * You will have access to the $routes object within that file without
- * needing to reload it.
- */
- require APPPATH . 'Config/' . ENVIRONMENT . '/Routes.php';
- }
Creating the Model
Next, create a new model naming CrudModel.php and save the file under the app >> Models directory. Then, copy and paste the provided PHP script below and save it.
- <?php
- namespace App\Models;
- use CodeIgniter\Model;
- class CrudModel extends Model
- {
- // Table
- protected $table = 'contact_details';
- // allowed fields to manage
- protected $allowedFields = ['firstname', 'middlename','lastname', 'gender', 'contact', 'email', 'address'];
- }
Creating the Interface
First, create the template files. The template files is the PHP Files that contains the script for tha main template of your application. Create a new folder naming templates under app >> Views. Then, create and save the following PHP Files.
header.php- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <!-- Styles -->
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g==" crossorigin="anonymous" referrerpolicy="no-referrer" />
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
- <!--end of Styles -->
- <!-- Scritps -->
- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
- <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/js/all.min.js" integrity="sha512-6PM0qYu5KExuNcKt5bURAoT6KCThUmHRewN3zUFNaoI6Di7XJPTMoT6K0nsagZKk2OB4L7E3q1uQKHNHd4stIQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
- <!-- end of Scritps -->
- </head>
- <body>
- <!-- Top Navigation Bar -->
- <nav class="navbar navbar-dark navbar-expand-lg bg-dark bg-gradient">
- <div class="container">
- <a class="navbar-brand" href="<?= base_url() ?>">CI4 Simple CRUD</a>
- <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
- <span class="navbar-toggler-icon"></span>
- </button>
- <div class="collapse navbar-collapse" id="navbarNavDropdown">
- <ul class="navbar-nav">
- <li class="nav-item">
- <a class="nav-link active" aria-current="page" href="<?= base_url() ?>">Home</a>
- </li>
- <li class="nav-item">
- <a class="nav-link" href="<?= base_url('main/create') ?>"><i class="fa fa-plus-square"></i> Add New</a>
- </li>
- <li class="nav-item">
- <a class="nav-link" href="<?= base_url('main/list') ?>"><i class="fa fa-th-list"></i> List</a>
- </li>
- </ul>
- </div>
- <a href="https://sourcecodester.com" target="_blank" class="text-light fw-bold text-decoration-none">SourceCodester</a>
- </div>
- </nav>
- <!--End Top Navigation Bar -->
- <!-- Wrapper -->
- <div class="wrapper my-4">
- <!-- Main Container -->
- <div class="main container">
- <div class="alert alert-success rouded-0">
- <div class="d-flex">
- <div class="col-11"><?= $session->getFlashdata('success_message') ?></div>
- <div class="col-1 text-end"><a href="javascript:void(0)" onclick="$(this).closest('.alert').remove()" class="text-muted text-decoration-none"><i class="fa fa-times"></i></a></div>
- </div>
- </div>
- <?php endif ?>
- <div class="alert alert-danger rouded-0">
- <div class="d-flex">
- <div class="col-11"><?= $session->getFlashdata('error_message') ?></div>
- <div class="col-1 text-end"><a href="javascript:void(0)" onclick="$(this).closest('.alert').remove()" class="text-muted text-decoration-none"><i class="fa fa-times"></i></a></div>
- </div>
- </div>
- <?php endif ?>
- </div>
- <!-- Main Container -->
- </div>
- </body>
- </html>
Next, create the interface of the pages of the application. Create a new folder naming crud in your app >> Views directory. Then, create and save the following PHP files.
home.php- <div class="card card-outline card-primary rounded-0">
- <div class="card-header">
- <h4 class="mb-0">List of Contact</h4>
- </div>
- <div class="card-body">
- <div class="container-fluid">
- <table class="table table-stripped table-bordered">
- <colgroup>
- <col width="10%">
- <col width="40%">
- <col width="40%">
- <col width="10%">
- </colgroup>
- <thead>
- <tr class="bg-gradient bg-primary text-light">
- <th class="py-1 text-center">#</th>
- <th class="py-1 text-center">Name</th>
- <th class="py-1 text-center">Gender</th>
- <th class="py-1 text-center">Action</th>
- </tr>
- </thead>
- <tbody>
- <?php $i = 1; ?>
- <?php foreach($list as $row): ?>
- <tr>
- <th class="p-1 align-middle text-center"><?= $i++ ?></th>
- <td class="p-1 align-middle"><?= $row->lastname.", ".$row->firstname.(!empty($row->middlename)? " ".$row->middlename:'') ?></td>
- <td class="p-1 align-middle"><?= $row->gender ?></td>
- <td class="p-1 align-middle text-center">
- <div class="btn-group btn-group-sm">
- <a href="<?= base_url('main/view_details/'.$row->id) ?>" class="btn btn-default bg-gradient-light border text-dark rounded-0" title="View Contact"><i class="fa fa-eye"></i></a>
- <a href="<?= base_url('main/edit/'.$row->id) ?>" class="btn btn-primary rounded-0" title="Edit Contact"><i class="fa fa-edit"></i></a>
- <a href="<?= base_url('main/delete/'.$row->id) ?>" onclick="if(confirm('Are you sure to delete this contact details?') === false) event.preventDefault()" class="btn btn-danger rounded-0" title="Delete Contact"><i class="fa fa-trash"></i></a>
- </div>
- </td>
- </tr>
- <?php endforeach; ?>
- <?php endif; ?>
- </tbody>
- </table>
- </div>
- </div>
- </div>
- <div class="card card-primary rounded-0">
- <div class="card-header">
- <h4 class="text-muted"><i class="far fa-plus-square"></i> Add New Contact Details</h4>
- </div>
- <div class="card-body">
- <div class="contianer-fluid">
- <form action="<?= base_url('main/save') ?>" method="POST" id="create-form">
- <input type="hidden" name="id">
- <div class="mb-3">
- <label for="" class="control-label">Fullname (first name, middle name, last name)</label>
- <div class="input-group">
- <input type="text" autofocus class="form-control form-control-border" id="firstname" name="firstname" value="<?= !empty($request->getPost('firstname')) ? $request->getPost('firstname') : '' ?>" required="required" placeholder="First Name">
- <input type="text" class="form-control form-control-border" id="middlename" name="middlename" value="<?= !empty($request->getPost('middlename')) ? $request->getPost('middlename') : '' ?>" required="false" placeholder="Middle Name (optional)">
- <input type="text" class="form-control form-control-border" id="lastname" name="lastname" value="<?= !empty($request->getPost('lastname')) ? $request->getPost('lastname') : '' ?>" required="required" placeholder="Last Name">
- </div>
- </div>
- <div class="mb-3 col-lg-6 col-md-6 col-sm-12 col-xs-12">
- <label for="gender" class="control-label">Gender</label>
- <select name="gender" id="gender" class="form-select form-select-border" required>
- <option <?= !empty($request->getPost('gender')) && $request->getPost('gender') == 'Male' ? 'selecte' : '' ?>>Male</option>
- <option <?= !empty($request->getPost('gender')) && $request->getPost('gender') == 'Female' ? 'selecte' : '' ?>>Female</option>
- </select>
- </div>
- <div class="mb-3">
- <div class="row">
- <div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
- <label for="contact" class="control-label">Contact #</label>
- <input type="text" class="form-control" id="contact" name="contact" required="required" value="<?= !empty($request->getPost('contact')) ? $request->getPost('contact') : '' ?>">
- </div>
- <div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
- <label for="email" class="control-label">Email</label>
- <input type="email" class="form-control" id="email" name="email" required="required" value="<?= !empty($request->getPost('email')) ? $request->getPost('email') : '' ?>">
- </div>
- </div>
- </div>
- <div class="mb-3 col-lg-6 col-md-6 col-sm-12 col-xs-12">
- <label for="address" class="control-label">Address</label>
- <textarea name="address" id="address" cols="30" rows="3" class="form-control" required="required"><?= !empty($request->getPost('address')) ? $request->getPost('address') : '' ?></textarea>
- </div>
- </form>
- </div>
- </div>
- <div class="card-footer text-center">
- <button class="btn btn-primary" form="create-form" type="submit"><i class="fa fa-save"></i> Save Details</button>
- <button class="btn btn-secondary" form="create-form" type="reset"><i class="fa fa-times"></i> Reset</button>
- </div>
- </div>
- <div class="card card-outline card-primary rounded-0">
- <div class="card-header">
- <div class="h4 mb-0">Contact Details</div>
- </div>
- <div class="card-body">
- <div class="container-fluid">
- <dl>
- <dt class="text-muted">Name</dt>
- <dt class="text-muted">Gender</dt>
- <dt class="text-muted">Contact #</dt>
- <dt class="text-muted">Email</dt>
- <dt class="text-muted">Address</dt>
- </dl>
- </div>
- </div>
- <div class="card-footer text-center">
- <a href="<?= base_url('main/edit/'.(isset($data['id']) ? $data['id'] : '')) ?>" class="btn btn btn-primary btn-sm rounded-0"><i class="fa fa-edit"></i> Edit</a>
- <a href="<?= base_url('main/delete/'.(isset($data['id']) ? $data['id'] : '')) ?>" class="btn btn btn-danger btn-sm rounded-0" onclick="if(confirm('Are you sure to delete this contact details?') === false) event.preventDefault()"><i class="fa fa-trash"></i> Delete</a>
- <a href="<?= base_url('main/list') ?>" class="btn btn btn-light bg-gradient-light border btn-sm rounded-0"><i class="fa fa-angle-left"></i> Back to List</a>
- </div>
- </div>
- <div class="card card-primary rounded-0">
- <div class="card-header">
- <h4 class="text-muted"><i class="far fa-edit"></i> Edit Contact Details</h4>
- </div>
- <div class="card-body">
- <div class="contianer-fluid">
- <form action="<?= base_url('main/save') ?>" method="POST" id="create-form">
- <div class="mb-3">
- <label for="" class="control-label">Fullname (first name, middle name, last name)</label>
- <div class="input-group">
- <input type="text" autofocus class="form-control form-control-border" id="firstname" name="firstname" value="<?= isset($data['firstname']) ? $data['firstname'] : '' ?>" required="required" placeholder="First Name">
- <input type="text" class="form-control form-control-border" id="middlename" name="middlename" value="<?= isset($data['middlename']) ? $data['middlename'] : '' ?>" required="false" placeholder="Middle Name (optional)">
- <input type="text" class="form-control form-control-border" id="lastname" name="lastname" value="<?= isset($data['lastname']) ? $data['lastname'] : '' ?>" required="required" placeholder="Last Name">
- </div>
- </div>
- <div class="mb-3 col-lg-6 col-md-6 col-sm-12 col-xs-12">
- <label for="gender" class="control-label">Gender</label>
- <select name="gender" id="gender" class="form-select form-select-border" required>
- <option <?= isset($data['gender']) && $data['gender'] == 'Female' ? 'selecte' : '' ?>>Female</option>
- </select>
- </div>
- <div class="mb-3">
- <div class="row">
- <div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
- <label for="contact" class="control-label">Contact #</label>
- <input type="text" class="form-control" id="contact" name="contact" required="required" value="<?= isset($data['contact']) ? $data['contact'] : '' ?>">
- </div>
- <div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
- <label for="email" class="control-label">Email</label>
- <input type="email" class="form-control" id="email" name="email" required="required" value="<?= isset($data['email']) ? $data['email'] : '' ?>">
- </div>
- </div>
- </div>
- <div class="mb-3 col-lg-6 col-md-6 col-sm-12 col-xs-12">
- <label for="address" class="control-label">Address</label>
- <textarea name="address" id="address" cols="30" rows="3" class="form-control" required="required"><?= isset($data['address']) ? $data['address'] : '' ?></textarea>
- </div>
- </form>
- </div>
- </div>
- <div class="card-footer text-center">
- <button class="btn btn-primary" form="create-form" type="submit"><i class="fa fa-save"></i> Save Details</button>
- <a class="btn btn-secondary" href="<?= base_url('main/view_details/'.(isset($data['id']) ? $data['id'] : '')) ?>"><i class="fa fa-times"></i> Cancel</a>
- </div>
- </div>
Creating the Controller
Lastly, we will create the Main Controller to our application. The controller file contain the files that processes the CRUD Operations and display our pages.On your app >> Controllers directory, create a new PHP file naming Main.php. Then, paste the following PHP Script.
- <?php
- namespace App\Controllers;
- use App\Models\CrudModel;
- class Main extends BaseController
- {
- // Session
- protected $session;
- // Data
- protected $data;
- // Model
- protected $crud_model;
- // Initialize Objects
- public function __construct(){
- $this->crud_model = new CrudModel();
- $this->session= \Config\Services::session();
- $this->data['session'] = $this->session;
- }
- // Home Page
- public function index(){
- $this->data['page_title'] = "Home Page";
- echo view('templates/header', $this->data);
- echo view('crud/home', $this->data);
- echo view('templates/footer');
- }
- // Create Form Page
- public function create(){
- $this->data['page_title'] = "Add New";
- $this->data['request'] = $this->request;
- echo view('templates/header', $this->data);
- echo view('crud/create', $this->data);
- echo view('templates/footer');
- }
- // Insert And Update Function
- public function save(){
- $this->data['request'] = $this->request;
- $post = [
- 'firstname' => $this->request->getPost('firstname'),
- 'middlename' => $this->request->getPost('middlename'),
- 'lastname' => $this->request->getPost('lastname'),
- 'gender' => $this->request->getPost('gender'),
- 'contact' => $this->request->getPost('contact'),
- 'email' => $this->request->getPost('email'),
- 'address' => $this->request->getPost('address')
- ];
- $save = $this->crud_model->where(['id'=>$this->request->getPost('id')])->set($post)->update();
- else
- $save = $this->crud_model->insert($post);
- if($save){
- $this->session->setFlashdata('success_message','Data has been updated successfully') ;
- else
- $this->session->setFlashdata('success_message','Data has been added successfully') ;
- return redirect()->to('/main/view_details/'.$id);
- }else{
- echo view('templates/header', $this->data);
- echo view('crud/create', $this->data);
- echo view('templates/footer');
- }
- }
- // List Page
- $this->data['page_title'] = "List of Contacts";
- $this->data['list'] = $this->crud_model->orderBy('date(date_created) ASC')->select('*')->get()->getResult();
- echo view('templates/header', $this->data);
- echo view('crud/list', $this->data);
- echo view('templates/footer');
- }
- // Edit Form Page
- public function edit($id=''){
- $this->session->setFlashdata('error_message','Unknown Data ID.') ;
- return redirect()->to('/main/list');
- }
- $this->data['page_title'] = "Edit Contact Details";
- $qry= $this->crud_model->select('*')->where(['id'=>$id]);
- $this->data['data'] = $qry->first();
- echo view('templates/header', $this->data);
- echo view('crud/edit', $this->data);
- echo view('templates/footer');
- }
- // Delete Data
- public function delete($id=''){
- $this->session->setFlashdata('error_message','Unknown Data ID.') ;
- return redirect()->to('/main/list');
- }
- $delete = $this->crud_model->delete($id);
- if($delete){
- $this->session->setFlashdata('success_message','Contact Details has been deleted successfully.') ;
- return redirect()->to('/main/list');
- }
- }
- // View Data
- public function view_details($id=''){
- $this->session->setFlashdata('error_message','Unknown Data ID.') ;
- return redirect()->to('/main/list');
- }
- $this->data['page_title'] = "View Contact Details";
- $qry= $this->crud_model->select("*, CONCAT(lastname,', ',firstname,COALESCE(concat(' ', middlename), '')) as `name`")->where(['id'=>$id]);
- $this->data['data'] = $qry->first();
- echo view('templates/header', $this->data);
- echo view('crud/view', $this->data);
- echo view('templates/footer');
- }
- }
That's it! You can now test the source code and see if it meets our goal for this tutorial which is to have a Simple Application with CRUD Operation using the PHP CodeIgniter 4 Framework. If there's an error occurred on your end please review the changes in your source code and differentiate it from the source code I provided above. you can also download the working source code I created for this tutorial. The dowload button is located below this article.
DEMO VIDEO
That's the end of this tutorial. I hope this will help you with what you are looking for and you'll find this useful for your future PHP Projects using CodeIgniter 4 Framework. Explore more on this website for more Tutorials and Free Source Codes.
Enjoy Coding :)
Add new comment
- 10211 views