Let us develop a registration and login system in CodeIgniter 4 for the customers. There will be a simple home page with options for registration and login. Customers can submit a registration form. Once registration is successful, the customer can login into the application. You will also learn form validation in CodeIgniter 4.
If you want to know how to install and configure CodeIgniter 4, you can read the topic Install and Test CodeIgniter 4 on the XAMPP Server
Folders and Files
We will be using a folder named 'projects' in D:\ drive
and installed CodeIgniter 4 in customer folder under the projects directory. So, the root directory is D:/projects/customer
.
We will have a Controller - Customer.php
, Model - ModelCustomer.php
and three views - home.php
, login.php
and signup.php
under the Views folder
Create a MySQL table to store customer details
We will use a table named 'customer' in MySQL database.
Table: customer
This table stores all customers who successfully completed the signup.
Below are the columns in this table.
- id - Primary key and auto incremented id of the customer
- name - Name of the customer
- email - Email Id of the customer
- password - Password for login
customer.sql
CREATE TABLE `customer` (
`id` int(11) NOT NULL,
`name` varchar(100) NOT NULL,
`email` varchar(100) NOT NULL,
`password` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
ALTER TABLE `customer`
ADD PRIMARY KEY (`id`);
ALTER TABLE `customer`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=1;
Write Model code (ModelCustomer.php)
We will select all the rows from the customer table. Below is the model code, keep ModelCustomer.php
in app/Models folder.
app/Models/ModelCustomer.php
<?php
namespace App\Models;
use CodeIgniter\Model;
class ModelCustomer extends Model{
protected $table = 'customer';
protected $primaryKey = 'id';
protected $allowedFields = ['name','email','password'];
}
$table
is used to indicate that the model will primarily use this table. However, you can use other tables also in the query.
Write Controller code (Customer.php)
Our controller will have an index()
method, signup()
method, login()
method and logout()
method. See the code below at the beginning of the controller:
<?php
namespace App\Controllers;
use CodeIgniter\Controller;
use App\Models\ModelCustomer;
class Customer extends Controller {
protected $model;
public function __construct() {
helper(['form', 'url']);
$this->model = new ModelCustomer();
}
public function index() {
echo view('home');
}
}
Load the form and url helpers in the constructor method. Then create an instance of the model. Home page screen is given below:
We will add the methods for Signup, Login and Logout in the controller.
Controller Method signup()
This method is called when the user clicks the Signup link on the home page. If the form is submitted, it validates the input fields. If the validation is successful, this method inserts the data into the database table. Let's see the code for signup()
method.
public function signup() {
$element = [];
$element['succ_msg'] = "";
$element['err_msg'] = "";
if ($this->request->getMethod() === 'post') {
$rules = [
'name' => [
'label' => 'Name',
'rules' => 'trim|required',
],
'email' => [
'label' => 'Email Id',
'rules' => 'trim|required|valid_email|is_unique[customer.email]',
],
'password' => [
'label' => 'Password',
'rules' => 'required',
],
'conf_pwd' => [
'label' => 'Confirm Password',
'rules' => 'required|matches[password]',
]
];
$errors = [
'name' =>[
'required' => '{field} is required'
],
'email' => [
'required' => '{field} is required',
'valid_email' => 'This is not a valid email address',
'is_unique' => 'This email id already registered'
],
'password' => [
'required' => '{field} is required'
],
'conf_pwd' => [
'required' => '{field} is required',
'matches' => '{field} does not match with Password'
],
];
if (!$this->validate($rules, $errors)) {
echo view('signup',$element);
}
else {
// validations are successful, go for signup
$name = $this->request->getPost('name');
$email = $this->request->getPost('email');
$password = $this->request->getPost('password');
$password = password_hash($password,PASSWORD_DEFAULT);
$data = array('name'=>$name, 'email'=>$email, 'password'=>$password);
$result = $this->model->save($data);
if ($result){
$msg = 'Signup successful, please <a href="/customer/login">login</a> with your email id and password';
$element['succ_msg'] = $msg;
}
else{
$msg = "Error in Signup";
$element['err_msg'] = $msg;
}
echo view('signup',$element);
}
}
else {
echo view('signup', $element);
}
} // end of method signup
For validating input fields, rules are defined using $rules
array. For details on how to do form validation in CodeIgniter 4, you can read the topic How to Do Form Validation With Custom Rule in CodeIgniter4.
$this->model->save()
method will insert the row into the database table.
Controller Method login()
Method login()
is called when the user clicks on the Login link in the Home page. On successful login, it redirects the user to the home page where it shows a welcome message and a logout option, otherwise, it reloads login view with the error message. Let's see the code:
<?php
public function login(){
$session = session();
if ($this->request->getMethod() === 'post') {
$email = $this->request->getPost('email');
$password = $this->request->getPost('password');
// validate fields
$rules = [
'email' => [
'label' =>'Email Id',
'rules' => 'trim|required'
],
'password' => [
'label' => 'Password',
'rules' => 'required',
]
];
$errors = [
'email' => [
'required' => '{field} is required',
],
'password' => [
'required' => '{field} is required'
],
];
if (!$this->validate($rules, $errors)) {
// validation not passed, so load the form again
echo view('login');
}
else {
$result = $this->model->where('email', $email)->first();
if($result){
$pass = $result['password'];
$verify_pass = password_verify($password, $pass);
if ($verify_pass) {
$sess_array = [
'email' => $result['email'],
'name' => $result['name'],
];
$session->set($sess_array);
return redirect()->to('/customer');
}
else {
$session->setFlashdata('msg', 'Invalid password entered');
echo view('login');
}
}
else {
$session->setFlashdata('msg', 'Email Id not registered');
echo view('login');
}
}
}
else {
echo view('login');
}
} // end of method login
It uses an array to store the name and email in the session so that the name and email can be used anywhere in the application.
Controller Method logout()
Method logout()
deletes the session and redirects the user to the home page. See below:
public function logout() {
$session = session();
$session ->destroy();
return redirect()->to('/customer');
}
So, these were our controller methods, now let's see the Views in next step.
Write Views (home.php, signup.php, login.php)
There will be three views for the home page, signup page and login page. Additionally, there will be a custom CSS file and a small piece of JavaScript for showing/hiding password in the login page. Let us take a look at them one by one.
View for Home Page
Our home page is simple, it just displays two links, one for signup and the other for login if the customer is not logged in. But when the customer is logged in, it will display a welcome message with the name of the customer and a logout link. Below are the screens for before login and after login:
Before Login
After Login
app/Views/home.php
<!DOCTYPE html>
<html lang="en">
<head>
<title>Customer Signup & Login</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<link rel="stylesheet" href="/assets/css/style.css">
</head>
<body>
<?php $session = session();?>
<div class="container">
<h1>You are at Home Page </h1>
<div class="welcome-user">
<?php if ($session->get('name')) { ?>
<h2> <?php echo "Welcome ".$session->get('name');?></h2>
<a class="user" href="/logout">Logout</a>
<?php } else { ?>
<a id = "signup" href="/signup">Signup</a>
<a class="user" id = "login" href="/login">Login</a>
<?php } ?>
</div>
</div>
</body>
</html>
View for Signup Page
The signup page will display a form for the customer to fill out and submit. It has the name, email id, password and confirm password fields and a submit button.
app/Views/signup.php
<!DOCTYPE html>
<html lang="en">
<head>
<title>Customer Signup</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<link rel="stylesheet" href="/assets/css/style.css">
</head>
<body>
<div class="container">
<h2>Customer Signup</h2>
<p class="error "><?= $err_msg ?></p>
<p class="success"><?= $succ_msg ?></p>
<?php $validation = \Config\Services::validation(); ?>
<?= session()->getFlashdata('error') ?>
<form id ="frm" action = "/customer/signup" method = "post">
<?= csrf_field() ?>
<div class="form-group col-md-12">
<label>Name</label>
<input type = "text" name="name" id = "name" class="form-control" maxlength="100" value="<?php echo set_value('name');?>" placeholder="Enter Your Name">
<span class="error"><?= $validation->getError('name');?> </span>
</div>
<div class="form-group col-md-12">
<label>Email Id</label>
<input type = "text" name="email" id = "email" class="form-control" maxlength="100" value="<?php echo set_value('email');?>" placeholder="Enter Your Email">
<span class="error"><?= $validation->getError('email');?> </span>
</div>
<div class="form-group col-md-12">
<label>Password</label>
<input type = "password" name="password" id = "password" class="form-control" placeholder="Enter a Password">
<span class="error"><?= $validation->getError('password');?> </span>
</div>
<div class="form-group col-md-12">
<label>Confirm Password</label>
<input type = "password" name="conf_pwd" id = "conf_pwd" class="form-control" placeholder="Enter Password again">
<span class="error"><?= $validation->getError('conf_pwd');?> </span>
</div>
<div class="col-md-12 text-center">
<input type ="submit" name="signup" class="btn btn-primary" value="Submit">
<a href = "/customer" class="btn btn-danger" name="login">Cancel</a>
</div>
</form>
</div>
</body>
</html>
Note that csrf_field()
is added for CSRF protection and related error will be displayed using session()->getFlashdata('error')
. To enable CSRF protection for post requests, update app/Config/Filters.php
to add csrf for post in $methods
property.
public $methods = ['post' => ['csrf'],];
View for Login Page
Login page will have email_id and password as input fields. See the below code:
app/Views/login.php
<!DOCTYPE html>
<html lang="en">
<head>
<title>Customer Login</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<link rel="stylesheet" href="/assets/css/style.css">
<script src="/assets/js/scripts.js"></script>
</head>
<body>
<div class="container">
<h2>Customer Login</h2>
<?php $validation = \Config\Services::validation(); ?>
<form id ="frm" action = "/customer/login" method = "post">
<?= csrf_field() ?>
<p class="error">
<?php if (session()->getFlashdata('msg')) {
echo session()->getFlashdata('msg');
}?>
</p>
<div class="form-group col-md-12">
<label>Email Id</label>
<input type = "text" class="form-control" name="email" id = "email" value="<?php echo set_value('email')?>" placeholder ="Enter your Email Id">
<span class="error"><?= $validation->getError('email');?> </span>
</div>
<div class="form-group col-md-12">
<label>Password</label>
<input type = "password" class="form-control" name="password" id = "password" placeholder ="Enter Password">
<span class="error"><?= $validation->getError('password');?> </span>
</div>
<div class="form-group col-md-12 tgl-pwd">
<input type="checkbox" class="check" onclick="togglePwd()">Show Password
</div>
<div class="form-group col-md-12 login-btn">
<button type="submit" class="btn btn-primary" name="login">Login</button>
<a href = "/customer" class="btn btn-danger" name="login">Cancel</a>
</div>
</form>
</div>
</body>
</html>
Here, we have included a JavaScript file scripts.js
. We will use the JavaScript function for the "Show Password" checkbox. When the user clicks on it, it calls a JavaScript function togglePwd()
written in scripts.js
.
Below is the code for togglePwd()
function:
scripts.js
function togglePwd() {
var pwd = document.getElementById("password");
if (pwd.type === "password")
pwd.type = "text";
else
pwd.type = "password";
}
This function changes the input type of the password field in the login page, from "password" to "text" and vice versa.
Let me give the stylesheet I created for all these views.
style.css
* {box-sizing: border-box;
}
.container{
min-height: 700px;
}
h1,h2 {
margin-top: 50px;
text-align: center;
}
.welcome-user {
text-align: center;
font-size: 20px;
}
.user{
padding-left: 35px;
}
.login{
text-align: center;
font-size: 20px;
}
#frm {
margin: 50px auto;
padding-bottom: 30px;
padding-top: 20px;
border: 1px solid #09168d;
border-radius: 7px;
background: #fff;
width: 47%;
}
.tgl-pwd{
padding: 0;
}
.check {
width: 10%;
height: 20px;
}
label{
font-weight: bold;
}
.login-btn{
text-align: center;
}
p.error{
color: red;
text-align: center;
font-size: 20px;
}
p.success{
color: green;
text-align: center;
font-size: 20px;
}
span.error{
color: red;
text-align: left;
}
Update Configuration files and Test the Application
Below is a section of app/Config/App.php
, set $baseURL
and $index Page as given below:
public $baseURL = 'http://localhost:8080/';
public $indexPage = '';
Update database setup file (app/Config/Database.php) for database name, userid and password.
public $default = [
'DSN' => '',
'hostname' => 'localhost',
'username' => 'root',
'password' => '',
'database' => 'demo',
'DBDriver' => 'MySQLi',
'DBPrefix' => '',
'pConnect' => false,
'DBDebug' => (ENVIRONMENT !== 'production'),
'charset' => 'utf8',
'DBCollat' => 'utf8_general_ci',
'swapPre' => '',
'encrypt' => false,
'compress' => false,
'strictOn' => false,
'failover' => [],
'port' => 3306,
];
Update Routes (app/Config/Routes.php)
$routes->setDefaultNamespace('App\Controllers');
$routes->setDefaultController('Customer');
$routes->setDefaultMethod('index');
$routes->setTranslateURIDashes(false);
$routes->set404Override();
$routes->setAutoRoute(true);
/*
* --------------------------------------------------------------------
* Route Definitions
* --------------------------------------------------------------------
*/
// We get a performance increase by specifying the default
// route since we don't have to scan directories.
$routes->get('/', 'Customer::index');
$routes->get('/signup', 'Customer::signup');
$routes->get('/login', 'Customer::login');
$routes->get('/logout', 'Customer::logout');
Update .env to set the environment as development. This file is in root directory.
Copy of env to .env
. Update the environment from production to development as below:
# CI_ENVIRONMENT = production
CI_ENVIRONMENT = development
Test the Application
You can test the application using the built-in PHP server. Run php spark serve
from the command prompt. This will start the server in port 8080.
Run http://localhost:8080/. This will open the home page.
Click on Signup and do a successful signup. Then login using the email id and password as given during signup. You should be able to login successfully and see the message displayed on the screen with the name and logout link.
Conclusion
Developing Registration and Login forms can help you understand CodeIgniter 4 if you have just started working with it. We have done form validation, used session library and used database select/insert. I hope this will help you in your project development.
Post a Comment