Bug->Doc #70418 [Ver]: SplObjectStorage not replacing objects when hash matches
| From: | cmb@php.net | Date: | Mon, 18 Oct 2021 16:14:54 +0000 |
| Subject: | Bug->Doc #70418 [Ver]: SplObjectStorage not replacing objects when hash matches | ||
| References: | 1 | Groups: | php.doc.bugs |
| Request: | Send a blank email to doc-bugs+get-19272@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=70418&edit=1
ID: 70418
Updated by: cmb@php.net
Reported by: richardh at channelgrabber dot com
Summary: SplObjectStorage not replacing objects when hash
matches
Status: Verified
-Type: Bug
+Type: Documentation Problem
Package: SPL related
PHP Version: 5.5.28
Block user comment: N
Private report: N
New Comment:
> Of course, that works fine with the default hashes...
And given that it behaves like that since "forever", I suggest to
document that ::getHash()[1] is supposed to return unique hashes,
and to clarify
| The storage object will never contain more than one object with
| the same identifier.
in case of hash collissions.
[1] <https://www.php.net/manual/en/splobjectstorage.gethash.php>
Previous Comments:
------------------------------------------------------------------------
[2015-09-03 17:22:20] cmb@php.net
Actually, that behavior[1] is part of the ability to store
additional info with the object. The idea is obviously that it
should be possible to change the info only, but leave the object
as is, by calling ::attach() again with the same object. Of
course, that works fine with the default hashes...
[1] <https://github.com/php/php-src/blob/php-5.6.12/ext/spl/spl_observer.c#L220-L225>
------------------------------------------------------------------------
[2015-09-03 15:11:15] cmb@php.net
Confirmed: <https://3v4l.org/i1v7q>
------------------------------------------------------------------------
[2015-09-03 11:32:31] richardh at channelgrabber dot com
Description:
------------
If you change how the SplObjectStorage calculates an objects hash, and then attach an object which
will create the same hash as a currently stored object, SplObjectStorage will silently drop the new
object rather than replacing the current object at that hash with the new one. This means that if
the object differs from the stored object, those changes are also dropped which can result in
unexpected behaviour when iterating over the stored objects.
This conflict with how arrays work when reassigning a value for the same index.
Test script:
---------------
class IdObjectStorage extends SplObjectStorage {
public function getHash($object) { return (string) $object->id; }
}
$storage = new IdObjectStorage(); $array = [];
$object1 = new stdClass(); $object1->id = 1; $object1->value = 'Object #1';
$storage->attach($object1);
$array[$object1->id] = $object1;
foreach($storage as $x) var_dump($x->value); // Object #1
foreach($array as $x) var_dump($x->value); // Object #1
$object2 = new stdClass(); $object2->id = 1; $object2->value = 'Object #2';
$array[$object2->id] = $object2;
$storage->attach($object2);
foreach($storage as $x) var_dump($x->value); // Object #1
foreach($array as $x) var_dump($x->value); // Object #2
Expected result:
----------------
SplObjectStorage should work the same as arrays, in that when an object is attached with the same
hash as a current entry, that entry is replaced with the new object.
string(9) "Object #1"
string(9) "Object #1"
string(9) "Object #2"
string(9) "Object #2"
Actual result:
--------------
SplObjectStorage silently drops the new object as it already has an object for that hash.
string(9) "Object #1"
string(9) "Object #1"
string(9) "Object #1"
string(9) "Object #2"
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=70418&edit=1