diff --git a/NEWS b/NEWS index 1634189bde10f..38d3bde8a746e 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,8 @@ PHP NEWS - Core: . Added first-class callable cache to share instances for the duration of the request. (ilutov) + . It is now possible to use reference assign on WeakMap without the key + needing to be present beforehand. (nielsdos) - Intl: . Added IntlNumberRangeFormatter class to format an interval of two numbers diff --git a/UPGRADING b/UPGRADING index 334c0fc6bdac3..ece101e83fd5d 100644 --- a/UPGRADING +++ b/UPGRADING @@ -23,6 +23,10 @@ PHP 8.6 UPGRADE NOTES 2. New Features ======================================== +- Core: + . It is now possible to use reference assign on WeakMap without the key + needing to be present beforehand. + - Intl: . Added IntlNumberRangeFormatter class to format an interval of two numbers with a given skeleton, locale, IntlNumberRangeFormatter::COLLAPSE_AUTO, IntlNumberRangeFormatter::COLLAPSE_NONE, IntlNumberRangeFormatter::COLLAPSE_UNIT, IntlNumberRangeFormatter::COLLAPSE_ALL collapse and IntlNumberRangeFormatter::IDENTITY_FALLBACK_SINGLE_VALUE, IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE, IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY and diff --git a/Zend/tests/weakrefs/weakmap_by_ref_dimension_assign.phpt b/Zend/tests/weakrefs/weakmap_by_ref_dimension_assign.phpt new file mode 100644 index 0000000000000..6444de7eea6ba --- /dev/null +++ b/Zend/tests/weakrefs/weakmap_by_ref_dimension_assign.phpt @@ -0,0 +1,13 @@ +--TEST-- +By-ref assign of WeakMap dimension +--FILE-- + +--EXPECT-- +int(1) diff --git a/Zend/zend_weakrefs.c b/Zend/zend_weakrefs.c index 4830089e50916..ffb93951f7f23 100644 --- a/Zend/zend_weakrefs.c +++ b/Zend/zend_weakrefs.c @@ -370,18 +370,25 @@ static zval *zend_weakmap_read_dimension(zend_object *object, zval *offset, int zend_weakmap *wm = zend_weakmap_from(object); zend_object *obj_addr = Z_OBJ_P(offset); zval *zv = zend_hash_index_find(&wm->ht, zend_object_to_weakref_key(obj_addr)); - if (zv == NULL) { - if (type != BP_VAR_IS) { - zend_throw_error(NULL, - "Object %s#%d not contained in WeakMap", ZSTR_VAL(obj_addr->ce->name), obj_addr->handle); + if (type == BP_VAR_W || type == BP_VAR_RW) { + if (zv == NULL) { + zval value; + zend_weakref_register(obj_addr, ZEND_WEAKREF_ENCODE(&wm->ht, ZEND_WEAKREF_TAG_MAP)); + ZVAL_NULL(&value); + zv = zend_hash_index_add_new(&wm->ht, zend_object_to_weakref_key(obj_addr), &value); + } + ZVAL_MAKE_REF(zv); + } else { + if (zv == NULL) { + if (type != BP_VAR_IS) { + zend_throw_error(NULL, + "Object %s#%d not contained in WeakMap", ZSTR_VAL(obj_addr->ce->name), obj_addr->handle); + return NULL; + } return NULL; } - return NULL; } - if (type == BP_VAR_W || type == BP_VAR_RW) { - ZVAL_MAKE_REF(zv); - } return zv; }