-
Notifications
You must be signed in to change notification settings - Fork 7.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Casting an object to array does not unwrap refcount=1 references #8655
Comments
The difference is that previously this code was routed through zend_array_dup(), duplicating the properties hashtable, with respect to RC=1 references prior to PHP 8.1. |
FWIW, introduced by commit 9da66e6. |
/cc @dstogov maybe then? |
I'm not sure which behaviour is right. Reference in PHP may automatically turn into regular zval when their reference-counter is decremented to 1, but the point where this conversion occurs is not defined (and cannot be defined). Relaying on reference/non-reference type is a bad idea. In case It's possible to fix this case with the following patch diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c
index 746897f641..43b54f915c 100644
--- a/Zend/zend_object_handlers.c
+++ b/Zend/zend_object_handlers.c
@@ -111,6 +111,9 @@ ZEND_API HashTable *zend_std_build_object_properties_array(zend_object *zobj) /*
continue;
}
+ if (Z_ISREF_P(prop) && Z_REFCOUNT_P(prop) == 1) {
+ prop = Z_REFVAL_P(prop);
+ }
Z_TRY_ADDREF_P(prop);
_zend_hash_append(ht, prop_info->name, prop);
} |
Thanks for the patch! I submitted it as #8737 with a test case. |
I wouldn't say this is a bug. I would say |
Here is the bug in action without using ReflectionReference: class Foo
{
public $foo;
}
function hydrate($properties, $object)
{
foreach ($properties as $name => &$value) {
$object->$name = &$value;
}
};
$object = new Foo;
hydrate(['foo' => 123], $object);
$cast = (array) $object;
$object->foo = 234;
echo $cast['foo']; |
OK. Agree :) |
Description
The following code produces the expected output on PHP < 8.1, but breaks on PHP >=8.1 see https://3v4l.org/L9WpO
Resulted in this output:
But I expected this output instead:
PHP Version
8.1
Operating System
No response
The text was updated successfully, but these errors were encountered: