SO,
The problem
It\'s not well-known, but PHP allows to compare objects - and not just on equality ==
- but on <
PHP compares sequentially (in the order of declaration) the object properties and stops at the first inequal property found. This behavior is not documented, so there's not much to be said about it, sadly, other than looking at the source of PHP.
Not documented is usually a synonym of "don't rely on it".
Each class in php has an associated structure (in the c code) of handler functions, it looks like
struct _zend_object_handlers {
/* general object functions */
zend_object_add_ref_t add_ref;
zend_object_del_ref_t del_ref;
[...]
zend_object_compare_t compare_objects;
[...]
};
compare_objects
points to a function that "takes two objects" and returns -1,0,1 according to whatever this comparator defines as the order (just like strcmp() does for strings).
This function is used only when both operands (objects) point to the same comparision function - but let's just stick with this case.
That's where e.g. DateTime
"adds" its feature to compare two DateTime instances, it just defines another, DateTime-specific compare_objects
function and puts it in the structure describing its class.
static void date_register_classes(TSRMLS_D)
{
[...]
INIT_CLASS_ENTRY(ce_date, "DateTime", date_funcs_date);
ce_date.create_object = date_object_new_date;
[...]
date_object_handlers_date.compare_objects = date_object_compare_date;
So if you want to know (exactly) how two DateTime instances are compared, take a look at date_object_compare_date.
The comparision described in the manual (at least for the case cmp(o1,o2)==0) seems to be implemented in zend_std_compare_objects. And it's used by both StdClass and a simple user defined class like e.g.
<?php
class Foo { }
$a = new StdClass;
$b = new Foo;
$a > $b;
But other classes (in php extensions) do set other functions. DateTime, ArrayObject, PDOStatement, even Closures use different functions.
But I haven't found a way to define a comparision function/method in script code (but haven't looked too hard/long)
The exact behavior is defined in the PHP language specification, thus, you can rely on it.
[…] if the objects are of different types, the comparison result is FALSE. If the objects are of the same type, the properties of the objects are compares [sic] using the array comparison described above.
And the array comparison is defined as follows:
[…] For arrays having the same numbers of elements, the keys from the left operand are considered one by one, if the next key in the left-hand operand exists in the right-hand operand, the corresponding values are compared. If they are unequal, the array containing the lesser value is considered less-than the other one, and the comparison ends; otherwise, the process is repeated with the next element. […] If all the values are equal, then the arrays are considered equal.
Simply exchange every mention of array with object and key with property in your mind and you have the exact description of how this works. I omitted useless array specifics in above quote.