# Object comparison

- Thread: https://externals.io/message/63785
- Original archive: https://news-web.php.net/php.internals/63785
- Started by Sara Golemon on 2012-11-09T00:07:24+00:00
- Messages: 9
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #63785 — Sara Golemon — 2012-11-09T00:07:24+00:00

URL: https://externals.io/message/63785#63785

From: http://php.net/manual/en/language.operators.comparison.php

An object compared to anything which is not a bool, null, or object
should result in the object appearing to be greater than the other
operand.  For example:

$a = new stdClass();
$b = new stdClass();

var_dump(null < $a);
var_dump(false < $a);
var_dump(true == $a);
var_dump($a == $b);
var_dump(0 < $a);
var_dump(1 < $a); // false
var_dump(2 < $a); // false
var_dump("foo" < $a);
var_dump("2" < $a);
var_dump(tmpfile() < $a);

Based on docs, I expect all nine of these to yield true, however in
practice, the two marked "false" come out as false because the RHS
object is converted to an integer (1), contrary to the docs.

Doc bug? Or code bug?  I'm inclined to call it a code bug, but wanted
others' thoughts.

-Sara

---

## #63786 — Stas Malyshev — 2012-11-09T00:47:32+00:00

URL: https://externals.io/message/63785#63786 · In reply to: #63785

Hi!

> Doc bug? Or code bug?  I'm inclined to call it a code bug, but wanted
> others' thoughts.

I would say comparing object to a number makes little sense, so no
reason to define any specific result there. It may be true, false or
bologna sandwich.
The docs say what happens when the first parameter is object, but say
nothing what happens if the second one is object. This is for reason -
if you compare object to array, they can't both be greater, something
has to take priority. The docs say first arg takes priority. So by docs,
comparison of (number, object) has no defined value, while comparison of
(object, number) has.
-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

---

## #63789 — Sherif Ramadan — 2012-11-09T03:51:38+00:00

URL: https://externals.io/message/63785#63789 · In reply to: #63785

> From: http://php.net/manual/en/language.operators.comparison.php
>
> An object compared to anything which is not a bool, null, or object
> should result in the object appearing to be greater than the other
> operand.  For example:
>
> $a = new stdClass();
> $b = new stdClass();
>
> var_dump(null < $a);
> var_dump(false < $a);
> var_dump(true == $a);
> var_dump($a == $b);
> var_dump(0 < $a);
> var_dump(1 < $a); // false
> var_dump(2 < $a); // false
> var_dump("foo" < $a);
> var_dump("2" < $a);
> var_dump(tmpfile() < $a);
>
> Based on docs, I expect all nine of these to yield true, however in
> practice, the two marked "false" come out as false because the RHS
> object is converted to an integer (1), contrary to the docs.
>
> Doc bug? Or code bug?  I'm inclined to call it a code bug, but wanted
> others' thoughts.
>


Hi Sara,

I believe the documentation is failing us here.

From what I see the docs are pretty lacking in what should be expected
in terms of object comparison.

For example, the page at http://php.net/types.comparisons doesn't even
include objects in the comparison table.

Of course by looking at the "Comparison with Various Types" table at
http://php.net/language.operators.comparison one gets the impression
that the "Operand 1" and "Operand 2" columns are to signify LVALUE and
RVALUE operands, respectively. Obviously this isn't the case and the
documentation just fails us here.

var_dump(new stdclass < 1, newstdcalss > 1, 1 < new stdclass, 1 > new
stdclass); // false, false, false, false

Clearly there are cases when the object can be neither less-than nor
greater-than an operand in a comparison.

The statement "object is always greater" in that table is misleading
and doesn't tell us the whole truth.

For example,
class foo { public function __toString() { return ''; } }
var_dump(new foo < '', new foo > '', '' < new foo, '' > new foo); //
false, false, false, false

Obviously there are more complex cases where the object may not pan
out to be greater than a non-object type that the documentation fails
to address.

> -Sara

---

## #63791 — crankypuss — 2012-11-09T09:50:51+00:00

URL: https://externals.io/message/63785#63791 · In reply to: #63785

> From: http://php.net/manual/en/language.operators.comparison.php
>
> An object compared to anything which is not a bool, null, or object
> should result in the object appearing to be greater than the other
> operand.  For example:
>
> $a = new stdClass();
> $b = new stdClass();
>
> var_dump(null < $a);
> var_dump(false < $a);
> var_dump(true == $a);
> var_dump($a == $b);
> var_dump(0 < $a);
> var_dump(1 < $a); // false
> var_dump(2 < $a); // false
> var_dump("foo" < $a);
> var_dump("2" < $a);
> var_dump(tmpfile() < $a);
>
> Based on docs, I expect all nine of these to yield true, however in
> practice, the two marked "false" come out as false because the RHS
> object is converted to an integer (1), contrary to the docs.
>
> Doc bug? Or code bug?  I'm inclined to call it a code bug, but wanted
> others' thoughts.
>
> -Sara
>

