CodeIgniter Form Validation Callback Functions with Multiple Arguments

If you’re reading this you most likely already know that you can only send one argument to callback functions using CodeIgniter’s Form Validation Class. If you are not yet familiar with this feature/limitation, here is an example of how the callback works.

Here is our controller with a normal callback (_foo) and our multiple-argument callback function (_valid_login)…

class Login extends Controller {
 function Login()
 {
  parent::Controller();
  $this->load->model('users');
  $this->load->library('session');
 }
 function _foo($str = '', $val = '') // normal callback function
 {
  if ($str != $val) {
   $this->form_validation->set_message('_foo', 'The %s field must be ' . $val);
   return FALSE;
  }
  return TRUE;
 }
 function _valid_login($str = '', $params = '') // callback function with multiple parameters
 {
  list($username, $password) = explode(',', $params);
  if ($this->users->valid_login($username, $password)) {
   return TRUE;
  }
  $this->form_validation->set_message('_validate_login', 'No matching accounts!');
  return FALSE;
 }
 function index()
 {
  $username = $this->input->post('username', TRUE);
  $password = $this->input->post('password', TRUE);
  $params = "{$username},{$password}";
  $this->load->library('form_validation');
  $this->form_validation->set_rules('username', 'Username', "trim|required|valid_email|strtolower|xss_clean|callback__foo[bar]|callback__valid_login[{$params}]");
  $this->form_validation->set_rules('password', 'Password', 'trim|required|min_length[6]|xss_clean');
  if ($this->form_validation->run() == FALSE) {
   // invalid or initial request
   $this->load->view('login');
  } else {
   // success
   redirect('account')
  }
 }
}

The model…

class Users extends Model {
 function Users(){
  parent::Model();
 }
 function valid_login($username = '', $password = '')
 {
  $this->db->where('username', $username);
  $this->db->where('password', $password);
  return $this->db->count_all_results($this->table);
 }
}

And the view…

<form action="login" method="post">
 <table>
  <tr>
   <td>Username</td>
   <td><input name="username" type="text" /><?php echo form_error('username'); ?></td>
  </tr>
  <tr>
   <td>Password</td>
   <td><input name="password" type="password" /><?php echo form_error('password'); ?></td>
  </tr>
  <tr>
   <td>&nbsp;</td>
   <td><input type="submit" value="Log In" /></td>
  </tr>
 </table>
</form>

Our _foo() callback function is what you might normally expect, where only a single argument is passed. If you need to send multiple parameters however, our _validate_login example function is about as simple as it gets.

A quick note about the _validate_login function… The $str parameter represents what is always passed to any form validation function, the field’s current value. We are ignoring the first argument for the sake of this example so don’t bother pointing out that we could have used that to get the username 😉

The only thing you really need to do to pass multiple arguments is expode() the string passed to our function into an array and assign the parts (2 for this example) to variable names using PHP’s list() function.

There’s not much else to it. Now you know how to pass multiple arguments to a CodeIgniter form validation callback function 🙂

9 thoughts on “CodeIgniter Form Validation Callback Functions with Multiple Arguments”

  1. Great post. In my case, I needed to pass an array that maintained the key/value pairs, so I chose to use php’s http_build_query function to convert the array to a string, and then once inside the callback, use php’s parse_str function to decode the query back into an array.

  2. Glad my post helped.

    Not sure if there are any performance differences but you could also try serialize() and unserialize() to pass an array or object to your function (very useful for multi-dimensional arrays or complex objects) 🙂

  3. Reagrding my previous reply…

    You would need to use urlencode(serialize($myarray)) and urldecode(unserialize($myarray)) to ensure the data passes correctly in the URL. In which case, your method of using http_build_query() and parse_str() may be likely to outperform my method.

    My method still applies however for nested arrays and objects. Which may make it better in general since you only need one method to parse the arguments regargless of how complex they may become 😉

  4. When I am trying to validate my form. I am getting this error- “Unable to load the requested class: validation”
    Can you help me to find whats the problem.?

    my code is :
    $this->load->library(‘form_validation’);

    and…

    public function insert_student()
    {
    $this->load->helper(array(‘form’, ‘url’));
    $this->load->library(‘validation’);
    $this->load->helper(array(‘form’));
    $this->form_validation->set_rules(‘sname’, ‘username’, ‘required’);
    $this->form_validation->set_rules(’email’, ‘Email’, ‘required’);
    $this->form_validation->set_rules(‘password’, ‘password’, ‘required’);
    $rules[‘vpassword’] = “required”;
    $rules[‘address’] = “required”;
    $rules[‘gender’] = “required”;
    $rules[‘hobbies’] = “required”;
    $rules[‘class’] = “required”;

    $this->validation->set_rules($rules);
    if ($this->validation->run() == FALSE)
    {
    $this->load->view(‘form_view’);
    }
    else
    {
    $this->load->model(‘student_insert_model’);
    $this->student_insert_model->add_student();
    $this->load->helper(‘url’);
    redirect(“/index”);

    }

    1. Take another look at your code… $this->load->library(‘validation’); should be $this->load->library(‘form_validation’);

      Also, replace $this->validation with $this->form_validation in the rest of your code.

      In other words, you’re mixing old and new versions of the validation libraries 😉

  5. Well if you really need some outside data in that function, why not use a global variable? Of course not good practice to start making global variables. But definitely one solution to a problem! 🙂

    1. My method uses the same principles as the core functions. Not sure why you’d want to reinvent the wheel and do things differently with globals when it’s relatively easy to create callbacks that accept parameters 😉

  6. i am getting this error “Unable to load the requested class: validation”, can you help me to find whats the problem ?
    my code :
    load->helper(‘url’);
    $this->load->helper(‘form’);
    $this->load->library(‘form_validation’);
    $this->load->library(’email’);
    }
    function index(){
    $rules[‘namadepan’]=”required|min_length[6]|max_length[15]”;
    $rules[‘namabelakang’]=”required|min_length[6]|max_length[15]”;
    $rules[‘alamatemail’]=”required|valid_email”;
    $this->form_validation->set_rules($rules);

    $fields[‘namadepan’]=’Nama Depan’;
    $fields[‘namabelakang’]=’Nama Belakang’;
    $fields[‘alamatemail’]=’Alamat Email’;
    $this->form_validation->set_fields($fields);

    if ($this->form_validation->run() ==FALSE){
    $this->load->view(‘form_view’);
    }
    else {
    $config[‘protocol’]=’mail’;
    $config[‘smtp_port’]=’25’;
    $config[‘smtp_host’]=’smtp.yahoomail.com’;
    $config[‘wordwrap’]=TRUE;

    $this->email->initialize($config);
    $this->email->from($_POST[‘alamatemail’],$_POST[‘namadepan’].”.$_POST[‘namabelakang’]);
    $this->email->to(‘wbanjarish@yahoo.com’);
    $this->email->subject($_POST[‘subjek’]);
    $this->email->message($_POST[‘isi’]);
    $data[‘title’]=’sedang mengirim email…’;
    $data[‘header’]=’sedang mengirim email…’;
    $data[‘message’]=$this->email->send()?’pesan email berhasil dikirim!’:’Gagal mengirim pesan email!’;
    $this->load->view(’email_view.php’,$data);
    }
    }
    }
    ?>

    1. First things first… $this->load->helper(‘form’) is not necessary. $this->load->library(‘form_validation’) automatically includes that helper. I don’t see anywhere in your code where you called (the deprecated library) $this->load->library(‘validation’) which is what would throw that error. More complete code will be necessary to help you 😉

Leave a Reply

Your email address will not be published. Required fields are marked *