[php] Checking if a variable is an integer in PHP

I have the following code

    $page = $_GET['p'];

    if($page == "")
    {
        $page = 1;
    }
    if(is_int($page) == false)
    {
        setcookie("error", "Invalid page.", time()+3600);
        header("location:somethingwentwrong.php");
        die();
    }
    //else continue with code

which I am going to use for looking at different "pages" of a database (results 1-10, 11-20, etc). I can't seem to get the is_int() function to work correctly, however. Putting "1" into the url (noobs.php?p=1) gives me the invalid page error, as well as something like "asdf".

This question is related to php

The answer is


Values $_GET are always strings – that's what GET paramters come as. Therefore, is_int($_GET[...]) is always false.

You can test if a string consists only of digits(i.e. could be interpreted as a number) with is_numeric.


$page = (isset($_GET['p']) ? (int)$_GET['p'] : 1);
if ($page > 0)
{
  ...
}

Try casting and checking if it's a number initially.


/!\ Best anwser is not correct, is_numeric() returns true for integer AND all numeric forms like "9.1"

For integer only you can use the unfriendly preg_match('/^\d+$/', $var) or the explicit and 2 times faster comparison :

if ((int) $var == $var) {
    // $var is an integer
}

PS: i know this is an old post but still the third in google looking for "php is integer"



An integer starting with 0 will cause fatal error as of PHP 7, because it might interpret it as an octal character.

Invalid octal literals

Previously, octal literals that contained invalid numbers were silently truncated (0128 was taken as 012). Now, an invalid octal literal will cause a parse error.

So you might want to remove leading zeros from your integer, first:

$var = ltrim($var, 0);

When i start reading it i did notice that you guys forgot about abvious think like type of to check if we have int, string, null or Boolean. So i think gettype() should be as 1st answer. Explain: So if we have $test = [1,w2,3.45,sasd]; we start test it

foreach ($test as $value) {
        $check = gettype($value);
        if($check == 'integer'){
            echo "This var is int\r\n";
        }
        if($check != 'integer'){
            echo "This var is {$check}\r\n";
        }
}

And output:

> This var is int 
> This var is string 
> This var is double 
> This var is string

I think this is easiest way to check if our var is int, string, double or Boolean.


doctormad's solution is not correct. try this:

$var = '1a';
if ((int) $var == $var) {
    var_dump("$var is an integer, really?");
}

this prints

1a is an integer, really?"

use filter_var() with FILTER_VALIDATE_INT argument

$data = Array('0', '1', '1a', '1.1', '1e', '0x24', PHP_INT_MAX+1);
array_walk($data, function ($num){
$is_int = filter_var($num, FILTER_VALIDATE_INT);
if ($is_int === false)
var_dump("$num is not int");
});

this prints

1a is not int 
1.1 is not int
1e is not int
0x24 is not int
9.2233720368548E+18 is not int

When the browser sends p in the querystring, it is received as a string, not an int. is_int() will therefore always return false.

Instead try is_numeric() or ctype_digit()


I had a similar problem just now!

You can use the filter_input() function with FILTER_VALIDATE_INT and FILTER_NULL_ON_FAILURE to filter only integer values out of the $_GET variable. Works pretty accurately! :)

Check out my question here: How to check whether a variable in $_GET Array is an integer?


You could try using a casting operator to convert it to an integer:

$page = (int) $_GET['p'];

if($page == "")
{
    $page = 1;
}
if(empty($page) || !$page)
{
    setcookie("error", "Invalid page.", time()+3600);
    header("location:somethingwentwrong.php");
    die();
}
//else continue with code

Just for kicks, I tested out a few of the mentioned methods, plus one I've used as my go to solution for years when I know my input is a positive number or string equivalent.

I tested this with 125,000 iterations, with each iteration passing in the same set of variable types and values.

Method 1: is_int($value) || ctype_digit($value)
Method 2: (string)(int)$value == (string)$value
Method 3: strval(intval($value)) === strval($value)
Method 4: ctype_digit(strval($value))
Method 5: filter_var($value, FILTER_VALIDATE_INT) !== FALSE
Method 6: is_int($value) || ctype_digit($value) || (is_string($value) && $value[0] === '-' && filter_var($value, FILTER_VALIDATE_INT) !== FALSE)

