Experimenting with CodeIgniter

Filed under: PHP,Python | 1 Comment

I have been programming exclusively in Python (mostly with Django) for a while now, but my newest project is PHP. Getting my feet wet again in PHP made me realize how spoiled I had gotten so I did some framework shopping to help ease the pain. I settled on CodeIgniter thanks mostly to it being light-weight and easily expandable. While there are a lot of nice parts there is also a lot of unnecessary typing, mostly centering around models.

Models seem like an afterthought. Example A: they are advertised as a place to keep your methods to interact with the DB, not as a model of your data. This means tons of repetition by making wrapper methods for all your data. Example B: models aren’t hooked up with forms or validations even though most likely you’ll want both for every model you have. With a little bit of cleverness these annoyances can be greatly reduced, I’m not sure why this hasn’t been done officially.

Here’s what I’ve done so far, but this is only after a couple days of tinkering so I’m sure there will be changes:

I extended the native Model and Form libraries to work together. Each Model class has a public member declaration detailing the fields along with some meta information, namely validation rules. Using that info it only takes a few abstracted methods to automatically create and validate forms from models. For example, my registration method:

function register()
{
    require_anonymous_login();
    if ($this->User->is_valid()) {
        $this->User->create();
    }
    render_to_response('auth/register', array('title'=>'Register'));
}

That saves quite a bit of time, but we also have to construct the form. The built-in helpers for this are pretty pathetic, you end up calling tons of functions with nasty arrays for options (not CodeIgniter’s fault, PHP doesn’t support calling functions with named parameters). There’s one function for the form field, another for a possible error message and yet another for the value in case there was an error. For each field. You end up with something obscene like:

echo form_label('Username', 'username');
echo form_error('username');

$data = array(  'name'=>'username', 
                'value'=>set_value('username'),
                'size'=>'25');
                
echo form_input($data);

That can be automated somewhat, but you need to call the right ending function for each field type (form_input(), form_checkbox(), form_password(), etc). Half the fun of having a data model is this kind of stuff should be automated for you, a boolean column should know to represent itself as a checkbox, a varchar as an input, text as textarea, etc. Not to mention you have to create (and update!) the forms by hand since CodeIgniter “models” don’t describe your data.

To ease the pain I created a method that returns the fields in a model and then a global wrapper function that detects the data type and calls the right form helper function. For forms where you need some customization (fields next to each other and so forth), you can still get most of the benefit just without the savings of the loop. The entire registration form (labels, errors, different field types, etc) is now this:

	<?php foreach(form_fields_from_model('User') as $field): ?>
    <div class="form-row">
        <label for="<?=$field['slug']?>"><?=$field['name']?></label>
        <?= full_field($field); ?>
    </div>
	<?php endforeach; ?>

It’s still rough around the edges, but it’s nice to have the validation in the model and to have model forms update automatically with schema changes. Still not close to the elegance of Django, but it should save quite a bit of time (which is all I’m looking for frankly).

Read the latest posts

One Response to “Experimenting with CodeIgniter”

  1. Shawn Medero says:

    Your solution sounds elegant, any chance you’ll be releasing your extensions to the public? Most of the open source marriages between CI’s Model and Form Validation libraries are buried inside one of the user contributed ORM solutions. Would be nice to have something out there that is a bit more flexible.

Leave a Reply to Shawn Medero