Friday, November 16, 2012

PHP is_int() vs. is_numeric()

These two functions seem similar, don't they? In fact, is_int() seems like a more specific version of is_numeric(). You may, for example, want to make sure that the ID of a blog post that is being passed through the query string is not only numeric but, specifically, an integer. After all, 7.145 is numeric, but you want to make sure the incoming value hasn't been tinkered with and is simply a 7. You'd be tempted to do something like the following:

if(isset($_GET['blog_id']) && is_int($_GET['blog_id'])) {
     // do something with the blog ID
}

Unfortunately, this won't work. It turns out that is_int() will return false when the value passed to it is a string, whereas is_numeric is perfectly capable of evaluating a string and deciding whether it's something numeric. So, even if the value of blog_id as passed through the query string is a 7, this will return false.

"Wait... What?" you may be saying to yourself, right now. Yes, you read that correctly. It will be false, even if it's a 7. That's because (and here's the important bit) anything passed in the query string is considered by PHP to be a string. Even though there are no quotes around it, even though, to you and me, it's a number 7, PHP reads that as a string. This goes for all superglobals, in fact. In short, anything that is accessed through a '$_<something or other>' will return as a string: $_POST, $_SESSION, you get the idea.

One way around this might be to cast the value as an int, like so:

(int)$_GET['blog_id']

Or you could settle for is_numeric(), knowing that it will be fine with scientific notation, floats, etc. But that might be enough to make sure the value is safe, even if it doesn't match.

The two main takeaways for me, here, are that:

  1. Values stored in superglobals translate as strings in PHP.
  2. is_numeric() can reliably check to see whether strings are numeric or not, whereas is_int() will return false for strings, even if it looks like an integer.
Hope this helps someone!