Codeigniter Framework Training Note

September 18, 2019

note: quick and lazy training note.

Installation and Configuration

In this section we will show the steps to get CodeIgniter up and running on the development server. We assume that the Webserver has been configured.

- [Download CodeIgniter](https://www.codeigniter.com/)
- Extract and rename downloaded file to project name (ie... projectname)
- Copy to Webserver's Document Root.

- Create MySql database for project
- Update projectname/application/config/database.php configuration file according to your database setup.
- Browse to [Project](http://localhost/projectname)

Create Read Update Delete (CRUD)

CRUD is something we have in most application. We will go through the steps to create a simple CRUD operation. In order to do this, first create a ‘cities’ table in the database. We will create a register of cities to be used in our application. For this application, use the SQL below to create cities table and with it we insert a sample data after.

CREATE TABLE cities (
    id int(11) NOT NULL AUTO_INCREMENT,
    name varchar(128) NOT NULL,
    description text NOT NULL,
    PRIMARY KEY (id)
);

INSERT INTO cities (name, description) VALUE ('KT', 'Kuala Terengganu');

After creating the table, we need to create a Model called Cities_model for the CodeIgniter application to talk to the database. So we create a new file ‘applications/models/Cities_model.php’ with the following content:

<?php
class Cities_model extends CI_Model {
        public function __construct()
        {
                $this->load->database();
        }
}

With the database and Model all set up, we can continue creating a listing of cities,a form to add data to the cities table, updating those records and deleting them.

Optionally, we can ask CodeIgniter to load globally by editing ‘libraries’ section in the application/config/autoload.php file. It would be set as below:

$autoload['libraries'] = array('database', 'session');

In the above code, we autoload session and database libraries so they can be used without loading in each controller files.

City Listing

To show a listing of all cities we will need to code a Controller to get the request from the browser, an index function in the controller to process the request and a view to display the code.

Before that, we will need to create a function to retrieve all cities from the database. Since we are talking to the database, the code will be placed in the model. Open up Cities_model.php and add the following below in the Model class:

public function list_cities()
{

    $query = $this->db->get('cities');
    return $query->result_array();
}

The list_cities function calls the class $this->db which loads the database configuration in application/config/database.php. CodeIgniter’s DB class have many functions related to talking to the database. One of the methods provided is DB::get() which retrieves results from the table specified. In this case $this->db->get(‘cities’) retrieves all record from table ‘cities’.

Later in the training we will show how to filter records to be retrieved as we usually do using SQL or the Query Builder.

For now we will then continue to create the Controller which will receive user request, call our newly created Model function list_cites() and display the list using the View we will code after.

Create a new controller file “application/controllers/Cities.php” with the following code:

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Cities extends CI_Controller {

    public function __construct()
    {
            parent::__construct();
            $this->load->model('Cities_model');
    }


    public function index() {

        $cities = $this->Cities_model->list_cities();

        $this->load->view('cities/index', [ 'cities' => $cities ]);
    }

}

The index() method first calls our Cities_model’s list_cities() method that will return the records fetched into $cities. We then call CI’s view and pass the value to the view as the second parameter.

Let’s create our view file “application/views/cities/index.php”.

<table>
    <caption></caption>
    <thead>
        <tr>
            <th>Name</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <?php foreach($cities as $city) { ?>
        <tr>
            <td><?php echo $city['name'] ?></td>
            <td><?php echo $city['description'] ?></td>
        </tr>
        <?php } ?>
    </tbody>
</table>

In the view file, we cycle through each record retrieved and echoes it in a designated table. As we can see CodeIgniter uses straightforward PHP and HTML for this purpose.

Create New City Record

To create a new city record, we must have a form to fill. Create a “application/views/cities/create.php” and fill it with the code below

<form 
  method="POST" action="<?php echo base_url()?>Cities/store" >
    <div>
        <label>Name</label>
        <div>
            <input type="text" id="name" name="name" >
        </div>
    </div>
    <div>
        <label>Description</label>
        <div>
            <textarea id="description" name="description"></textarea>
        </div>
    </div>


    <hr>
    <div>
        <label></label>
        <div class="uk-form-controls">
            <input type="submit" id="submit" name="submit" value="Submit">
        </div>
    </div>
</form>

In order to open this form, we will have to create the method in the Cities controller file.

public function create() {

    echo $this->load->view('cities/create');
}

We will create another function to retrieve the values that the form submitted. After saving the record, we redirect back to cities listing.

public function store()
{
    $this->load->model('Cities_model');

    $data['name'] = $this->input->post('name');
    $data['description'] = $this->input->post('description');

    $this->Cities_model->create($data);

    redirect('/Cities/index');
}

To complete this function we will need to add into the Cities_model a create() function which goes as below:

public function create( $data ) {


    return $this->db->insert( 'cities' , $data );

}

create() calls the DB function insert which takes the table as the first parameter and the data which is to be inserted as the second parameter. It will map the table fields with the data based on the index of array $data.

Updating Cities Record

To update the city record, we will need to retrieve the value of the created record and place them in a form to be edited. To retrieve the record, we will code a function in Cities_model:

public function getCity($city_id) {

    $query = $this->db->from( 'cities' );
    $query->where( 'id', $city_id);

    $result = $query->get();

    if($result) {
        return $result->row_array();
    } else {
        return [];
    }

}

To call this function, we create a function in Controller to get the record, call the appropriate view and then another function to update the record with submitted information:

public function edit($id)
{
    $this->load->model('Cities_model');

    $data['city'] = $this->Cities_model->get($id);

    $this->load->view('/Cities/edit', $data);
}

public function update($id)
{
    $this->load->model('Cities_model');

    $data['name'] = $this->input->post('name');
    $data['description'] = $this->input->post('description');

    $this->Cities_model->update($data, $id);

    redirect('/Cities/index');
}

We need to go back to the Cities_model and add update() function to be used to save the data.

public function update( $data, $id ) {

    $where = "id = " . $id;
    $sql = $this->db->update_string( 'cities' , $data, $where);

    return $this->db->query($sql);

}

We now create the update view in “application/views/cities/update.php” :

<form 
  method="POST" action="<?php echo base_url()?>Cities/update/<?php echo $city['id'] ?>" >
    <div>
        <label>Name</label>
        <div>
            <input type="text" id="name" name="name" value="<?php echo $city['name'] ?>">
        </div>
    </div>
    <div>
        <label>Description</label>
        <div>
            <textarea id="description" name="description"><?php echo $city['description'] ?></textarea>
        </div>
    </div>

    <hr>
    <div>
        <label></label>
        <div class="uk-form-controls">
            <input type="submit" id="submit" name="submit" value="Submit">
        </div>
    </div>
</form>

This form is similar to create form but it now has values assigned to each form item.

Deleting City Record

To delete a city record we go back to Cities_model and add the below function:

public function delete($id) {
    return $this->db->delete( 'cities', array('id' => $id) );
}

To access this function we create a Controller function in Cities Controller to call this function:

public function delete($id)
{
    $this->load->model('Cities_model');
    $this->Cities_model->delete($id);

    redirect('/Cities/index')
}

We have completed the CRUD and now we will slightly modify the cities/index.php view file to create links for to these functions:

<table>
    <caption>Cities <a href="<?php echo base_url('/Cities/create/' )?>">New</a></caption>
    <thead>
        <tr>
            <th>Name</th>
            <th>Description</th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        <?php foreach($cities as $city) { ?>
        <tr>
            <td><?php echo $city['name'] ?></td>
            <td><?php echo $city['description'] ?></td>
            <td>
                [ <a href="<?php echo base_url('/Cities/edit/' . $city['id'] )?>">Edit</a> ]
                [ <a href="<?php echo base_url('/Cities/delete/' . $city['id'] )?>">Delete</a> ]</td>
        </tr>
        <?php } ?>
    </tbody>
</table>

Form Validation

In order to make sure data is correctly filled in by the user, we need to validate what is sent is correct. CodeIgniter provides this feature as a library to be used generally in the controller.

Let us open up the Cities Controller file and update the create function

public function store()
{
    $this->load->model('Cities_model');
    $this->load->helper(array('form', 'url'));
    $this->load->library('form_validation');

    $this->form_validation->set_rules('name', 'Name', 'required');
    $this->form_validation->set_rules('description', 'Description', 'required');

    if ($this->form_validation->run() == FALSE) 
    {
        redirect('Cities/create');
    } else {
        $data['name'] = $this->input->post('name');
        $data['description'] = $this->input->post('description');

        $this->Cities_model->create($data);
        redirect('/Cities/index');

    }


}

Now the store() function will validate the values first instead of directly creating a new Cities record without first checking the values sent. When the validation runs and is not successful (values having invalid success conditions).

In the “application/views/cities/create.php”, let us display the validation errors. Open up the file and add the code below before the

tag.

<?php echo validation_errors(); ?>

Session

CodeIgniter provides a simple to use library to talk with PHP session. To initialize the library, we can use the code below in the controller:

$this->load->library('session');

This loads the Session library into the controller and the library is available as

$this->session

To add data to session you can use the below syntax:

$data = array('item' => 'My Value');
$this->session->set_userdata($data);
//OR
$this->session->set_userdata('some_name', 'some_value');

There are a few ways to refer to values we just set in the session. One can use:

$_SESSION['item']
//OR
$this->session->item
//OR
$this->session->userdata('item');

To remove data from session, we can just unset from PHP’s session variable like so:

unset($_SESSION['some_name']);
//OR
$this->session->unset_userdata('some_name');

Database Operations

Selecting data.

$limit = 20;
$offset = 0;
$query = $this->db->get('mytable', $limit, $offset);
echo $this->db->last_query();

Query builder

$this->db->where('first_name', "Rico" );
$this->db->where('last_name', "Sam" );

or $this->db->where( [‘first_name’=> “B”, ‘last_name’ => “C”, ‘emp_no’ => “D” ] );

To group a query

$this->db->group_start()
    $this->db->where('first_name', "Rico" );
    $this->db->where('last_name', "Sam" );
$this->db->group_end()

Usually db::get($tablename) will reset the query but if the need comes, we can reset the query builder manually using:

$this->db->reset_query();

For LIKE statements, below are examples

$this->db->like('first_name','Abu');

Occasionally we want to make sure there wont be repeatitive results:

$this->db->distinct();

Inserting data

$employee = [
    'emp_no' => '01934553',
    'first_name' => 'Abu',
    'last_name' => 'Samaha',
    'gender' => 'm',
    'hire_date' => '2018-01-01'

];  

$this->db->insert('employees', $employee);

Or we can insert a few records at a time.

$employee1 = [
    'emp_no' => '01934553',
    'first_name' => 'Abu',
    'last_name' => 'Samaha',
    'gender' => 'm',
    'hire_date' => '2018-01-01'

];

$employee2 = [
    'emp_no' => '01934554',
    'first_name' => 'Ali',
    'last_name' => 'Sarip',
    'gender' => 'm',
    'hire_date' => '2018-02-02'
];

$this->db->insert_batch('employees', [$employee1, $employee2]);

Updating is almost similar

$data = array(
        'first_name' => 'Ali',
        'last_name' => 'Arip',
        'gender' => 'm'
);

$this->db->where('emp_no', '01934554');
$this->db->update('employees', $data);

or

$this->db->update('employees', $data, "emp_no = '01934554'");

For batch updates, each record must have an primary field to be used as reference for the update to be done correctly. The primary key is sent as a string to the third parameter for the update_batch() function

    //record
    $user  = [
        [
            'id' => 1,
            'name' => 'hizam',
            'password' => 'abc123'
        ],
        [
            'id' => 2,
            'name' => 'ramzai',
            'password' => 'abc124'
        ]
    ];

    $this->db->update_batch('users', $user,'id');

Deleting records

$this->db->where('id', $id);
$this->db->delete('mytable');

Multiple records in multiple table

$tables = array('salaries', 'titles', 'current_dept_emp');
$this->db->where('emp_no', '01934554');
$this->db->delete($tables);

Transactions can be done like so:

$this->db->trans_begin();

$this->db->query('AN SQL QUERY...');
$this->db->query('ANOTHER QUERY...');
$this->db->query('AND YET ANOTHER QUERY...');

if ($this->db->trans_status() === FALSE)
{
        $this->db->trans_rollback();
}
else
{
        $this->db->trans_commit();
}

$this->db->trans_start();
$this->db->query('create employee...');
$this->db->query('assign to department...');
$this->db->query('set wage...');
$this->db->trans_complete();

if ($this->db->trans_status() === FALSE)
{
    // generate an error... or use the log_message() function to log your error
}

To export to csv it is easy with CI’s provided functions

$this->load->database();
$this->load->dbutil();
$this->load->helper('download');

//retrieve 20 employee records as example
$employee = $this->db->get('employees', 20);
force_download('mycsv.csv',$this->dbutil->csv_from_result($employee));

Sending Email Notification

Sending email via codeigniter is made easy by using it’s own config and mail library

//first load the email library
$this->load->library('email');

//prepare the configurations needed by the email library
$config['protocol']    = 'smtp';
$config['smtp_host']    = 'smtp.mailtrap.io';
$config['smtp_port']    = '465';
$config['smtp_timeout'] = '7';
$config['smtp_user']    = '1234567848343';
$config['smtp_pass']    = '12345667891011';
$config['charset']    = 'utf-8';
$config['newline']    = "\r\n";
$config['mailtype'] = 'text'; // or html
$config['validation'] = TRUE; // bool whether to validate email or not      

//initialize email
$this->email->initialize($config);

//provide recipient/sender information to be sent with email
$this->email->from('me@example.com', 'Hizam');
$this->email->to('zam3858@gmail.com');
//$this->email->cc('another@another-example.com');
//$this->email->bcc('them@their-example.com');

//the email content
$this->email->subject('Email Test');
$this->email->message('Testing the email class.');

//attempt to send the email
$this->email->send();

//print the result
echo $this->email->print_debugger();

Pagination

$config = array();
    $config["base_url"] = base_url() . "welcome/example1";
    $config["total_rows"] = $this->Countries->record_count();
    $config["per_page"] = 20;
    $config["uri_segment"] = 3;

    $this->pagination->initialize($config);

    $page = ($this->uri->segment(3)) ? $this->uri->segment(3) : 0;
    $data["results"] = $this->Countries->
        fetch_countries($config["per_page"], $page);
    $data["links"] = $this->pagination->create_links();

    $this->load->view("example1", $data);

Routing

Routing in codeigniter by defaults reads from the request URL, breaks the request into segments separated by slash ‘/’.

The first segment tells codeigniter which controller to use, the second segment tells codeigniter which method in the controller to call and the other segments are translated into parameters for the method. For example:

localhost/City/view/1

//Segment 1: City
//Segment 2: view
//Segment 3: 1

This will then call the City controller in application/controllers/City.php and run the function view with 1 as the value for the first parameter.

If the controller starts with an uppercase such as Cityhunter, in the url we can refer to it with all lowercase ‘cityhunter’. If the controller is camelcase, for example, CityHunter, the url must use exact case as the name for example “http://localhost/CityHunter/"

If we do not want to use this default behaviour, the routes file located in application/config/routes.php is where we define our custom routes.

// http://localhost/in-the-url 
// will call Targetcontroller's index function
$route['in-the-url'] = "Targetcontroller";

For the parameters, we can add pattern in to the uri definition like so:

//the (:num) tells a number should be inserted here.
$route['cities/(:num)'] = "City/view/$1";

We can also define the route should be mapped based on the request method.

//this will only map when http://localhost/cities is requested using post method
$route['cities']['post'] = "cities/store";

//this one will call Cities controller's index method
$route['cities']['get'] = "cities/index";

THE END :)

comments powered by Disqus