Req #43304 [Com]: Casting During Comparison

From: Date: Fri, 09 Jan 2015 00:58:08 +0000
Subject: Req #43304 [Com]: Casting During Comparison
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-189810@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=43304&edit=1

 ID:                 43304
 Comment by:         ajf@php.net
 Reported by:        ken at smallboxsoftware dot net
 Summary:            Casting During Comparison
 Status:             Open
 Type:               Feature/Change Request
 Package:            Feature/Change Request
 Operating System:   ALL
 PHP Version:        5.2.5
 Block user comment: N
 Private report:     N

 New Comment:

By the way: the behaviour kissifrot mentions was actually fixed a while ago. I'm not sure in
which version, I think it was 5.4 or 5.5.


Previous Comments:
------------------------------------------------------------------------
[2012-01-16 16:49:56] michael dot kluge at wundermedia dot de

Well, this is what we do.
But this is in my opinion nothing but a workaround for that.

I would regard the current behaviour as a bug or, sadly, rather as an example of bad design in any
language. It's just not logical.

Javascript e.g. implements this correctly (from Firebug; Mozilla JS-implementation):
>>> var x1='001',x2='01';
undefined
>>> x1==x2
false
>>> x1===x2
false
>>> x2=1
1
>>> x1==x2
true
>>> x1===x2
false

Therefore I added my last comment to (re-)start a discussion on that, hoping that this might be
changed or at least be made configurable. 
At least this request is marked as "Feature/Change Request". ;-)

My idea is to change this:
- Drop the concept of "numerical strings"
- Equal types do never convert on any comparison

First this should be made configurable (default is to stop the weird behaviour), to give grace time
to the developers to adapt their scripts
In later versions this should be removed completely.
Maybe a similiar way the magic-quotes-crap is going...

Maybe one more thing about the docs:
It states:
"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."
This also constricts the simple declarations of the operators in the case of both operands being
"numerical strings".
This is exactly the behaviour being very bad in my eyes, and should be changed for creating
unexpected results in certain circumstances.
I see no valid reason for the operators to change behaviour if both operands are of the same type.
(Except maybe lazy devs not willing to obey types) ;-)

Maybe I've overseen something... Does anybody know of any good reason why the actual behaviour
might be regarded better than the one proposed by others and me?

------------------------------------------------------------------------
[2012-01-16 15:53:25] delphists at apollo dot lv

From docs:
[quote]
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.
[/quote]

Want to be strict, when comparing? Then use strict operators...

------------------------------------------------------------------------
[2012-01-16 14:29:07] michael dot kluge at wundermedia dot de

No comments from any PHP devs yet?

Well I strongly disagree with the current implementation.

From PHP-Docs:
$a === $b Identical TRUE if $a is equal to $b, and they are of the same type.

This is the correct definition of the === operator.
An so it should work like that definition:

So
$a = "001234";
$b = "1234";
$a == $b should be equal to $a === $b (both should be false)
as both variables hold the same type
and from the above definition
those expressions should be equal:
$a === $b
($a == $b && typeof($a)==typeof($b))

So if (typeof($a)==typeof($b)) is true, $a===$b should be identical to $a==$b.

If comparing two variables of the same type in NO case any type-conversion should be applied!

If you need conversions in those cases these should be explicitly noted as e.g.:
intval($a) == intval($b)

Adding special exceptions to the general definition doesn't make much sense in my eyes; it just
makes the base definition wrong in certain circumstances and leads to unexpected behaviour in
certain cases (see comment from kissifrot).

We stumbled upon this when comparing certain product ids in use by one of our customers, just being
different in the leading zeros. (So id "001" is another product than "01" ==>
therefore using strings; please don't ask why, as I don't know what reasons might have
caused these strange ids)

delphists said that "there are also lots of cases when numerical strings have to be compared as
integers". I agree with that, but in those cases the developer should convert the types
manually.
Also the example with the database should, in my opinion, be implemented differently:
The model should return integers for integer-typed database fields and not strings.
On the other hand if you expect input parameters containing integer values these could also be
converted to integers, which can be easily done in the validity checks of the parameters.

IMHO, despite of PHP trying to make type-conversions transparent to the developer, the developer
should in any case keep in mind, that PHP is not typeless and respect the types accordingly. And
"0123" and "123" are definitely NOT logically equal in any case! I think the
weird concept of "numerical strings" should be dropped.

------------------------------------------------------------------------
[2011-03-11 09:43:13] delphists at apollo dot lv

Sorry for digging up this bug report, but it's still opened, so I don't think that digging
it up should be a problem.

I agree with kissifrot about specific case - both values convert to "(int)2147483647", at
least on 32bit system, which is nowhere near to "00001000010000000198358".

Though, I can't agree with drm. There is a reason for having two types of comparisons - if you
are sure that you don't need values to be converted, just use strict comparison.

I agree that there are cases when numerical strings need to be compared as strings, but there are
also lots of cases when numerical strings have to be compared as integers. For example, some
functions that return data from DB, return integers as strings, which may be compared to data from
browser, which by default is also string, but comparison needs to work like if they were numbers.

------------------------------------------------------------------------
[2011-02-17 08:58:37] kissifrot at gmail dot com

I agree with that, for example if I have
$ric1 = '00001000010000000198358';
$ric2 = '00001000010000000198455';
var_dump($ric1 == $ric2)

should return false, not true, just because it's logical.
But the current behavior makes PHP somewhat unreliable :(

------------------------------------------------------------------------


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    https://bugs.php.net/bug.php?id=43304


--
Edit this bug report at https://bugs.php.net/bug.php?id=43304&edit=1


Thread (9 messages)

« previous php.bugs (#189810) next »