37

Is there a nicer way to do this?

if( $_POST['id'] != (integer)$_POST['id'] )
    echo 'not a integer';

I've tried

if( !is_int($_POST['id']) )

But is_int() doesn't work for some reason.

My form looks like this

<form method="post">
   <input type="text" name="id">
</form>

I've researched is_int(), and it seems that if

is_int('23'); // would return false (not what I want)
is_int(23);   // would return true

I've also tried is_numeric()

is_numeric('23'); // return true
is_numeric(23); // return true
is_numeric('23.3'); // also returns true (not what I want)

it seems that the only way to do this is: [this is a bad way, do not do it, see note below]

if( '23' == (integer)'23' ) // return true
if( 23 == (integer)23 ) // return true
if( 23.3 == (integer)23.3 ) // return false
if( '23.3' == (integer)'23.3') // return false

But is there a function to do the above ?


Just to clarify, I want the following results

23     // return true
'23'   // return true
22.3   // return false
'23.3' // return false

Note: I just figured out my previous solution that I presented will return true for all strings. (thanks redreggae)

$var = 'hello';
if( $var != (integer)$var )
    echo 'not a integer';

// will return true! So this doesn't work either.

This is not a duplicate of Checking if a variable is an integer in PHP, because my requirements/definitions of integer is different than theres.

11
  • Try RegEXP. preg_match('/^[\d]*$/',$variable)!==FALSE Commented Oct 7, 2013 at 22:18
  • Why do you need to "validate"? Cannot you just filter values? So: $input = (int)$_POST['id'] . This will give you a 100% safe integer (or 0 in case of issues), and it is much easier to handle... Commented Oct 7, 2013 at 22:19
  • @Qualcuno I was thinking about that, but I want to notify the user that they didn't type in a correct number and not change it for them. Commented Oct 7, 2013 at 22:21
  • how about var_dump($_POST["id"]),this will tell you the datatype; Commented Oct 7, 2013 at 22:22
  • Why? Suppose he/she types "aaa", it will become 0 and you will refuse it the same way as you'd refuse the input 0. (because it's an id, so I suppose it will be > 0). You will just tell your users "wrong input", no need to detail it further! Commented Oct 7, 2013 at 22:23

12 Answers 12

55

try ctype_digit

if (!ctype_digit($_POST['id'])) {
    // contains non numeric characters
}

Note: It will only work with string types. So you have to cast to string your normal variables:

$var = 42;
$is_digit = ctype_digit((string)$var);

Also note: It doesn't work with negative integers. If you need this you'll have to go with regex. I found this for example:

EDIT: Thanks to LajosVeres, I've added the D modifier. So 123\n is not valid.

if (preg_match("/^-?[1-9][0-9]*$/D", $_POST['id'])) {
    echo 'String is a positive or negative integer.';
}

More: The simple test with casting will not work since "php" == 0 is true and "0" === 0 is false! See types comparisons table for that.

$var = 'php';
var_dump($var != (int)$var); // false

$var = '0';
var_dump($var !== (int)$var); // true
Sign up to request clarification or add additional context in comments.

17 Comments

$integer = 42; ctype_digit($integer); will return false
yes..if you check it with "normal" variable and not $_GET or $_POST than first cast to string. $is_digit = ctype_digit((string)42);
@aaron That is correct a string would need to be input. Luckily in case of $_POST values, they are always strings.
@GeoffreyHuck Well, they're not unknown once you've used them... I think ctype_digit should be used much more often than is_numeric, which has a more memorable name but is rarely actually the test you want to perform.
You need the D modifier to the preg_match. And it doesn't accept the 0 to number.
|
17

try filter_var function

filter_var($_POST['id'], FILTER_VALIDATE_INT);

use:

if(filter_var($_POST['id'], FILTER_VALIDATE_INT)) { 
    //Doing somethings...

}

Comments

9

In PHP $_POST values are always text (string type).

You can force a variable into the integer type like this:

$int_id = (int)$_POST['id'];

That will work if you are certain that $_POST['id'] should be an integer. But if you want to make absolutely sure that it contains only numbers from 0 to 9 and no other signs or symbols use:

if( ctype_digit( $_POST['id'] ) )
{
  $int_id = (int)$_POST['id'];
}

1 Comment

Not true: $_POST can be array.
3

if you know it is a string variable (like post o get values), you can use:

function is_really_integer($var) {
  return $var == (string)(integer)$var;
}

2 Comments

this is what I do and it's very fast
I need to extract a substring from a string and that substring must be a number. If not, (int)(substring) is 0. So, (string)(integer)(substring) is a valid check for the substring to be numeric.
3

Using is_numeric() for checking if a variable is an integer is a bad idea. This function will send TRUE for 3.14 for example. It's not the expected behavior

To do this correctly, you can use one of these options :

Considering this variables array :

$variables = [
    "TEST 0" => 0,
    "TEST 1" => 42,
    "TEST 2" => 4.2,
    "TEST 3" => .42,
    "TEST 4" => 42.,
    "TEST 5" => "42",
    "TEST 6" => "a42",
    "TEST 7" => "42a",
    "TEST 8" => 0x24,
    "TEST 9" => 1337e0
];

The first option (FILTER_VALIDATE_INT Way) :

# Check if your variable is an integer
if( ! filter_var($variable, FILTER_VALIDATE_INT) ){
  echo "Your variable is not an integer";
}

Output :

