One of the contributors for the "Because, PHP" page came up with a fun
example where the result of object comparison changes upon observation
of that object.

class A { public $a; }
class B extends A { public $b; }
$a = new B(); $a->a = 0; $a->b = 1;
$b = new B(); $b->a = 1; $b->b = 0;

var_dump($a < $b); // bool(true)
print_r($a); // Output is unimportant
var_dump($a < $b); // bool(false)

Tracked this down to the introduction of slotted object properties
introduced in PHP 5.4 and some optimistic logic contained in
zend_object_handlers.c.

TL;DR - The print_r is materializing the ->properties HashTable in the
first object.  Once that happens, zend_std_compare_objects() flips
from walking the slotted properties in properties_table to
materializing both ->propoperties HashTables and using a symtable
compare.  The result differs, because rebuild_object_properties walks
->properties_info which may not necessarily be in the same order as
the values ->properties_table.

See also my writeup here: https://3v4l.org/NLZNm

So the questions for us are:

1. Does this matter? (I think so, it's spooky action at a distance)
2. Is it a bug introduced in 5.4 that's okay to fix? Or would fixing
it count as a BC break due to how long it's been broken? (I say
fixable bug, the BC break was at 5.4)
3. If yes to 1&2, how far back do we fix it? Bugfix branches (7.1+)?
Or would a change like this in branch be too much? Surely at least 7.3
could be fixed.

-Sara

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to