@@ -399,20 +399,22 @@ static zend_object *spl_SplObjectStorage_new(zend_class_entry *class_type)
399
399
}
400
400
/* }}} */
401
401
402
+ /* Returns 1 if the SplObjectStorage contains an entry for getHash(obj), even if the corresponding value is null. */
402
403
int spl_object_storage_contains (spl_SplObjectStorage * intern , zend_object * obj ) /* {{{ */
403
404
{
405
+ if (EXPECTED (!intern -> fptr_get_hash )) {
406
+ return zend_hash_index_find (& intern -> storage , obj -> handle ) != NULL ;
407
+ }
404
408
int found ;
405
409
zend_hash_key key ;
406
410
if (spl_object_storage_get_hash (& key , intern , obj ) == FAILURE ) {
407
411
return 0 ;
408
412
}
409
413
410
- if (key .key ) {
411
- found = zend_hash_exists (& intern -> storage , key .key );
412
- } else {
413
- found = zend_hash_index_exists (& intern -> storage , key .h );
414
- }
415
- spl_object_storage_free_hash (intern , & key );
414
+ ZEND_ASSERT (key .key );
415
+ found = zend_hash_exists (& intern -> storage , key .key );
416
+ zend_string_release_ex (key .key , 0 );
417
+
416
418
return found ;
417
419
} /* }}} */
418
420
@@ -432,6 +434,25 @@ PHP_METHOD(SplObjectStorage, attach)
432
434
spl_object_storage_attach (intern , obj , inf );
433
435
} /* }}} */
434
436
437
+ static int spl_object_storage_has_dimension (zend_object * object , zval * offset , int check_empty )
438
+ {
439
+ spl_SplObjectStorage * intern = spl_object_storage_from_obj (object );
440
+ if (UNEXPECTED (offset == NULL || Z_TYPE_P (offset ) != IS_OBJECT || (intern -> flags & SOS_OVERRIDDEN_READ_DIMENSION ))) {
441
+ /* Can't optimize empty()/isset() check if getHash, offsetExists, or offsetGet is overridden */
442
+ return zend_std_has_dimension (object , offset , check_empty );
443
+ }
444
+ spl_SplObjectStorageElement * element = zend_hash_index_find_ptr (& intern -> storage , Z_OBJ_HANDLE_P (offset ));
445
+ if (!element ) {
446
+ return 0 ;
447
+ }
448
+
449
+ if (check_empty ) {
450
+ return i_zend_is_true (& element -> inf );
451
+ }
452
+ /* NOTE: SplObjectStorage->offsetExists() is an alias of SplObjectStorage->contains(), so this returns true even if the value is null. */
453
+ return 1 ;
454
+ }
455
+
435
456
static zval * spl_object_storage_read_dimension (zend_object * object , zval * offset , int type , zval * rv )
436
457
{
437
458
spl_SplObjectStorage * intern = spl_object_storage_from_obj (object );
@@ -1307,6 +1328,7 @@ PHP_MINIT_FUNCTION(spl_observer)
1307
1328
spl_handler_SplObjectStorage .free_obj = spl_SplObjectStorage_free_storage ;
1308
1329
spl_handler_SplObjectStorage .read_dimension = spl_object_storage_read_dimension ;
1309
1330
spl_handler_SplObjectStorage .write_dimension = spl_object_storage_write_dimension ;
1331
+ spl_handler_SplObjectStorage .has_dimension = spl_object_storage_has_dimension ;
1310
1332
1311
1333
spl_ce_MultipleIterator = register_class_MultipleIterator (zend_ce_iterator );
1312
1334
spl_ce_MultipleIterator -> create_object = spl_SplObjectStorage_new ;
0 commit comments