php string comparison, why cast to float
php, string
Solution
TL;DR
This is the result of "smart" comparison for strings in PHP. Yes, it is not what you can expect, but for now - it is how it's implemented.
Digging deeper
Maintaining comparison
To realize reason for this, you'll need to look into PHP sources (for greater good or bad). In PHP, there is such thing as `compare_function` which is used to handle comparisons. It contains different cases for different types of arguments. So, for strings it is:
case TYPE_PAIR(IS_STRING, IS_STRING):
zendi_smart_strcmp(result, op1, op2);
return SUCCESS;
`TYPE_PAIR`, as any other stuff, is just a macro.
Moving deeper
From previous step, we're now moving to `zendi_smart_strcmp`. It is PHP's "smart thing" to compare two strings. And here we are:
if ((ret1=is_numeric_string_ex(Z_STRVAL_P(s1), Z_STRLEN_P(s1), &lval1, &dval1, 0, &oflow1)) && (ret2=is_numeric_string_ex(Z_STRVAL_P(s2), Z_STRLEN_P(s2), &lval2, &dval2, 0, &oflow2)))
{
//compare as two numbers, I've omitted this
}
else
{
string_cmp: //yes, yes, we're using goto
Z_LVAL_P(result) = zend_binary_zval_strcmp(s1, s2);
ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_LVAL_P(result)));
}
Inside omitted code there is also part for determining if result is `long` or `double` - but that's irrelevant since we've already know what caused comparison as floats: as long as strings can be treated as numbers, PHP will use that to produce comparison - and - yes, that is intended (so, yes, string `"1000"` is equal to `"1e3"` when using `==` operator, same for `"255"` and `"0xFF"` - they don't contain "e" (exponent) part, but still are equal)
Solution
You may restrict the case with, for example:
var_dump("0e8" == "0e6"); //true
So no need to deal with md5 hashes. If compare that as numbers, it's true (since both operands are valid floats, and `0 x 10^8` == `0 x 10^6`). But they are not same as strings. Thus, your direct solution would be - use `===` operator to compare:
var_dump("0e8" === "0e6"); //false
Yes, it's a confusing thing in PHP - because it is not obvious (and debatable at least). But that's how it currently works.
Problem
Ive come across this code ``` <?php $a = md5('240610708'); $b = md5('QNKCDZO'); echo "$a\n"; echo "$b\n"; echo "\n"; var_dump($a); var_dump($b); var_dump($a == $b); ``` This evaluates that 2 strings which could be a number `0exxxxxx`. I understand that if either are used in a numeric context then the string will be taken as a number, as confirmed by http://www.php.net/manual/en/language.types.string.php#language.types.string.conversion When a string is evaluated in a numeric context, the resulting value and type are determined as follows. If the string does not contain any of the characters '.', 'e', or 'E' and the numeric value fits into integer type limits (as defined by PHP_INT_MAX), the string will be evaluated as an integer. In all other cases it will be evaluated as a float. 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). Valid numeric data is an optional sign, followed by one or more digits (optionally containing a decimal point), followed by an optional exponent. The exponent is an 'e' or 'E' followed by one or more digits. Im just not sure why `==` triggers a numeric comparison when both sides are of type string.