TEST 0 : 0 (type:integer) is not an integer ✘
TEST 1 : 42 (type:integer) is an integer ✔
TEST 2 : 4.2 (type:double) is not an integer ✘
TEST 3 : 0.42 (type:double) is not an integer ✘
TEST 4 : 42 (type:double) is an integer ✔
TEST 5 : 42 (type:string) is an integer ✔
TEST 6 : a42 (type:string) is not an integer ✘
TEST 7 : 42a (type:string) is not an integer ✘
TEST 8 : 36 (type:integer) is an integer ✔
TEST 9 : 1337 (type:double) is an integer ✔

The second option (CASTING COMPARISON Way) :

# Check if your variable is an integer
if ( strval($variable) != strval(intval($variable)) ) {
  echo "Your variable is not an integer";
}

Output :

TEST 0 : 0 (type:integer) is an integer ✔
TEST 1 : 42 (type:integer) is an integer ✔
TEST 2 : 4.2 (type:double) is not an integer ✘
TEST 3 : 0.42 (type:double) is not an integer ✘
TEST 4 : 42 (type:double) is an integer ✔
TEST 5 : 42 (type:string) is an integer ✔
TEST 6 : a42 (type:string) is not an integer ✘
TEST 7 : 42a (type:string) is not an integer ✘
TEST 8 : 36 (type:integer) is an integer ✔
TEST 9 : 1337 (type:double) is an integer ✔

The third option (CTYPE_DIGIT Way) :

# Check if your variable is an integer
if( ! ctype_digit(strval($variable)) ){
  echo "Your variable is not an integer";
}

Output :

TEST 0 : 0 (type:integer) is an integer ✔
TEST 1 : 42 (type:integer) is an integer ✔
TEST 2 : 4.2 (type:double) is not an integer ✘
TEST 3 : 0.42 (type:double) is not an integer ✘
TEST 4 : 42 (type:double) is an integer ✔
TEST 5 : 42 (type:string) is an integer ✔
TEST 6 : a42 (type:string) is not an integer ✘
TEST 7 : 42a (type:string) is not an integer ✘
TEST 8 : 36 (type:integer) is an integer ✔
TEST 9 : 1337 (type:double) is an integer ✔

The fourth option (REGEX Way) :

# Check if your variable is an integer
if( ! preg_match('/^\d+$/', $variable) ){
  echo "Your variable is not an integer";
}

Output :

TEST 0 : 0 (type:integer) is an integer ✔
TEST 1 : 42 (type:integer) is an integer ✔
TEST 2 : 4.2 (type:double) is not an integer ✘
TEST 3 : 0.42 (type:double) is not an integer ✘
TEST 4 : 42 (type:double) is an integer ✔
TEST 5 : 42 (type:string) is an integer ✔
TEST 6 : a42 (type:string) is not an integer ✘
TEST 7 : 42a (type:string) is not an integer ✘
TEST 8 : 36 (type:integer) is an integer ✔
TEST 9 : 1337 (type:double) is an integer ✔

Comments

2

Check it out: http://php.net/manual/en/function.ctype-digit.php - it validates if string contains only digits, so be sure not to pass an int to that function as it will most likely return false; However all values coming from $_POST are always strings so you are safe. Also it will not validate negative number such as -18 since - is not a digit, but you can always do ctype_digit(ltrim($number, '-'))

is_int checks the variable type which in your case is string; it would be the same as (integer)$v === $v as == does some real obscure things in order to compare two variables of a different type; you should always use === unless you want mess like "0af5gbd" == 0 to return true

Also, keep in mind that ctype_digit will not tell you if the string can be actually converted to a valid int since maximum integer value is PHP_INT_MAX; If your value is bigger than that, you will get PHP_INT_MAX anyway.

1 Comment

nice idea with ltrim($number, '-')..but remember that ---123 will work in this way.
2
preg_match('/^\d+$/D',$variable) //edit 

Comments

1

The accepted answer using ctype_digit is correct, however you can make life easier using a function. This will covert the variable to a string, so you don't have to:

function is_num($x){
    if(!is_string($x)){
        $x=(string)$x;
    }
    if(ctype_digit($x)){
      return true;
    }
    return false;
}

Usage:

if (is_num(56)) {
    // its a number
}

if (is_num('56')) {
    // its a number
}

If you want to accept decimals too, use this:

function is_num($x){
    if(!is_string($x)){
        $x=(string)$x;
    }    
    if (strpos($x,'.')!==false) {      
        if(substr_count($x,'.')>1||strpos($x,'.')<1||strpos($x,'.')>=strlen($x)){
            return false;    
        }
        $x=str_replace('.','',$x);    
    }
    if(ctype_digit($x)){
        return true;
    }  
    return false;
}

Comments

1

Use filter_var but be careful it's return bool.

In case you have string '0' => you will get false

Right way to use:

if (filter_var($_POST['id'], FILTER_VALIDATE_INT) !== false) { 
    // Doing somethings...
}

Comments

0

Use the following, universal function to check all types:

function is_digit($mixed) {
    if(is_int($mixed)) {
        return true;
    } elseif(is_string($mixed)) {
        return ctype_digit($mixed);
    }

    return false;
}

Comments

0

I use:

is_int($val)||ctype_digit($val)

Note than this catch only positive integer strings

Comments

0

is_int is perfectly working there is not need of extra code

or you can check using is_numeric

1 Comment

If you read my question, you'd see why is_int and is_numeric don't give me the right values.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.