== and ===

php.internals

Hendy Irawan

21 years ago
Just came across this: http://bugs.php.net/bug.php?id=23110 I've been programming PHP since PHP 3 and wasn't even aware of this behavior. "Numeric strings"? What is that? if ($typedPassword == $password) doSomeAdministrativeTaskHere(); You better not use '000000001' as password, or '0e00.0000', since people would be able to use '' (yes, empty string!) to hack your app.
-- Hendy Irawan http://www.gauldong.net http://dev.gauldong.net

Sara Golemon

21 years ago
> Just came across this: > http://bugs.php.net/bug.php?id=23110 > > I've been programming PHP since PHP 3 > and wasn't even aware of this behavior. >
And now you are. PHP is a loosely typed language. Odds are it's one of the things which attracted you to it in the first place.
> "Numeric strings"? What is that? >
Roughly speaking, a string matching the pattern: /^(-\d)?\d*(.[0-9]*)?(E[+-]\d+)?/ Though that's not precisely how the engine handles it internally.
> if ($typedPassword == $password) doSomeAdministrativeTaskHere(); > > You better not use '000000001' as password, or '0e00.0000', since > people would be able to use '' (yes, empty string!) to hack your app. >
Quick! Go change your password!

Hendy Irawan

21 years ago
On 4/19/05, Sara Golemon <pollita@php.net> wrote:
> > Just came across this: > > http://bugs.php.net/bug.php?id=23110 > > > > I've been programming PHP since PHP 3 > > and wasn't even aware of this behavior. > > > And now you are. > > PHP is a loosely typed language. Odds are it's one of the things which > attracted you to it in the first place.
I can understand 0 == '' is true, but the string thingy is a bit surprising me. I thought === is only used when comparing different types, so it's used to strictly compare things of the same type as well? (as the case, strings, but objects come to mind as well) I guess === is a strict equality operator more than it is a type equality operator.
> > "Numeric strings"? What is that? > > > Roughly speaking, a string matching the pattern: > /^(-\d)?\d*(.[0-9]*)?(E[+-]\d+)?/ > Though that's not precisely how the engine handles it internally. > > > if ($typedPassword == $password) doSomeAdministrativeTaskHere(); > > > > You better not use '000000001' as password, or '0e00.0000', since > > people would be able to use '' (yes, empty string!) to hack your app. > > > Quick! Go change your password!
<?php echo '0' == '0.0000e0' ?> 1 <?php echo '0' == 'asadoaskd' ?> (nothing, false) <?php echo '0' == (int)'adasd' ?> 1 That confuses me more (but understandable, and thank God PHP behave this way)... I thought 'asdasd' is 0 when [implicitly] converted to int [for comparison]? I guess I never knew PHP well :-(
-- Hendy Irawan http://www.gauldong.net http://dev.gauldong.net

Sara Golemon

21 years ago
> <?php echo '0' == '0.0000e0' ?> > 1 > > <?php echo '0' == 'asadoaskd' ?> > (nothing, false) > > <?php echo '0' == (int)'adasd' ?> > 1 > > That confuses me more (but understandable, and thank God PHP behave > this way)... I thought 'asdasd' is 0 when [implicitly] converted to > int [for comparison]? I guess I never knew PHP well :-( >
That would be the 'Roughly Speaking' and 'not precisely how the engine handles it internally' parts. In the case of string to string comparison there must be at least one digit involved at the start of the string (or a plus/minus sign followed by digits, etc...) in order to qualify as a numeric string. if (int && string) convert to int if (string && int) convert to int if (string && string && both strings start with numerics) convert both to int There's also float versions of those, but... you get the picture. -Sara

Hendy Irawan

21 years ago
On 4/19/05, Sara Golemon <pollita@php.net> wrote:
> > <?php echo '0' == '0.0000e0' ?> > > 1 > > > > <?php echo '0' == 'asadoaskd' ?> > > (nothing, false) > > > > <?php echo '0' == (int)'adasd' ?> > > 1 > > > > That confuses me more (but understandable, and thank God PHP behave > > this way)... I thought 'asdasd' is 0 when [implicitly] converted to > > int [for comparison]? I guess I never knew PHP well :-( > > > That would be the 'Roughly Speaking' and 'not precisely how the engine > handles it internally' parts. > > In the case of string to string comparison there must be at least one digit > involved at the start of the string (or a plus/minus sign followed by > digits, etc...) in order to qualify as a numeric string.
I don't see this is the case: <?php echo '0' == '0asodkaowueoq' ?> (false) <?php echo '0' == '0 asdkasod' ?> (false) Isn't '0asdkoasdk' a numeric string? However: <?php echo 0 == 'asodkasodk' ?> 1 (this is expected, although for the $password case, it can lead to security holes). More niceties: <?php echo null == 0 ?> 1 <?php echo null == '' ?> 1 <?php echo null == '0' ?> (false) Programming in PHP can be a lot of fun! ;-)
-- Hendy Irawan http://www.gauldong.net http://dev.gauldong.net

Andrey Hristov

21 years ago
Hi, don't forget that PHP was made for web programming and in this world you get from the user the input only as string therefore <?php echo '0' == 'asadoaskd' ?> (nothing, false)
>> Quite ok I will say. Nobody can enter '0' and pass through the check.
<?php echo '0' == (int)'adasd' ?> 1
>> You don't cast the passwords, don't you?
One more thing, consider creating a hash of the password and don't store the password in clear text. When the password is hashed, it is a string and you can compare it without any problems. Either you can use sha1()/md5() of PHP or let the RDBMS do the job if it provides MD5/SHA1 as functions. This way you are even not vulnerable to SQL injection coming from the password, but injection may come from the user name (you can hash it too ;) Regards, Andrey Hendy Irawan wrote: