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...