You seem to be reporting a bug ("contrary to the docs"), but you might 
be suggesting that the doc be corrected (since doc and behaviour should 
always match).

I would suggest being very careful about implementing something as 
central as a change to how comparisons are made, that ought to be 
approached with great caution because it has the potential for breaking 
a huge amount of existing code.

[It does occur to me however, simply as a point of interest, that 
objects traditionally have both a constructor and a destructor, and the 
idea of objects also having a comparator makes a certain amount of 
sense; a default object comparator might implement the currently defined 
comparisons while allowing derived classes to override the default 
behaviour and leaving comparisons not involving objects undisturbed.]

Comparing objects to scalars is really an apples/oranges comparision to 
begin with.

---

## #63793 — Christian Stoller — 2012-11-09T13:18:04+00:00

URL: https://externals.io/message/63785#63793 · In reply to: #63785

I would like to place a suggestion for comparing objects (I hope it is no problem, because this does not have anything to do with Sara's question - but it came to my mind when I read her mail). It would be a great feature if objects could be compared to other objects with ">", "<" and the other operators, like it is suggested in RFC https://wiki.php.net/rfc/comparable
The DateTime class offers this feature - it would be nice if this could be made usable for userland classes/objects, too.

Best regards

Christian Stoller


-----Original Message-----
From: php@golemon.com [mailto:php@golemon.com] On Behalf Of Sara Golemon
Sent: Friday, November 09, 2012 1:07 AM
To: PHP internals
Subject: [PHP-DEV] Object comparison

From: http://php.net/manual/en/language.operators.comparison.php

An object compared to anything which is not a bool, null, or object
should result in the object appearing to be greater than the other
operand.  For example:

$a = new stdClass();
$b = new stdClass();

var_dump(null < $a);
var_dump(false < $a);
var_dump(true == $a);
var_dump($a == $b);
var_dump(0 < $a);
var_dump(1 < $a); // false
var_dump(2 < $a); // false
var_dump("foo" < $a);
var_dump("2" < $a);
var_dump(tmpfile() < $a);

Based on docs, I expect all nine of these to yield true, however in
practice, the two marked "false" come out as false because the RHS
object is converted to an integer (1), contrary to the docs.

Doc bug? Or code bug?  I'm inclined to call it a code bug, but wanted
others' thoughts.

-Sara

---

## #63794 — Sebastian Krebs — 2012-11-09T13:27:36+00:00

URL: https://externals.io/message/63785#63794 · In reply to: #63793

Hi,

Maybe it goes way to far, but there is a PECL-extension [1], that allows to
overload every(?) operator. However, it seems to be unmaintained for 6
years now and will probably not work anymore, but it may be usable as a
starting point. Python provides this too [2]

Regards,
Sebastian


[1] http://pecl.php.net/package/operator
[2] http://docs.python.org/2/reference/datamodel.html#special-method-names


2012/11/9 Christian Stoller <stoller@leonex.de>

> I would like to place a suggestion for comparing objects (I hope it is no
> problem, because this does not have anything to do with Sara's question -
> but it came to my mind when I read her mail). It would be a great feature
> if objects could be compared to other objects with ">", "<" and the other
> operators, like it is suggested in RFC https://wiki.php.net/rfc/comparable
> The DateTime class offers this feature - it would be nice if this could be
> made usable for userland classes/objects, too.
>
> Best regards
>
> Christian Stoller
>
>
> -----Original Message-----
> From: php@golemon.com [mailto:php@golemon.com] On Behalf Of Sara Golemon
> Sent: Friday, November 09, 2012 1:07 AM
> To: PHP internals
> Subject: [PHP-DEV] Object comparison
>
> From: http://php.net/manual/en/language.operators.comparison.php
>
> An object compared to anything which is not a bool, null, or object
> should result in the object appearing to be greater than the other
> operand.  For example:
>
> $a = new stdClass();
> $b = new stdClass();
>
> var_dump(null < $a);
> var_dump(false < $a);
> var_dump(true == $a);
> var_dump($a == $b);
> var_dump(0 < $a);
> var_dump(1 < $a); // false
> var_dump(2 < $a); // false
> var_dump("foo" < $a);
> var_dump("2" < $a);
> var_dump(tmpfile() < $a);
>
> Based on docs, I expect all nine of these to yield true, however in
> practice, the two marked "false" come out as false because the RHS
> object is converted to an integer (1), contrary to the docs.
>
> Doc bug? Or code bug?  I'm inclined to call it a code bug, but wanted
> others' thoughts.
>
> -Sara
>
> --
> 
> 
>
>
>
>


-- 
github.com/KingCrunch

---

## #63795 — Pierre Joye — 2012-11-09T13:52:39+00:00

URL: https://externals.io/message/63785#63795 · In reply to: #63785

hi!


> From: http://php.net/manual/en/language.operators.comparison.php
>
> An object compared to anything which is not a bool, null, or object
> should result in the object appearing to be greater than the other
> operand.  For example:
>
> $a = new stdClass();
> $b = new stdClass();
>
> var_dump(null < $a);
> var_dump(false < $a);
> var_dump(true == $a);
> var_dump($a == $b);
> var_dump(0 < $a);
> var_dump(1 < $a); // false
> var_dump(2 < $a); // false
> var_dump("foo" < $a);
> var_dump("2" < $a);
> var_dump(tmpfile() < $a);
>
> Based on docs, I expect all nine of these to yield true, however in
> practice, the two marked "false" come out as false because the RHS
> object is converted to an integer (1), contrary to the docs.
>
> Doc bug? Or code bug?  I'm inclined to call it a code bug, but wanted
> others' thoughts.

As stated by other before, comparing scalars and objects sound wrong
in the 1st place. But I have seen way too many weird codes relying on
weird things :). That's why I would not be in favor of changing
anything in this area as some code out there may rely on that (have
the feeling that object comparison has been like that since 5.0).