Method 1: 0.0552167892456
Method 2: 0.126773834229
Method 3: 0.143012046814
Method 4: 0.0979189872742
Method 5: 0.112988948822
Method 6: 0.0858821868896

(I didn't even test the regex, I mean, seriously... regex for this?)

Things to note:
Method 4 always returns false for negative numbers (negative integer or string equivalent), so is a good method to consistently detect that a value is a positive integer.
Method 1 returns true for a negative integer, but false for a string equivalent of a negative integer, so don't use this method unless you are certain your input will never contain a negative number in string or integer form, and that if it does, your process won't break from this behavior.

Conclusions
So it seems that if you are certain that your input will not include a negative number, then it is almost twice as fast to use is_int and ctype_digit to validate that you have an integer. Using Method 1 with a fallback to method 5 when the variable is a string and the first character is a dash is the next fastest (especially when a majority of the input is actual integers or positive numbers in a string). All in all, if you need solid consistency, and you have no idea what the mix of data is coming in, and you must handle negatives in a consistent fashion, filter_var($value, FILTER_VALIDATE_INT) !== FALSE wins.

Code used to get the output above:

$u = "-10";
$v = "0";
$w = 0;
$x = "5";
$y = "5c";
$z = 1.44;

function is_int1($value){
    return (is_int($value) || ctype_digit($value));
}

function is_int2($value) {
    return ((string)(int)$value == (string)$value);
}

function is_int3($value) {
    return (strval(intval($value)) === strval($value));
}

function is_int4($value) {
    return (ctype_digit(strval($value)));
}

function is_int5($value) {
    return filter_var($value, FILTER_VALIDATE_INT) !== FALSE;
}

function is_int6($value){
    return (is_int($value) || ctype_digit($value) || (is_string($value) && $value[0] === '-' && filter_var($value, FILTER_VALIDATE_INT)) !== FALSE);
}

$start = microtime(TRUE);
for ($i=0; $i < 125000; $i++) {
  is_int1($u);
  is_int1($v);
  is_int1($w);
  is_int1($x);
  is_int1($y);
  is_int1($z);
}
$stop = microtime(TRUE);
$start2 = microtime(TRUE);
for ($j=0; $j < 125000; $j++) {
  is_int2($u);
  is_int2($v);
  is_int2($w);
  is_int2($x);
  is_int2($y);
  is_int2($z);
}
$stop2 = microtime(TRUE);
$start3 = microtime(TRUE);
for ($k=0; $k < 125000; $k++) {
  is_int3($u);
  is_int3($v);
  is_int3($w);
  is_int3($x);
  is_int3($y);
  is_int3($z);
}
$stop3 = microtime(TRUE);
$start4 = microtime(TRUE);
for ($l=0; $l < 125000; $l++) {
  is_int4($u);
  is_int4($v);
  is_int4($w);
  is_int4($x);
  is_int4($y);
  is_int4($z);
}
$stop4 = microtime(TRUE); 

$start5 = microtime(TRUE);
for ($m=0; $m < 125000; $m++) {
  is_int5($u);
  is_int5($v);
  is_int5($w);
  is_int5($x);
  is_int5($y);
  is_int5($z);
}
$stop5 = microtime(TRUE); 

$start6 = microtime(TRUE);
for ($n=0; $n < 125000; $n++) {
  is_int6($u);
  is_int6($v);
  is_int6($w);
  is_int6($x);
  is_int6($y);
  is_int6($z);
}
$stop6 = microtime(TRUE); 

$time = $stop - $start;  
$time2 = $stop2 - $start2;  
$time3 = $stop3 - $start3;  
$time4 = $stop4 - $start4;  
$time5 = $stop5 - $start5;  
$time6 = $stop6 - $start6;  
print "**Method 1:** $time <br>";
print "**Method 2:** $time2 <br>";
print "**Method 3:** $time3 <br>";
print "**Method 4:** $time4 <br>";  
print "**Method 5:** $time5 <br>";  
print "**Method 6:** $time6 <br>";  

All $_GET parameters have a string datatype, therefore, is_int will always return false.

You can see this by calling var_dump:

var_dump($_GET['p']); // string(2) "54"

Using is_numeric will provide the desired result (mind you, that allows values such as: 0x24).