This question already has answers here:
Why does PHP convert a string with the letter E into a number?
(7 answers)
Closed 8 years ago.
var_dump(md5('240610708') == md5('QNKCDZO'));
Output:
bool(true)
Example: http://3v4l.org/2vrMi
md5('240610708') 's result is 0e462097431906509019562988736854.
md5('QNKCDZO') 's result is 0e830400451993494058024219903391.
They are both float number format strings (numerical strings), and if you use == in php, when 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.
Both of the strings are converted to 0 when compared with ==, if you want to compare them as string, remember to use ===(strict comparison) instead.
See: PHP expresses two different strings to be the same
You need to use the type-sensitive comparison operator ===.
The hashes evaluate to 0e462097431906509019562988736854 and 0e830400451993494058024219903391, respectively. When you use ==, each is converted to a numeric representation because of the e (scientific notation), so they each become 0. 0 == 0 is true.
On the other hand, this:
md5('240610708') === md5('QNKCDZO')
returns false because the string values are different. === forces type-sensitive comparison.
Related
This question already has answers here:
PHP intval() weird results
(5 answers)
Closed 7 years ago.
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.
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)))
Can somebody explain to me why this codes returns "TRUE".
I know that i should use the "===" rather "==" but I run to this code and wondering why it returns to true. Thanks in advance.
<?php
$s = "final";
$i = 0;
if($s == $i){
echo "TRUE";
}else{
echo "FALSE";
}
When you are trying to compare string and number, interpretator converts your string to int, so you got 0 == 0 at final. Thats why string == 0 is true.
Take a look at the PHP comparison tables.
You can see in the "Loose comparisons with ==" table that comparing the number 0 with a string containing text ("php" in the example) evaluates to TRUE.
This is just a property of the loose comparisons implemented in PHP. I wouldn't search for any more logic behind this than that this is a given.
As mentionned above, it is an issue with php's loose comparison. The accepted answer on php string comparasion to 0 integer returns true? Explains it well enough IMHO. in short "==" attempts to cast your string into an int, and since it fails, the resulting int has a value of 0
From PHP comparison operators:
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.
And from PHP string conversion to numbers:
The value is given by the initial portion of the string. If the string starts with valid numeric data, this will be the value used. Otherwise, the value will be 0 (zero).
So when you compare integer and a string, PHP tries to convert string to integer first and as "final" doesn't contain any valid numeric data, it is converted to 0.
You can try:
var_dump( intval('12final') ); //int(12)
var_dump( floatval('1.2final') ); //float(1.2)
This is because of both 12final and 1.2final start with valid numeric data (12 and 1.2 respecrively), their converted value is not 0.
Can someone explain why the following two statements return true?
if ('0e368798' == '00000000')
or
if ((string)'0e368798' == (string)'00000000')
Why do I have to use the strict operator to check the equality of these two strings?
Because XeY is X * 10^(Y), and 0 times anything is 0. 0000000 is also 0. And == in PHP very intuitively thinks that if it can be converted into a number, it should be.
EDIT: It was in a helpful comment that is now deleted, so with apologies to the commenter whose name I did not catch, I will repeat it here - from PHP docs on comparison:
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.
I encountered a strange and unexpected behavior in PHP while comparing some string values. The first two statements below return true when I would expect them to return false. The last statement returns false as expected. I'm aware of PHP's Type Juggling, but what I understand from the docs is that type juggling happens when you are comparing two different data types like a string and an integer. In the examples below though both literals are strings. Does this mean that when you are doing string comparison in PHP it inspects both strings to see if they look like integers and if so type casts the both of them to integers and then compares those integer values. So my question is under what conditions does this behavior happen, how exactly does string comparison work in PHP?
var_dump("10" == "10.0000");
var_dump("10" == "+10.");
var_dump("10" == "10 ");
#output
bool(true)
bool(true)
bool(false)
Updates
So baba's answer below comparison involves numerical strings really helped in getting me to understand what's going on. The function is_numeric will return to you whether or not a string is considered to be a numeric string. interestingly "10 " is not considered a numeric string but " 10" is. I dug around the PHP source code and I believe the implementation of is_numeric is in the is_numeric_string_ex function. From that one can tell exactly when PHP will treat a string as a numeric string.
You are getting error because of the position of the space this would return true
var_dump("10" == " 10"); // true
So if you RUN
var_dump("10" == "10 "); //false
What you are actually Running is because it would be treated as a string
var_dump("10" == 0); //false
This is because Type juggling would convert "10 " to 0 this is in the PHP Documentation
FROM PHP DOC
TRUE if $a is equal to $b after type juggling.
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.
If you want to trick type juggling
var_dump("10" == 0 + "10 "); // true
This is Because
An example of PHP's automatic type conversion is the addition operator '+'. If either operand is a float, then both operands are evaluated as floats, and the result will be a float. Otherwise, the operands will be interpreted as integers, and the result will also be an integer. Note that this does not change the types of the operands themselves; the only change is in how the operands are evaluated and what the type of the expression itself is.
I suppose the definite answer lies buried somewhere in the vastness of
compare_function
in php-src/Zend/zend_operators.c and the macros used in there.
In this case, all the 'strings' except the last one, are treated like floats or integers, and then compared. Thats why line 1 and 2 give a true.
In line 3 there is a space in the string, and that means for php that is is a 'real' string, and that line gets strings compared.
I do not like loose typed languages either, but for php this is the way it works.
I'm comparing strings with comparison operators.
I need some sort of explanation for the below two comparisons and their result.
if('ai' > 'i')
{
echo 'Yes';
}
else
{
echo 'No';
}
output: No
Why do these output this way?
if('ia' > 'i')
{
echo 'Yes';
}
else
{
echo 'No';
}
Output: Yes
Again, why?
Maybe I forgot some basics, but I really need some explanation of these comparison examples to understand this output.
PHP will compare alpha strings using the greater than and less than comparison operators based upon alphabetical order.
In the first example, ai comes before i in alphabetical order so the test of > (greater than) is false - earlier in the order is considered 'less than' rather than 'greater than'.
In the second example, ia comes after i alphabetical order so the test of > (greater than) is true - later in the order being considered 'greater than'.
To expand on coderabbi's answer:
It is the same type of logic as when you order by number in some applications and get results like the following:
0
1
105
11
2
21
3
333
34
It's not based on string length, but rather each character in order of the string.
The < and > comparison operators in PHP will compare the first character of your string, then compare other characters that follows in the strings.
Therefore, your first expression ai (first string) and i (second string) a is the first character in the string compared with i as the first character in the second string with > will return false, and subsequently the second statement will return true due to the same reason.
However, if you really need to compare two longer string values with many characters, you may try using the substr_compare method:
substr_compare("abcde", "bc", 1, 2);
in this sample, you have your two strings to be compared, 1 is the offset start position, and 2 represents how many characters you want to compare to the right of those strings. -1 will means the offset start from the end of the first string. e.g. do something like this:
substr_compare("string1", "string2", 0, length);
also, consider using strcmp() also i.e. strcmp("string1", "string2", length) where length is number of character you want to compare from the two strings.
When both strings are in number format, PHP will convert the strings to numbers and convert the values.
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.
Reference: Comparison Operators