Cheers,
--
Pierre

@pierrejoye | http://blog.thepimp.net | http://www.libgd.org

---

## #63796 — jpauli — 2012-11-09T21:00:54+00:00

URL: https://externals.io/message/63785#63796 · In reply to: #63793

> I would like to place a suggestion for comparing objects (I hope it is no problem, because this does not have anything to do with Sara's question - but it came to my mind when I read her mail). It would be a great feature if objects could be compared to other objects with ">", "<" and the other operators, like it is suggested in RFC https://wiki.php.net/rfc/comparable
> The DateTime class offers this feature - it would be nice if this could be made usable for userland classes/objects, too.


I really like that idea, and the patch looks pretty good and looks
backward compatible.
I'm +1 with it

I'm also +1 with patching the doc to describe the full default compare behavior.

Julien.Pauli

---

## #63797 — Nathan Nobbe — 2012-11-10T03:46:37+00:00

URL: https://externals.io/message/63785#63797 · In reply to: #63796

> On Fri, Nov 9, 2012 at 2:18 PM, Christian Stoller <stoller@leonex.de>
> wrote:
> > […]
> no problem, because this does not have anything to do with Sara's question
> - but it came to my mind when I read her mail). It would be a great feature
> if objects could be compared to other objects with ">", "<" and the other
> operators, like it is suggested in RFC https://wiki.php.net/rfc/comparable
> > […]
> be made usable for userland classes/objects, too.
>
>
> I really like that idea, and the patch looks pretty good and looks
> backward compatible.
> I'm +1 with it
>
> I'm also +1 with patching the doc to describe the full default compare
> behavior.
>

Another spot in the docs I would enjoy discussion about <,>,>=,<= comparing
two objects:

http://php.net/manual/en/language.oop5.object-comparison.php

I notice this behavior is suggested in a comment for use in an
array_uintersect callback:

http://php.tonnikala.org/manual/el/function.array-uintersect.php#72841

Indeed, trying to intersect two arrays of objects with a user callback
'works' with the > comparison operator, but maybe this is just luck, or
subject to BC break later?

<?php
class myclass { function __construct($name) { $this->name = $name; } }

$o1 = new myclass('o1');
$o2 = new myclass('o2');
$o3 = new myclass('o3');
$o4 = new myclass('o4');

$a1 = array($o1, $o2, $o3);
$a2 = array($o3, $o2, $o4);

var_dump(array_uintersect($a1, $a2, function($v1, $v2) {
    if($v1 === $v2)
        return 0;
    if($v1 > $v2)
        return 1;
    return -1;
}));

I'd expect the > comparison there to be roughly equivalent
to if(spl_object_hash($v1) > spl_object_hash($v2)), no?  Info on the
default behavior here would be nice.


-nathan
