Simple CRUD With CodeIgniter


Last week we took a look at an introduction to the CodeIgniter PHP framework. In that example we saw the basics of how CodeIgniter works and the basics of the MVC pattern. But we didn't really do much with models. Today we will look at the power of models in CodeIgniter to make CRUD functions easy.

CRUD stands for create, read, update and delete, which are some of the most basic functions that can be done with data storage. In this tutorial we will be applying CRUD to a MySQL database. We will take a look at the database libraries included in CodeIgniter to ease work with databases, and other included libraries to help out with development as well.

If you haven't yet, you may want to read through An Introduction to CodeIgniter first, so that you at least know the basics of CodeIgniter.

Getting Started

The first thing you should do is setup a database on your server. For the purposes of this tutorial, I will be calling mine "ci". Once that is created, execute the following SQL query to create a simple table.

    title TEXT,
    content TEXT

Next, we need to do a bit of configuration. Open up config/database.php in your favourite text editor and change the following values to match your database configuration.

$db['default']['hostname'] = "localhost";
$db['default']['username'] = "MySQL Username";
$db['default']['password'] = "MySQL Password";
$db['default']['database'] = "ci";

Next open up config/autoload.php. This file contains the systems to be loaded by default. Change the autoloaded libraries (around line 42) to this:

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

We are autoloading the database library because we will be using it a lot throughout this tutorial.


Let's get started by creating new records. First, create a new controller called crud.php. Inside of that file, type in the following code.

