Best way to check for positive integer (PHP)?

Not sure why there's no suggestion to use filter_var on this. I know it's an old thread, but maybe it will help someone out (after all, I ended up here, right?).

$filter_options = array( 
    'options' => array( 'min_range' => 0) 
);


if( filter_var( $i, FILTER_VALIDATE_INT, $filter_options ) !== FALSE) {
   ...
}

You could also add a maximum value as well.

$filter_options = array(
    'options' => array( 'min_range' => 0,
                        'max_range' => 100 )
);

Learn more about filters.


the difference between your two code snippets is that is_numeric($i) also returns true if $i is a numeric string, but is_int($i) only returns true if $i is an integer and not if $i is an integer string. That is why you should use the first code snippet if you also want to return true if $i is an integer string (e.g. if $i == "19" and not $i == 19).

See these references for more information:

php is_numeric function

php is_int function


The best way for checking for positive integers when the variable can be INTEGER or STRING representing the integer:

 if ((is_int($value) || ctype_digit($value)) && (int)$value > 0 ) { // int }

is_int() will return true if the value type is integer. ctype_digit() will return true if the type is string but the value of the string is an integer.

The difference between this check and is_numeric() is that is_numeric() will return true even for the values that represent numbers that are not integers (e.g. "+0.123").


It's definitely heading towards the land of micro-optimisation, but hey: the code I'm working on chews through millions of items every day and it's Friday. So I did a little bit of experimenting...

for ($i = 0; $i < 1000000; $i++) {
    // Option 1: simple casting/equivalence testing
    if ((int) $value == $value && $value > 0) { ... }

    // Option 2: using is_int() and ctype_digit().  Note that ctype_digit implicitly rejects negative values!
    if ((is_int($value) && $value > 0) || ctype_digit($value)) { ... }

    // Option 3: regular expressions
    if (preg_match('/^\d+$/', $value)) { ... }
}

I then ran the above tests for both integer and string values

Option 1: simple casting/equivalence testing

  • Integer: 0.3s
  • String: 0.4s

Option 2: using is_int() and ctype_digit()

  • Integer: 0.9s
  • String: 1.45s

Option 3: regular expressions

  • Integer: 1.83s
  • String: 1.60s

Perhaps unsurprisingly, option 1 is by far the quickest, since there's no function calls, just casting. It's also worth noting that unlike the other methods, option 1 treats the string-float-integer value "5.0" as an integer:

$valList = array(5, '5', '5.0', -5, '-5', 'fred');
foreach ($valList as $value) {
    if ((int) $value == $value && $value > 0) {
        print "Yes: " . var_export($value, true) . " is a positive integer\n";
    } else {
        print "No: " . var_export($value, true) . " is not a positive integer\n";
    }
}

Yes: 5 is a positive integer
Yes: '5' is a positive integer
Yes: '5.0' is a positive integer
No: -5 is not a positive integer
No: '-5' is not a positive integer
No: 'fred' is not a positive integer

Whether or not that's a good thing for your particular use-case is left as an exercise for the reader...