11

I have the following array and would like to know what the best way would be of validating and santizing this array to make sure only integers are allowed?

if(is_array($_POST['taxonomy'])) {
    $term_ids = array_map('esc_attr', $_POST['taxonomy']);
}

Which looks like this when printed:

Array
(
    [0] => 13
    [1] => 12
)

I know the esc_attr isn't very secure so would like something a bit more beefed up.

Any help would be great.

Cheers,

Dave

daveaspinall
  • 1,395
  • 1
  • 17
  • 28

5 Answers5

16

Since it's $_POST data, you'll want to check for ctype_digit (i.e. a string containing only digits):

$sanitizedValues = array_filter($_POST['taxonomy'], 'ctype_digit');

Note that this simply discards non-numeric values.

deceze
  • 510,633
  • 85
  • 743
  • 889
  • just tried this and it seems to be working spot on, thanks for everyone elses comments by the way, very helpful! How secure is this though? If someone were to inject something into this array? (We've had a few issues with hacking hence I'm going through all the code and plugging any holes). Cheers – daveaspinall Oct 07 '11 at 07:57
  • 1
    With this you can be sure that `$sanitizedValues` contains only strings that contain only numbers. Nothing more, nothing less. – deceze Oct 07 '11 at 07:59
  • Very nice, and very clean. Cheers @deceze and everyone else who posted a reply. – daveaspinall Oct 07 '11 at 08:03
  • Nice. Exactly what I was looking for. Kudos. – MikeSchinkel Dec 17 '12 at 22:45
6

An alternative would be using phps filter functions:

$array = array(
  13, 12, '1', 'a'
);

$result = filter_var($array, FILTER_VALIDATE_INT, array(
  'flags'   => FILTER_REQUIRE_ARRAY,
  'options' => array('min_range' => 1)
));

var_dump($result);

/*
array(4) {
  [0]=>
  int(13)
  [1]=>
  int(12)
  [2]=>
  int(1)
  [3]=>
  bool(false)
}
*/
Yoshi
  • 54,081
  • 14
  • 89
  • 103
  • Much more verbose but technically more appropriate. +1 :) – deceze Oct 07 '11 at 08:08
  • Sorry guys, whats the difference between the two? – daveaspinall Oct 07 '11 at 08:13
  • If it's a single field you're validating, I think it's just a matter of taste. Although if you have a lot of validating the filter functions can save you some work (see [filter_input_array](http://php.net/manual/function.filter-input-array.php) for example). And I guess, if you or someone else has to understand what you're doing 3months later, the filter function do more clearly show whats happening. – Yoshi Oct 07 '11 at 08:18
  • At the moment its just a single input. I've checked out the filter_input_array and it looks like its going to be very useful! I'll +1 this answer also, thanks alot @Yoshi for your help and advice. Every day's a school day :-) – daveaspinall Oct 07 '11 at 08:48
1
foreach( $array as $key => $value) {
    $array[$key] = (int) $value;

    if( $array[$key] != $value ) {
        // error
    }
}
Tobias
  • 9,170
  • 3
  • 24
  • 30
1
if(is_array($_POST['taxonomy'])) {
    $term_ids = array_map('intval', $_POST['taxonomy']);
}

Should do the trick. NOTE: this is sanitation. More: http://php.net/manual/en/function.intval.php

0

If you are looking for one-liner to check against specified condition you can use:

$onlyIntegers = Arr::check($_POST['taxonomy'], 'ctype_digit');

assuming your $_POST['taxonomy'] can contain numeric strings as @deceze suggested, or just plain:

$onlyIntegers = Arr::check($_POST['taxonomy'], 'is_int');

if you are sure that $_POST['taxonomy'] values should be in fact integers.

Arr::check method is a part of this php array library which contains various methods to help you deal with different types of arrays.

Minwork
  • 838
  • 8
  • 9