In this article I plan on addressing CodeIgniter’s shortfalls as a framework
for validating objects and introduce a method for improving the validator
classes re-usability.

When To Validate?

The answer to this question is simple: whenever we are dealing with input. The
(incorrect) assumption that CodeIgniter and many web-applications make is that
user input comes in the form of GET and POST variables and a considerable
amount of effort goes into validating inputs via these routes. However, GET
and POST are not the only sources for user input. User input can come via
external sources such as tying into a remote API, an RSS feed, or from the
database itself. From each of these sources we could get an invalid state. In
the case of the remote API or RSS feed this is easy to understand. The API
could change, or the RSS feed could be malformed. In the case of the database
the issue typically appears when data is stored into the database under one
context but is then accessed with a different expectation.

Now say that we inserted a person with name “Bob” and birthdate
“1975-01-01.” This passes the validator going into the database, but later on
we pull this row from the database and use it to construct a plain PHP object
with properties id, name, and birthdate which we pass onto the view and
attempt to output the birthdate with the following line:

<?phpechodate('Y-m-d',$person->birthdate);

This is going to cause an error. Why? Because the date function is expecting
the second parameter to be a UNIX timestamp, but birthdate is already a
formatted date string. Now, we could solve this by changing the schema of the
database or changing the schema of the person object, but it is important to
note that even if we did fix the disparity between the two we would still not
fix the issue that it is possible for the person object to exist in an
invalid state.

So my answer is to when should validation occur is during object instantiation
and setting. The properties of the object should not be able to be set to a
value that the object cannot accept. This places validation clearly into the
realm of the “M” in “MVC.”

Form Validation in CodeIgniter

CodeIgniter’s
documentation
offers a form validation class that makes the above mistake very clearly. It
can only validate the POST super global and doesn’t really offer much of a
solution towards validation of objects themselves. Furthermore, their example
controller oddly mixes the issue of object validation, and thus business logic,
inside the controller which tends to create in many CI application fairly
bloated controllers:

I cannot offer a solution towards adapting the validation class to be fully
object operating without a heavy rewrite of the class, but we can move this
obtuse validation into a distinct model that encapsulates this behavior away
from the controller.

Introducing the Abstract Validator Class

We can get the validation logic out of the controller by moving it into a
Validator class. We begin with an abstract base class since each form will
need their own validator classes:

<?phpabstractclassValidatorextendsCI_Model{protected$rules=array();protected$fields=array();# Get keys of fields.
publicfunctiongetStructure(){returnarray_keys($this->fields);}# Validate $_POST against the rules and fields.
publicfunctionvalidate(){foreach($this->rulesas$key=>$rule){$this->form_validation->set_rules($key,$this->fields[$key],$rule);}return$this->form_validation->run($this);}}

We take advantage of the fact that the CI god to access the form_validation
object inside the Validator instance to create the validate method which
merely sets the validation rules and then runs them. The Validator has two
properties $rules and $fields which we will use in sub-classes to provide
the CI_Validator rules and fields strings. We can transform the above
controller into the following subclass:

About

Joseph Hallenbeck attended the RTIS program at DigiPen Institute of Technology, studied Victorian-era literature at the University of Oxford, and graduated from Augustana University in Sioux Falls, SD with a B.A. in Philosophy and English Literature. He has worked as an interpretive ranger, naturalist, and caver for the National Park Service and is now employed as a Software Engineer at Research Square in Durham, NC.