2

Here, $username is a userinput, and I am trying to check if the entry was a username, or a userid (all integers)

I thought to use the intval function to see if $username and intval($username) is same, which means the input is a userid.

The input I gave was google. and intval('google') is 0. Why does the true part of the if statement get executed? Any idea?

I amnt using === because the userinput will be a string.

if($username == intval($username))
    {
     echo "userid";
    }
    else
    {
    echo "username";
    }

Not sure why the unexpected behaviour is happening.

Kishor
  • 1,513
  • 2
  • 15
  • 25
  • 1
    Why you are not trying with is_numeric()? – Sachin I Jun 25 '15 at 13:01
  • Yeah, I will just use a better function, probably `is_numberic` but just wanted to know why `intval` and `if` condition is having this unexpected behaviour. – Kishor Jun 25 '15 at 13:03

2 Answers2

3

It is happening because of the conversion & type juggling of comparison operators.

intval('anystring') will be 0.

And when a string is getting compared it is also converted into numeric value. So when the string is converted it will also be 0.

If you compare a number with a string or the comparison involves numerical strings, then each string is converted to a number and the comparison performed numerically. These rules also apply to the switch statement. The type conversion does not take place when the comparison is === or !== as this involves comparing the type as well as the value.

So in this case 'google1' == intval('google') will be 0 == 0 and that is true. For this type of comparison always use identical(===) comparison.

comparison

Sougata Bose
  • 31,517
  • 8
  • 49
  • 87
  • So when a string is compared to an integer, the string gets converted to an int, and is then compared to the integer? ( which is really weird?) – Kishor Jun 25 '15 at 13:04
  • Yes it is. Thats why you should use `===`. – Sougata Bose Jun 25 '15 at 13:05
  • Well, in my case, I cant really use `===` because `$username` will always be a string, and `intval` wont be. But I got your point. Makes sense now. Didnt knew it worked this way. Thanks! :) Will mark it as the right answer, because it obviously is. – Kishor Jun 25 '15 at 13:06
  • Then you have to do some trick with them. – Sougata Bose Jun 25 '15 at 13:08
  • Will do that ;) Yep. – Kishor Jun 25 '15 at 13:08
  • With the function you used (intval()), you will not get the actual result as you are dealing with the string anyhow, even though it would all be alphabates or numeric or a mix. So, try to use different methods like is_numeric() to get it done. – prava Jun 25 '15 at 13:13
2

This happens because of type juggling.
From the PHP Manual on Comparison Operators:

Comparison with Various Types

Type of Operand 1          | Type of Operand 2          | Result
----------------------------------------------------------------------------------------------------------------
string, resource or number | string, resource or number | Translate strings and resources to numbers, usual math

Since one operand is a number and one is a string here, the string is converted to a number, effectively making your check equivalent to:

if(intval($username) == intval($username))

Now, how to solve that problem:

is_int will not work because it checks the type of the variable, and while is_numeric will sort-of work, it will also return true for decimals, such as 123.456, which is probably not what you want.

The only real solution I can think of is to convert the resulting integer back into a string:

if($username === strval(intval($username)))
Community
  • 1
  • 1
Siguza
  • 21,155
  • 6
  • 52
  • 89