Intval的意外行为[重复]

This question already has an answer here:

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.

</div>

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

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)))