Jump to content
Larry Ullman's Book Forums

Validate Checkbox Group Input Data


Recommended Posts

Larry or Antonio,

 

I haven't been on here in a while and I apologize. Been busy with work and web dev!

Hartleysan and I have been working on a site and I had a question about validating checkbox data.

Larry doesn't cover this in his books (no offense at all, Larry) and it is something that is new for me.

 

What I have is a checkbox group with values that are all integers. There are two things that I want to do before storing the data in the database:

1) I want to make sure that the $_POST variable is an array.

2) I want to check that all the values in the array are integers.

 

I did a Google search and found an answer on Stackoverflow http://stackoverflow.com/questions/306252/how-to-align-checkboxes-and-their-labels-consistently-cross-browsers , however, it seems overcomplicated.

 

The guy who answered the question uses the following code:

function for_all(array $arr, $func) {
   return array_reduce($arr,
    function ($a, $v) use ($func) {
	    return $a && call_user_func($func, $v);
    }, true);
}
var_dump(
   for_all(array(1,2,3), 'is_numeric')
); //true

 

Is this level of complexity really necessary to just iterate through an array and check if every value is an integer?

What do you guys think about this?

Link to comment
Share on other sites

No. That is not neccassary. I would develop one or two functions. One for validating that we have a filled array and one for validating int values. Remember values in the post array are strings, so ctype_digit() and is_int() could both be used with type casting.

 

This example will return true if the array size (the explicit parameter hinting requires an array) is larger/equal to a minimum and less than/equal to the max.

function valid_array( array $array, $min = 0, $max = 1)
{
return ($min <= count($array) <= $max);
}

if ( valid_array($array, 1, 5)
{
echo 'This is a valid array with between one and 5 values.';
}

 

Because a checkbox array almost every time will be a small array, a liniar function will do the trick. I can almost guarantee a solution like call_user_func requires more overhead.

 

function valid_int( $value )
{
// I cannot really guarantee this will work. Maybe you have to cast the value differently. Don't remember
return ctype_digit((string)$value) && is_int((int)$value);
}

$min = 1; // Minimum required elements
$max = 5 // Maximum required elements

// Validate the array
if ( valid_array($array, $min, $max)
{
// Get array size
$size = count($array);

// Check all values in array, and add the valid ones to a new array
for ( $i = 0; $i < $size; $i++)
{
	if ( valid_int($array[$i] ) {
		$valid_integers_array[] = $array[$i]
	}
 }
}

// $valid_integers_array is now filled with valid values.
// We know it's an array between $min / $max and all integers.

 

You can of course omit $min, $max from the function or just use one. This is just to illustrate the possibilities. You can even build a new function like get_valid_array() and make it return the $valid_integers_array for you.

 

This is also a good time to develop a static validation/filter class. These are classes you can develop once and reuse in other projects. Validate::array($array); Filter::integer_array($array) or Filter::array('integer', $array); (Look up the Factory pattern in Larry's new book when it's released) are some ideas. :)

 

Good luck.

  • Upvote 1
Link to comment
Share on other sites

Antonio,

 

Thank you very much! That answer was far more than I expected!

 

I just had a quick question: Is it better to use is_int or is_numeric? I was doing research about this before and several sites said that is_numeric is better because is_int will look at a string of numbers (which is what is contained in the array) as a string and not an integer (thereby returning a false answer). What do you think?

 

Anyway, thank you again for an awesome and well thought out answer! :)

 

Matt

Link to comment
Share on other sites

Please notice I type cast inside the is_int() function. :)

 

Is_numeric will unfortunatly validate some unwanted chars. "1e4", "99.99" and some others will validate through that function.

 

You can also use a function like intval() to get an integer. Just remember to check that the var is not an array as non-empty arrays will return 1 and empty ones will return 0.

 

It really depends how important the validation/filtering is. It's not like allowing a double value or the 'e' char is really that dangerous.

  • Upvote 1
Link to comment
Share on other sites

Please notice I type cast inside the is_int() function.

 

Ah, I missed that when I was going over it!

 

It really depends how important the validation/filtering is. It's not like allowing a double value or the 'e' char is really that dangerous.

 

That's true! I just want to filter out strings (i.e. data types that could be dangerous).

 

Also, couldn't I use is_array to validate that the checkbox POST data is an array?

 

Thanks Antonio

Link to comment
Share on other sites

 Share

×
×
  • Create New...