-
Notifications
You must be signed in to change notification settings - Fork 7.8k
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
Add load_mangled_object_vars(), the inverse of get_mangled_object_vars() #9408
base: master
Are you sure you want to change the base?
Conversation
35df47e
to
ac5c0c2
Compare
load_mangled_object_vars($ro, []); | ||
var_dump($ro); | ||
|
||
load_mangled_object_vars($ro, ['ro' => 'abc']); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just here to prove that the implementation is incomplete for now, see PR description.
#9354 is related here. |
I think that needs to be discussed on the internals mailing list. |
// ext/reflection/php_reflection.c
/* {{{ _reflection_write_property */
static zval *_reflection_write_property(zend_object *object, zend_string *name, zval *value, void **cache_slot)
{
if (zend_hash_exists(&object->ce->properties_info, name)
&& (zend_string_equals_literal(name, "name") || zend_string_equals_literal(name, "class")))
{
zend_throw_exception_ex(reflection_exception_ptr, 0,
"Cannot set read-only property %s::$%s", ZSTR_VAL(object->ce->name), ZSTR_VAL(name));
return &EG(uninitialized_zval);
}
else
{
return zend_std_write_property(object, name, value, cache_slot);
}
}
/* }}} */
Agreed |
The function I'm looking for would do the following: function load_mangled_object_vars(object $object, array $vars): void
{
foreach ($vars as $name => $value) {
try {
if ('' === $name || "\0" !== $name[0]) {
$reflector = new ReflectionProperty($object, $name);
} else {
$i = strrpos($name, "\0");
$reflector = new ReflectionProperty(substr($name, 1, $i - 1), substr($name, $i + 1));
}
} catch (ReflectionException) {
$object->$name = $value;
continue;
}
$reflector->setValue($object, $value);
}
} Of course, it would do so much more efficiently, and it would also preserve references found in I realize that Here first maybe, then on internals? |
Being able to hydrate an object from its "mangled vars" is a quite common operation in eg ORMs.
Doing so right now requires writing complex and slow logic that involve many calls to reflection and/or rebound closures.
I propose to remove this overhead by adding
load_mangled_object_vars()
, which can be understood as the inverse ofget_mangled_object_vars()
.Internally, the implementation just calls
object_properties_load()
for now, which means it's missing checks for property types. I'm wondering if these checks should be added toobject_properties_load()
or toload_mangled_object_vars()
?