It seems that PHP's ===
operator is case sensitive. So is there a reason to use strcmp()
?
Is it safe to do something like the following?
if ($password === $password2) { ... }
The syntax of the strcmp() function is: Syntax: int strcmp (const char* str1, const char* str2); The strcmp() function is used to compare two strings two strings str1 and str2 . If two strings are same then strcmp() returns 0 , otherwise, it returns a non-zero value.
strcmp() should be used if you need to determine which string is "greater", typically for sorting operations.
The "strcasecmp()" function is a case insensitive string comparison function. This function compares two strings; the strcmp() function is case sensitive but the strcmp() and strcasecmp() functions both work the same. But it does not distinguish between uppercase and lowercase letters.
The reason to use it is because strcmp
returns < 0 if str1 is less than str2; > 0 if str1 is greater than str2, and 0 if they are equal.
===
only returns true
or false
, it doesn't tell you which is the "greater" string.
You should never use ==
for string comparison. ===
is OK.
$something = 0;
echo ('password123' == $something) ? 'true' : 'false';
Just run the above code and you'll see why.
$something = 0;
echo ('password123' === $something) ? 'true' : 'false';
Now, that's a little better.
Don't use ==
in PHP. It will not do what you expect. Even if you are comparing strings to strings, PHP will implicitly cast them to floats and do a numerical comparison if they appear numerical.
For example '1e3' == '1000'
returns true. You should use ===
instead.
Well...according to this PHP bug report, you can even get 0wned.
<?php
$pass = isset($_GET['pass']) ? $_GET['pass'] : '';
// Query /?pass[]= will authorize user
//strcmp and strcasecmp both are prone to this hack
if ( strcasecmp( $pass, '123456' ) == 0 ){
echo 'You successfully logged in.';
}
?>
It gives you a warning, but still bypass the comparison.
You should be doing ===
as @postfuturist suggested.
Always remember, when comparing strings, you should use the ===
operator (strict comparison) and not ==
operator (loose comparison).
Summing up all answers:
==
is a bad idea for string comparisons.
It will give you "surprising" results in many cases. Don't trust it.
===
is fine, and will give you the best performance.
strcmp()
should be used if you need to determine which string is "greater", typically for sorting operations.
Using ==
might be dangerous.
Note, that it would cast the variable to another data type if the two differs.
Examples:
echo (1 == '1') ? 'true' : 'false';
echo (1 == true) ? 'true' : 'false';
As you can see, these two are from different types, but the result is true
, which might not be what your code will expect.
Using ===
, however, is recommended as test shows that it's a bit faster than strcmp()
and its case-insensitive alternative strcasecmp()
.
Quick googling yells this speed comparison: http://snipplr.com/view/758/
strcmp()
and ===
are both case sensitive, but ===
is much faster.
Sample code: Speed Test: strcmp vs ===
strcmp will return different values based on the environment it is running in (Linux/Windows)!
The reason is the that it has a bug as the bug report says - Bug #53999strcmp() doesn't always return -1, 0, or 1
You can use strcmp()
if you wish to order/compare strings lexicographically. If you just wish to check for equality then ==
is just fine.
Also, the function can help in sorting. To be more clear about sorting. strcmp() returns less than 0 if string1 sorts before string2, greater than 0 if string2 sorts before string1 or 0 if they are the same. For example
$first_string = "aabo";
$second_string = "aaao";
echo $n = strcmp($first_string, $second_string);
The function will return greater than zero, as aaao is sorting before aabo.
if ($password === $password2) { ... }
is not a safe thing to do when comparing passwords or password hashes where one of the inputs is user controlled.
In that case it creates a timing oracle allowing an attacker to derive the actual password hash from execution time differences.
Use if (hash_equals($password, $password2)) { ... }
instead, because hash_equals performs "timing attack safe string comparison".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With