The good folk over at EllisLab released a new version of their CodeIgniter open source PHP web application framework a few weeks ago, and I’ve now upgraded this site to use this new version (which you shouldn’t notice) and taken the opportunity to do some minor design and code cleanups (you will hardly notice).
This is a significant release for CodeIgniter and, despite the usual excellent migration guide that EllisLab supply, I ran into a few problems, mainly in relation to database access and queries.
Session user_data column
For those of us using a database to store user session information, CodeIgniter 1.7.0 brings changes that store custom session data in the database (instead of in cookies) as well. This
requires a new user_data column to be added to the sessions table in the database with a suggested definition as follows:
ALTER TABLE `ci_sessions` ADD `user_data` text NOT NULL
However, CodeIgniter 1.7.0 still tries to insert NULL user_data at times so defining the column as shown above will result in “Field ‘user_data’ doesn’t have a default value” database
errors being reported. MySQL does not allow default values for text type columns, so I had to modify the user_data column definition to allow null values, by simply removing the
NOT NULL clause:
ALTER TABLE `ci_sessions` ADD `user_data` text
MySQL Port Support
CodeIgniter 1.7.0 adds support for port numbers to its MySQL drivers, but, as I was upgrading from an existing installation, I just copied my application/config/database.php file over and therefore didn’t have a port number configured. This resulted in a port number of 0 being used (since PHP interprets an empty string as an integer zero) and the database connection failing with the error “Unable to connect to your database server using the provided settings“. Adding the following line to the configuration file fixed the problem:
$db['default']['port'] = "3306";
Problems with order_by random
Some functions of this site rely on the fetching database rows in a random order. In the code, this requires the use of the ActiveRecord order_by() function with a parameter of “random” as shown below:
$this->db->order_by('', 'random');
Unfortunately there seems to have been a bug introduced with CodeIgniter 1.7.0 that causes ActiveRecord to generate invalid SQL when the above function is called in that form. A database error “Unknown column ‘ RAND() LIMIT 1′ in ‘order clause’” is reported because of a spurious escape quote that is inserted into the generated SQL:
SELECT ... ORDER BY ` RAND() LIMIT 1
You can see the extra quotation mark just after ORDER BY. I developed my own quick fix for this problem, pending a bug fix release from EllisLab. In the mysqli_driver.php file found in system/database/drivers/mysqli/ (part of CodeIgniter itself), modify the _escape_identifiers() function by inserting the following lines at the start, around line 416:
if ($item == '') { return $item; }
The same fix (at a different line number!) can also be applied to the regular MySQL driver, mysql_driver.php in system/database/drivers/mysql.
Problems with order_by multiple fields
I’d been using the ActiveRecord order_by() function in the following form, to order records by multiple keys:
$this->db->order_by('date,title');
In versions of CodeIgniter previous to 1.7.0 this worked, but under the new version the error “Unknown column … in ‘order clause’” was reported. The SQL generated by ActiveRecord was of the form:
SELECT ... ORDER BY `date,title`
You can see that the comma separated sort columns have been added to the SQL as one identifier instead of individually. To fix this I simply changed my own database code to explode() the sort columns and call order_by separately for each one:
$this->db->order_by($this->order());
…was changed to:
foreach (explode(',', $this->order()) as $field) { $this->db->order_by($field); }
A simple change, but something to be aware of.
On re-reading the CodeIgniter user guide, I don’t believe my original usage was actually supported. It was just blind luck it worked at all, but at least now I’m doing it right and there should be no problems with future versions. Fingers crossed!
New validation library
CodeIgniter 1.7.0 comes with a brand new form_validation library to help you validate your HTML form inputs. It replaces the old validation library, which remains in place for backward compatibility but is now considered deprecated. Changing your code to use the new library is fairly straightforward.
- In your controller classes and views, use form_validation rather than validation as the library name:
$this->load->library('form_validation'); ... $this->form_validation->set_rules(...);
- Instead of setting the “human readable” name of each form field separately with a call to set_fields(),
set_rules() has a new signature that includes the human readable name in the call.$this->validation->set_fields(array( 'name' => 'Name', 'email' => 'Email Address' )); ... $this->validation->set_rules(array( 'name' => 'trim|xss_clean|required|max_length[255]|callback_name_check', 'email' => 'trim|xss_clean|strtolower|max_length[255]|valid_email' ));
…becomes…
$this->form_validation->set_rules(array( array( 'field' => 'name', 'label' => 'Name', 'rules' => 'trim|xss_clean|required|max_length[255]|callback_name_check' ), array( 'field' => 'email', 'label' => 'Email Address', 'rules' => 'trim|xss_clean|strtolower|max_length[255]|valid_email' ) ));
- Instead of accessing submitted validation values directly as dynamic instance variables of the validation library class, you now need to call the set_value() function to retrieve them. This applies equally to both fetching values in controller classes and repopulating form fields in views.
$name = $this->validation->name;
…becomes…
$name = set_value('name');
- Similarly, the list of validation errors is now retrieved by calling the validation_errors() function instead of reading directly from the error_string instance variable.
And you’re done
So there you have it – a new version of the core framework that underpins this and other sites I maintain. It’s a significant release and the migration has not been entirely painless, but hopefully it’s worth it and everything is working just dandy now under the new version. I also hope that, through the magic of Google, this little narrative will help those who are having problems of their own. Happy CodeIgniting!


Thanks for the MySQL port support tip. I just upgraded my app to 1.7.0, and got the “Unable to connect to your database server using the provided settings” error. It’s nice when I can fix semi-obscure problems with a quick search.