0

I was using is_numeric to validate integers coming from POST data like:

if( ! is_numeric($_POST['integer_string'])) return FALSE // not a integer

Then I discovered is_numeric will return TRUE if the value has a decimal.

Next I tried casting and is_int:

$int = (int) $_POST['numeric_string'];
if( ! $int)  return FALSE // not a integer

But casting will cut the integer after a non numeric value is passed.

$int = '222i2';
echo $int;
// 222

The integer I'm attempting to validate will be used in WHERE clauses in SQL to identify integer primary keys.

What is a fool proof way to validate an integer from POST data or how do you personally deal with this problem?

Michael Rich
  • 191
  • 1
  • 11
  • There's many dupes. I've chosen [php validate integer](http://stackoverflow.com/questions/4100022/php-validate-integer) because it contains two decent answers: regular expressions and `filter_input()`. – Álvaro González Nov 04 '13 at 16:28
  • [`ctype_digit`](http://php.net/ctype_digit) – deceze Nov 04 '13 at 16:29
  • I viewed a lot of other answers, but none of them specified the integer being a primary key. But I suppose it's not that different from other integers. – Michael Rich Nov 04 '13 at 17:10
  • That doesn't really matter. The only thing that makes the integer more risky compared to others is the usage within an SQL statement. That's why I included the note about prepared statements in my answer. – Fleshgrinder Nov 04 '13 at 17:21
  • A primary key can be any data type supported by the database engine. It can also contain more than one column. There's nothing in the PK concept that makes it synonym for integer. – Álvaro González Nov 04 '13 at 17:24

3 Answers3

2

PHP has filter input

http://www.php.net/manual/en/function.filter-input.php

which you can use with FILTER_VALIDATE_INT

Shaun Hare
  • 3,771
  • 2
  • 24
  • 36
2

A fool proof way to validate anything in PHP are filter_var() and filter_input(). Plus of course using prepared statements either with PDO or MySQLi.

For your specific use case:

<?php

$id = filter_input(
    INPUT_POST,            // Submitted via $_POST
    "integer_string",      // Offset name in $_POST
    FILTER_VALIDATE_INT,   // The validation method
    FILTER_REQUIRE_SCALAR  // NULL and empty aren't valid
);

if ($id === false) {
    throw new InvalidArgumentException("Not an int!");
}

// Assuming you have a Database object that wraps your DB stuff.
$database->query("SELECT * FROM `table` WHERE `id` = ? LIMIT 1", "d", [ $id ]);

?>

If your PHP version doesn't support the various filter functions do the following:

<?php

if (ctype_digit($_POST["integer_string"]) === false) {
    throw new InvalidArgumentException;
}

// Before PHP 5.1.0
if (empty($_POST["integer_string"]) || ctype_digit($_POST["integer_string"]) === false) {
    throw new InvalidArgumentException;
}

?>
Fleshgrinder
  • 15,703
  • 4
  • 47
  • 56
0

For php < 5.2 you can use a regular expression:

preg_match("/^[0-9]+$/", $_POST["integer_string"]);

http://php.net/manual/en/function.preg-match.php

ProGM
  • 6,949
  • 4
  • 33
  • 52