Url Segment Validation Helper Function For CodeIgniter
by Henry Weismann on Feb.22, 2011, under Web Development
Here is a snippet for validating url segments. I wanted something similar to form validation for validating url segments. Basically to be able to use any form validation function, helper, php or callback functions to validate passed data. I have seen countless programmers not check data passed via the url and leading to broken CI pages…for example if they don’t check that they actually got a database result when using an id passed via the url that is not what was expected or they don’t check a passed argument is non zero number. For example it’s also handy for things like checking that a passed user id is the current logged in user too. Any function you want to use you can…you can even use the 2nd argument like match[1]. You can also pass FALSE as the site url and it will return the FALSE or TRUE result if fails or passes validation.
In this example I immediately redirect with an error if one of the checks fails but it uses my set_message() function. So just take that out or add your own function for setting the user message. You can redirect to an error page to show the message or a pretty oops error page.
This could be further enhanced to use the validation language capabilities and maybe added to the url class and allow you to save rules in a config file but here goes a barebone helper function:
/** * Validates data passed via the url by segment number. * Redirects on fail to specified site url or returns result * if the passed $site_url param is bool FALSE. Returns the segment * data on success or returns the formatted data if a prepping function was used. * @param string * @param string * @param string * @return bool or data */ function validate_segment($segment, $rules, $site_url = TRUE) { $CI = &get;_instance(); $CI->load->library('form_validation'); $data = $CI ->uri->segment($segment); $rules = explode('|',$rules); if(!in_array('required', $rules) && $data == '') { return $data; } if (in_array('required', $rules) AND $data == '') { set_message('The url has missing data.','error'); if($site_url) { $site_url = is_string($site_url) ? $site_url : ''; redirect($site_url); } } // -------------------------------------------------------------------- // Cycle through each rule and run it foreach ($rules As $rule) { if($rule == 'required') { continue; } // Is the rule a callback? $callback = FALSE; if (substr($rule, 0, 9) == 'callback_') { $rule = substr($rule, 9); $callback = TRUE; } // Strip the parameter (if exists) from the rule // Rules can contain a parameter: max_length[5] $param = FALSE; if (preg_match("/(.*?)\[(.*?)\]/", $rule, $match)) { $rule = $match[1]; $param = $match[2]; } // Call the function that corresponds to the rule if ($callback === TRUE) { if ( ! method_exists($CI, $rule)) { $validates = FALSE; } if($param) { $result = $CI->$rule($data, $param); } else { $result = $CI->$rule($data); } } else { if ( ! method_exists($CI->form_validation, $rule)) { // If our own wrapper function doesn't exist we see if a native PHP function does. // Users can use any native PHP function call that has one param. if (function_exists($rule)) { if($param) { $result = $rule($data, $param); } else { $result = $rule($data); } } } else { if($param) { $result = $CI->form_validation->$rule($data, $param); } else { $result = $CI->form_validation->$rule($data); } } } //is it a bool or did the function change the data and send it back $data = (is_bool($result)) ? $data : $result; // Did the rule test negatively? If so, grab the error. if(is_bool($result) && $result === FALSE) { if($site_url) { $site_url = is_string($site_url) ? $site_url : ''; set_message('The url has incorrect data.','error'); redirect($site_url); } return $data; } } return $data; }
Usage:
$id = validate_segment('3', 'required|is_natural_no_zero'); $user_id = validate_segment('4', 'required|is_natural_no_zero|is_admin|is_current_user'); $page_name = validate_segment('5', 'alpha_dash');
That’s 3 short lines of code to run 7 validation functions and redirect with a message if any of the passed data is not what you wanted.
Let me know if anyone finds it useful.