@@ -47,6 +47,7 @@ PHPAPI zend_object_handlers spl_handler_SplObjectStorage;
47
47
/* Bit flags for marking internal functionality overridden by SplObjectStorage subclasses. */
48
48
#define SOS_OVERRIDDEN_READ_DIMENSION 1
49
49
#define SOS_OVERRIDDEN_WRITE_DIMENSION 2
50
+ #define SOS_OVERRIDDEN_UNSET_DIMENSION 4
50
51
51
52
typedef struct _spl_SplObjectStorage { /* {{{ */
52
53
HashTable storage ;
@@ -221,6 +222,9 @@ spl_SplObjectStorageElement *spl_object_storage_attach(spl_SplObjectStorage *int
221
222
222
223
static int spl_object_storage_detach (spl_SplObjectStorage * intern , zend_object * obj ) /* {{{ */
223
224
{
225
+ if (EXPECTED (!(intern -> flags & SOS_OVERRIDDEN_UNSET_DIMENSION ))) {
226
+ return zend_hash_index_del (& intern -> storage , obj -> handle );
227
+ }
224
228
int ret = FAILURE ;
225
229
zend_hash_key key ;
226
230
if (spl_object_storage_get_hash (& key , intern , obj ) == FAILURE ) {
@@ -284,6 +288,11 @@ static zend_object *spl_object_storage_new_ex(zend_class_entry *class_type, zend
284
288
SPL_OBJECT_STORAGE_CLASS_HAS_OVERRIDE (class_type , ZEND_STR_OFFSETSET )) {
285
289
intern -> flags |= SOS_OVERRIDDEN_WRITE_DIMENSION ;
286
290
}
291
+
292
+ if (intern -> fptr_get_hash != NULL ||
293
+ SPL_OBJECT_STORAGE_CLASS_HAS_OVERRIDE (class_type , ZEND_STR_OFFSETUNSET )) {
294
+ intern -> flags |= SOS_OVERRIDDEN_UNSET_DIMENSION ;
295
+ }
287
296
}
288
297
break ;
289
298
}
@@ -487,6 +496,16 @@ static void spl_object_storage_write_dimension(zend_object *object, zval *offset
487
496
spl_object_storage_attach_handle (intern , Z_OBJ_P (offset ), inf );
488
497
}
489
498
499
+ static void spl_object_storage_unset_dimension (zend_object * object , zval * offset )
500
+ {
501
+ spl_SplObjectStorage * intern = spl_object_storage_from_obj (object );
502
+ if (UNEXPECTED (Z_TYPE_P (offset ) != IS_OBJECT || (intern -> flags & SOS_OVERRIDDEN_UNSET_DIMENSION ))) {
503
+ zend_std_unset_dimension (object , offset );
504
+ return ;
505
+ }
506
+ zend_hash_index_del (& intern -> storage , Z_OBJ_HANDLE_P (offset ));
507
+ }
508
+
490
509
/* {{{ Detaches an object from the storage */
491
510
PHP_METHOD (SplObjectStorage , detach )
492
511
{
@@ -1330,6 +1349,7 @@ PHP_MINIT_FUNCTION(spl_observer)
1330
1349
spl_handler_SplObjectStorage .read_dimension = spl_object_storage_read_dimension ;
1331
1350
spl_handler_SplObjectStorage .write_dimension = spl_object_storage_write_dimension ;
1332
1351
spl_handler_SplObjectStorage .has_dimension = spl_object_storage_has_dimension ;
1352
+ spl_handler_SplObjectStorage .unset_dimension = spl_object_storage_unset_dimension ;
1333
1353
1334
1354
spl_ce_MultipleIterator = register_class_MultipleIterator (zend_ce_iterator );
1335
1355
spl_ce_MultipleIterator -> create_object = spl_SplObjectStorage_new ;
0 commit comments