diff --git a/NEWS b/NEWS index 490f506629cad..4a4c605a9d847 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,7 @@ PHP NEWS . Fixed zend call stack size for macOs/arm64. (David Carlier) . Added support for Zend Max Execution Timers on FreeBSD. (Kévin Dunglas) . Ensure fiber stack is not backed by THP. (crrodriguez) + . Implement GH-13609 (Dump wrapped object in WeakReference class). (nielsdos) - Curl: . Deprecated the CURLOPT_BINARYTRANSFER constant. (divinity76) diff --git a/UPGRADING b/UPGRADING index aacd95838115d..62aba12cb9775 100644 --- a/UPGRADING +++ b/UPGRADING @@ -164,6 +164,8 @@ PHP 8.4 UPGRADE NOTES . Added request_parse_body() function that allows parsing RFC1867 (multipart) requests in non-POST HTTP requests. RFC: https://wiki.php.net/rfc/rfc1867-non-post + . Getting the debug info for WeakReference will now also output the object + it references, or null if the reference is no longer valid. - Curl: . curl_version() returns an additional feature_list value, which is an diff --git a/Zend/tests/weakrefs/weakrefs_001.phpt b/Zend/tests/weakrefs/weakrefs_001.phpt index 8db0fb2d80989..b5d2f6cc8678c 100644 --- a/Zend/tests/weakrefs/weakrefs_001.phpt +++ b/Zend/tests/weakrefs/weakrefs_001.phpt @@ -26,9 +26,15 @@ object(stdClass)#1 (0) refcount(2){ } object(stdClass)#1 (0) refcount(2){ } -object(WeakReference)#2 (0) { +object(WeakReference)#2 (1) { + ["object"]=> + object(stdClass)#1 (0) { + } } -object(WeakReference)#2 (0) { +object(WeakReference)#2 (1) { + ["object"]=> + object(stdClass)#1 (0) { + } } object(stdClass)#1 (0) refcount(2){ } @@ -36,4 +42,3 @@ object(stdClass)#1 (0) refcount(2){ } NULL NULL - diff --git a/Zend/tests/weakrefs/weakrefs_debug_dump.phpt b/Zend/tests/weakrefs/weakrefs_debug_dump.phpt new file mode 100644 index 0000000000000..719ca3af71961 --- /dev/null +++ b/Zend/tests/weakrefs/weakrefs_debug_dump.phpt @@ -0,0 +1,26 @@ +--TEST-- +Weakrefs debug dump +--FILE-- +hello = 'world'; + +$weak = WeakReference::create($s); +var_dump($weak); +unset($s); +var_dump($weak); + +?> +--EXPECT-- +object(WeakReference)#2 (1) { + ["object"]=> + object(stdClass)#1 (1) { + ["hello"]=> + string(5) "world" + } +} +object(WeakReference)#2 (1) { + ["object"]=> + NULL +} diff --git a/Zend/zend_weakrefs.c b/Zend/zend_weakrefs.c index 7a9bf14cb1543..0a7dac5321309 100644 --- a/Zend/zend_weakrefs.c +++ b/Zend/zend_weakrefs.c @@ -271,6 +271,25 @@ static void zend_weakref_free(zend_object *zo) { zend_object_std_dtor(&wr->std); } +static HashTable *zend_weakref_get_debug_info(zend_object *object, int *is_temp) +{ + *is_temp = 1; + + HashTable *ht = zend_new_array(1); + + zend_object *referent = zend_weakref_from(object)->referent; + zval value; + if (referent) { + ZVAL_OBJ_COPY(&value, referent); + } else { + ZVAL_NULL(&value); + } + + zend_hash_update(ht, ZSTR_KNOWN(ZEND_STR_OBJECT), &value); + + return ht; +} + ZEND_COLD ZEND_METHOD(WeakReference, __construct) { zend_throw_error(NULL, "Direct instantiation of WeakReference is not allowed, use WeakReference::create instead"); @@ -749,6 +768,7 @@ void zend_register_weakref_ce(void) /* {{{ */ zend_weakref_handlers.offset = XtOffsetOf(zend_weakref, std); zend_weakref_handlers.free_obj = zend_weakref_free; + zend_weakref_handlers.get_debug_info = zend_weakref_get_debug_info; zend_weakref_handlers.clone_obj = NULL; zend_ce_weakmap = register_class_WeakMap(zend_ce_arrayaccess, zend_ce_countable, zend_ce_aggregate);