2

The following funciton drove me nuts. How on earth 100x could be equal to 100 and then 100x is reported as an integer?
For the life of me, I cannot figure it out. You can copy and paste the whole thing and see it for yourself.
I'm missing a simple point somewhere here, help me out guys.

function blp_int($val) {
    $orgval = $val;
    $num = (int)$val;    
    echo "<li><font color=red>val: ". $val . " is being checked to see if it's an integer or not";
    echo "<li><font color=red>orgval: ". $orgval ;
    echo "<li><font color=red>num: ". $num ;
    if ($orgval==$num) {
        echo "<li><font color=red><b>YES IT IS! the [{$orgval}] is equal to [{$num}]</b>";
        return true;
    }
    return false;
}

if (blp_int("100"))
{
    echo "<h1>100 is an integer!</h1>";
}
else
{
    echo "<h1>100 is NOT an integer!</h1>";
}

if (blp_int("100x"))
{
    echo "<h1>100x is an integer!</h1>";
}
else
{
    echo "<h1>100x is NOT an integer!</h1>";
}

the above code, when run returns the following;

val: 100 is being checked to see if it's an integer or not
orgval: 100
num: 100
YES IT IS. the [100] is equal to [100]
100 is an integer!

val: 100x is being checked to see if it's an integer or not
orgval: 100x
num: 100
YES IT IS. the [100x] is equal to [100]
100x is an integer!

I can remedy the situation by adding the following bits

    if (!is_numeric($val))
    {
        return false;
    }

to the top of the blp_int function right off the bat but,.. I'm still super curious to find out why on earth php thinks 100x=100 are equals.

Average Joe
  • 4,521
  • 9
  • 53
  • 81
  • `is_int`, `ctype_digit`, `filter_var($string, FILTER_VALIDATE_INT)`, the latter can disallow/allow hex & octal ints if you want. If you want to use your code, case to int, but then back to string: `if((string)$orgval==(string)(int)$orgval)` – Wrikken Feb 29 '12 at 19:38
  • Your function use `echo` and `return` , try not writing function this way. what's the output? I mean what you see on the screen when `echo` the variables before the int casting and after? – Ofir Baruch Feb 29 '12 at 19:39

4 Answers4

2

As you can see in this example, casting 100x as an integer converts it to 100. Since you are not using strict comparison, '100x' == 100 is true. PHP removes the x from it to make just 100.

You could use strict comparison (which also compares the types), such that '100x' === 100 would return false. Using it, any time a string was compared to an integer, it would return false.


As per your edit: is_numeric may not be the most reliable, as it will return true for numbers formatted as a string, such as '100'. If you want the number to be an integer (and never a string), you could use is_integer instead. I'm not quite sure what exactly you're doing, but i thought I'd add this note.

animuson
  • 53,861
  • 28
  • 137
  • 147
  • What's the best way to write a function ( maybe call it "is_this_integer($v)" ) which returns true when $V passed to it *seems* to be an integer to the naked eye? so, not just 1 or -1 but also strings such as '1' or ' 1 ' or '-1 ' or ' -1' will all return true, and needless to say 100x or '100x' will not return as integer. – Average Joe Mar 03 '12 at 14:34
1

I think you should use three equal signs in your IF:

if ($orgval===$num) {

Otherwise PHP casts the value 100x to 100 and 100=100.

Documentation: Comparison Operators

ComFreek
  • 29,044
  • 18
  • 104
  • 156
1

What kind of check do you want to do? There are a few ways you could go about it:

if (preg_match('!^[0-9]+$!', $input))

if (intval($input) == $input)

if (intval($input) === $input)

if ('x'.intval($input) === 'x'.$input)

It depends on how closely you want to check if it's an integer. Does it matter if you need to trim() it first?

Cal
  • 7,067
  • 25
  • 28
0

Either cast it to an int or try http://php.net/manual/en/function.ctype-digit.php. You also need === in your if.

Bot
  • 11,868
  • 11
  • 75
  • 131