class Crud extends Controller {
    function index() {
        // Check if form is submitted
        if ($this->input->post('submit')) {
            $title = $this->input->xss_clean($this->input->post('title'));
            $content = $this->input->xss_clean($this->input->post('content'));
            // Add the post
            $this->posts_model->addPost($title, $content);

When the index function of our crud controller is called, it first checks if the form, which we will create, has been submitted. Next the input is run through an XSS filter for security purposes, and then added to the database through a function we will create.

Finally, a view will be loaded to display the form, and later, the posts.

The Model

Models are used in the MVC pattern for working with data. In CodeIgniter they are located in the models directory. Create a new model called posts_model.php. Type the following code inside it.

class Posts_model extends Model {
    function addPost($title, $content) {
        $data = array(
            'title' => $title,
            'content' => $content
        $this->db->insert('posts', $data);

This is a very simple example. Our model class, called Posts_model contains a function called addPost, which can be used with two parameters for the title and the content of the post. An array called $data is created which stores the values. Finally the data is inserted into the database using a function included in the database library, which we automatically loaded.

Creating The Form

For our form will be using a view. Create a new view called crud_view.php.

To build the form, we will use the form helper, which is a library included in CodeIgniter to help make building forms easier. Using the form helper, here is the code to create our form.

<?php $this->load->helper('form'); ?>
<?php echo form_open('crud'); ?>
        <?php echo form_input('title'); ?>
        <?php echo form_textarea('content'); ?>
        <?php echo form_submit('submit', 'Submit'); ?>
<?php echo form_close(); ?>

Now you can test it out. Point your browser to index.php/crud/ and try filling out the form. Check the database in phpMyAdmin (or whatever you use). If everything went well, there should be some new rows in the table. If it works, we can continue to the next part!


Reading from the database is still very simple in CodeIgniter, but a bit more complicated than inserting. Inside of our model, add in this new function:

function getPosts() {
    $query = $this->db->get('posts');
    $posts = array();
    foreach ($query->result() as $row) {
        $posts[] = array(
            'id' => $row->id,
            'title' => $row->title,
            'content' => $row->content
    return $posts;

This function first creates a query that gets all of the rows from the posts table of the database. Using a foreach statement, it loops through all of the rows to create an array. When that is finished, the function returns an array of all the posts.

Next, inside our controller, inside the index function, delete the line that loads the view, and add in the following lines of code in its place.

$data = array();
$data['posts'] = $this->posts_model->getPosts();
$this->load->view('crud_view', $data);

The variable $data is declared as an array. Then an array inside of $data contains all of our posts, using our getPosts function. And then it loads the view again, this time passing in the $data variable, now containing all of our posts.

Next we are going to display all of the posts to the user. Because we passed them in to the view, we just need to add a few lines to the view, below the form, to get it to display the posts.

<?php if (isset($posts)): foreach ($posts as $p): ?>
    <h2><?php echo $p['title']; ?></h2>
    <?php echo $p['content']; ?>
<?php endforeach; else: ?>
    <h2>No posts found</h2>
<?php endif; ?>

This first checks if there are any posts to display. If there are, it simply loops through each of them, displaying the title and the content for each of them. If there are no posts to show the user, it shows them a very informative message.


To update data in the database, first add a new function to our model.

function updatePost($id, $title, $content) {
    $data = array(
        'title' => $title,
        'content' => $content
    $this->db->where('id', $id);
    $this->db->update('posts', $data);

Our new function, updatePost, accepts three parameters, for the id of the post to update, the new title of the post, and the updated content.

$data is an array that stores the title and content. Next a function included in CodeIgniter's database library tells the next SQL query where the row should be updated. In this case it is where the id field of the table is equal to $id. And lastly, the update function is called, which updates the posts database table with the information supplied.

A new form needs to be created to be able to update the post. Create a new view called updateform.php and type in the following code which makes use of CodeIgniter's form helper.

<?php $this->load->helper('form'); ?>
<h1>CodeIgniter CRUD Tutorial Example</h1>
<?php echo form_open('crud/update/'.$id); ?>
        <?php echo form_input('title'); ?>
        <?php echo form_textarea('content'); ?>
        <?php echo form_submit('submit', 'Submit'); ?>
<?php echo form_close(); ?>

A new function also needs to be added to the controller for this to work.

function update() {
    $id = $this->uri->segment(3);
    if ($this->input->post('submit')) {
        $title = $this->input->xss_clean($this->input->post('title'));
        $content = $this->input->xss_clean($this->input->post('content'));
        $this->posts_model->updatePost($id, $title, $content);
        $data['posts'] = $this->posts_model->getPosts();
        $this->load->view('crud_view', $data);
    } else {
        $data = array('id' => $id);
        $this->load->view('updateform', $data);

As you can probably tell, this function is very similar to the one to add posts. However this one deals with URI segments. A segment is just a part of a URI, which contains a certain value. Here we use the third segment of the URI, which contains the ID of the post to update.

If the form has been submitted, the title and content are run through an XSS filter again, and the post is updated. It also retrieves all of the posts and passes them into the crud_view view, which is loaded after a post has been updated.

If the form has not been submitted, the form is loaded, with the ID of the post passed in, as it is used in the form.

To test this out, point your browser to index.php/crud/update/YourID, replacing YourID with the ID of the post you would like to update.


We will finish off this tutorial with Delete, which uses some very simple functions. Create one last function inside of our model.

function deletePost($id) {
    $this->db->where('id', $id);

That's really all there is to it. The where function is used just like in the "update" function, to indicate which rows will be affected. And then the next statement which simply deletes that row.

Another simple function must be added to our controller, this one called delete.

function delete() {
    $id = $this->uri->segment(3);
    $data['posts'] = $this->posts_model->getPosts();
    $this->load->view('crud_view', $data);

This, again, gets the ID of the post to delete from the third segment of the URI. The our deletePost function is called to delete the post with that ID. All of the posts are then retrieved, and displayed to the user through the crud_view view.

To do simple CRUD functions with CodeIgniter, it is really a very simple task. If you have any questions, or if somehow, something doesn't work for you, be sure to leave a comment and I will do my best to help you out.

Also, be sure to subscribe to the RSS feed or for email updates, because now that we know the basics of CodeIgniter, I will start posting a series of posts on something more useful, creating a simple website using CodeIgniter.

Stay Updated

Did you enjoy this post? Don't miss a single post by getting free updates!


  1. April 6, 2010

    cool, I LOVE CodeIgniter, but all of us who are really developing in it are using Smarty, so feel free to show us some Smarty implementation while you're there ;)


    • Luis
      April 6, 2010

      Why use smarty when php based templates are even better!? Your code should not be mixed with your presentation layer and although smarty is very powerful php is by far much better. Please don't get me wrong. I worked with Smarty for about 2 years under xoops and found it a great help at times but most of the times was useless. PHP gives a flexibility that smarty cannot reach yet.

  2. April 6, 2010

    In your readPosts why did you duplicate the data. You could of just returned $query->result() instead of running it through a foreach in the model? You are basically running two loops for one set of data.

    • April 6, 2010

      You're right, I probably could have returned $query->result(), and then used the objects to display the results.

      I actually only just discovered the result_array() function which would automatically generate an array, so that we wouldn't have to update the view. So in the following tutorials, I'm going to have to make sure to use either one or the other.

      • April 6, 2010

        I actually prefer to use objects over an array. Its what a lot of other programming languages do.

        • Adam Leonard
          April 6, 2010

          I agree, would be one less function call. Also, objects are just as easy to enumerate over.

  3. Carlos
    April 6, 2010

    Nice Tut, keep'em coming!


  4. Rob
    April 6, 2010

    I have a similar delete() function in one of my controllers. I have a link to it in my view and JS hooked up to it to display a confirm dialog. However, if the function is called directly by typing the URL into the browser, the record deletes without warning. Is there some way to write the function in the controller or model to prevent this?

    • April 6, 2010

      You can add a form with only a submit button that adds a POST value once submitted, and make it so that the page is only deleted once the button has been clicked.

    • Luis
      April 6, 2010

      You can check in the controller action if any post data has been sent or in the action is being called through Ajax.That way you don't get direct access to the action. I believe CI disables $_GET so don't bother to check for it.

  5. April 6, 2010

    When I tried the example I got an error saying posts_model was null... I was able to work around it by adding the following:

    $retval = $this->load->model('Posts_model');

    Am I missing something here?

    • July 18, 2010

      Got the same problem, but haven't solved it yet.. can anyone tell me what's missing? Can add that I'm really new to CI.

      • tAz
        October 31, 2010

        Very simple to fix - but tricky to debug without some prior knowledge.

        You must "load" a model before you use it:

        Amend the code in crud.php

        // Add the post
        $this->load->model('posts_model'); $this->posts_model->addPost($title, $content);

        Broken tuts are a curse :(

  6. Luis
    April 6, 2010

    Very good tutorial. I wish I could have found this when I was learning CI. Keep in mind that the Database class for CI has tons of features that's always good to keep in handy, this was my best mate in my old days:

    • April 6, 2010

      Thanks for linking to that. It looks like it would make a very useful reference!

  7. April 7, 2010

    Just a small suggestion, you can pass variables through XSS clean, just by passing TRUE into the input get method:

    $title = $this->input->post('title', TRUE); // this will be XSS cleaned

    • April 7, 2010

      That's a great idea! Thanks for the suggestion.

  8. April 7, 2010

    You could have done something like:


    It runs XSS filter over the field, which is the same as:

    $title = $this->input->xss_clean($this->input->post('title'));


    • April 7, 2010

      That's a great idea! Thanks for the suggestion. (Like the comment above you, but you couldn't have seen that :))

  9. Michelle
    April 19, 2010

    Why use smarty when php based templates are even better!? Your code should not be mixed with your presentation layer and although smarty is very powerful php is by far much better. Please don't get me wrong. I worked with Smarty for about 2 years under xoops and found it a great help at times but most of the times was useless. PHP gives a flexibility that smarty cannot reach yet.

  10. Why so much typing
    June 10, 2010

    In Crud controller why not do:

    $p = $this->input->post;
    foreach($p as $k=>$v) ${$k} = $p($k, true);
    $this->posts_model->addPost($title, $content);

    Every CRUD app I look at, makes me want to CRAP. If you have 20 or 30 posted fields, please don't tell me you write it all out a la:
    $blah = $this->input->xss_clean($this->input->post('blah'));

    Same goes for validation, Rails, Django, CI, Cake, etc., all tons of typing.

    If only Drupal were PHP 5.3 OO I would actually break away from my framework; at least you can crank out content at a ridiculous pace in Drupal (customizing, another matter)

    Apologies if coming down on CI, have heard/read good things, just my search for the barebones ORM-FormGenerator/Validator-CRUD framework has been for naught thus far...

  11. July 5, 2010

    Hello any body guide me for code igniter frame work,I because i am in some error using the frame work...error is Call to a member function updatePost() on a non-object

    • July 5, 2010

      Well I might not be able to say exactly what is causing your problem, but by the looks of the error message, you're trying to do something like $something->updatePost(), where either $something's class doesn't contain a function called updatePost(), or where $something isn't even an object.

      Given the error message, it's most likely the latter. Like I said, I don't know where exactly the error could come from, but this should help you to start your search to find the bug :)

  12. August 11, 2010

    Very good article however, on the update form if you put the submission URL to something like 'posts/update/$id', form_validation won't work as you expect.

    I've run into problems with this before - as form_validation links to the form by the form_open('posts/update'); function, so if it ended up being form_open('posts/update/1'), for example, form validation would fail.

    The solution to this would be to use form_hidden('update_id', $id) to have a hidden form element with the ID to update.

    Hope this makes sense. :)

  13. Cesar
    September 5, 2010

    Very good article! It worked properly. Thanks!

  14. October 19, 2010

    Great article. Lets give it a try.

  15. October 31, 2010

    Thanks for your tutorial..good :)

    but i have question about update data.
    Can i update a data with only get an id ?

    so, i only need one argument in function model
    function update($id){

    yeah, i need $id for update a data..

    please help me...thanks, :)

  16. Apocryphon
    December 31, 2010

    Hey, I tried the first part of this tutorial and received this 404 message:

    A PHP Error was encountered

    Severity: Warning

    Message: Cannot modify header information - headers already sent by (output started at /Applications/MAMP/htdocs/ci/system/application/controllers/main.php:14)

    Filename: codeigniter/Common.php

    Line Number: 360

    404 Page Not Found
    The page you requested was not found.

    Any idea what's causing this php error?

    • Apocryphon
      December 31, 2010

      Never mind! Fixed it.

  17. February 17, 2011

    Fatal error: Call to a member function addPost() on a non-object in E:\xampp\htdocs\ci\system\application\controllers\crud.php on line 11..when i try to submit..this occurs..what can I do?newbie with CI..

  18. Christoph
    March 5, 2011


    i am new to CI and i am very thankful for your tut. Unfortunately i am having problems from the beginning. After submitting the form i do not get new rows in the DB. After insertig some rows ba myself in phpmyadmin i tried to get the posts as you explained, but i get this error:

    A PHP Error was encountered

    Severity: Notice

    Message: Undefined property: Crud::$posts_model

    Filename: controllers/crud.php

    Line Number: 17

    Can someone help me?

    • March 8, 2011

      i have a same problem, but i have fix it with tAz trick on the previous comment.

      you should add this :

      before this script
      $this->posts_model->addPost($title, $content);


      • Jey Hussein
        September 26, 2011

        You reply has helped me a lot in solving this problem.
        Thank you.

    • March 8, 2011

      Ouch...I'm sorry i thought i was mistaken case. I have the same problem on line 17, then i add this

      $data['posts'] = $this->posts_model->getPosts();

      I'm new in CI, so my question to the writer is:
      do we need to add these lines before the operation model?

  19. George
    March 10, 2011

    To the guys who are finding errors, read the CodeIgniter user guide! You must load models before trying to use them.

    All of this (and much, much more) are explained in the user guide.

    The user guide for CodeIgniter is one of it's great assets and the fact that so many people are neglecting to read it is shocking.

    • Chris
      May 31, 2011

      Agreed that the user guide is excellent on Codeigniter.
      However, there is no clear explanation of a complete, simple, CRUD model there - this is the best attempt at one available [I believe] and it is natural that people are trying to add the finishing touches.
      It would be fabulous if the author could incorporate the corrections into the tutorial, as it is 98% there....

  20. Mack
    September 2, 2011

    Hey I'm pretty new to MVC and hence CI, but I've been looking around and have got a catch of it lately.

    Okay, in your code, inside the controller, where do you load the posts_model?

  21. vijay jawriya
    September 10, 2011

    thanx for this simple tutorial that make to understand codeigniter with ease. i have to make litle change to use this code.

  22. September 17, 2011

    Thanks Eric for this great CI basic CRUD prog. tutorial. Did trip up on quite a few things though, some of which are mentioned in previous comments here.

    Have captured hopefully all the fixes in a blog post which also has a source code dump of all the fixed controller, model & view files used by this and the intro tutorial pages. The blog post is here:

    Thanks again.

  23. Meer Afghan
    December 8, 2011

    thanks for help!