-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[PropertyAccess] Fix checking for missing properties #54194
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
Conversation
Is there a way to test this? |
I think I did add tests, do you have something more in mind? |
Something must have blinded me 👀 Sorry! |
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.
Is the __exists()
your next RFC?
I don't think so :) |
I tested this fix but it doesn't work for me I use PhpDocExtractor to be able to denormalize objects with properties like this:
However I still get the same error when I serialize this kind objects :
User Notice: Undefined property: Proxies_CG_\App\Entity\IndicatorType::$lazyObjectState in /home/.../src/Serializer/PropertyAccessor.php on line 419 |
@alexandre-le-borgne Can you please open a new issue and provide a small example application that allows to reproduce your issue? |
@@ -411,8 +411,18 @@ private function readProperty(array $zval, string $property, bool $ignoreInvalid | ||
throw $e; | ||
} | ||
} elseif (PropertyReadInfo::TYPE_PROPERTY === $type) { | ||
if ($access->canBeReference() && !isset($object->$name) && !\array_key_exists($name, (array) $object) && !(new \ReflectionProperty($class, $name))->hasType()) { |
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.
Is there a reason why the $access->canBeReference()
check has been dropped here ?
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.
yes: that check was just wrong - __get
can return by reference, so this was an unrelated check
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.
Thanks for the information.
This change broke my tests. They work with 6.4.4 and not with 6.4.6. I use magic getters in one of my entities like so: public function __get(string $arg)
{
if (preg_match('/custom_checkbox_(\d+)_entry(_other)?/', $arg, $matches)) {
if (isset($matches[2])) {
return $this->getCustomCheckboxEntryOther((int) $matches[1]);
}
return $this->getCustomCheckboxEntryForCheckbox((int) $matches[1]);
}
if (preg_match('/customCheckboxEntryValueByCheckboxId(\d+)/', $arg, $matches)) {
return $this->getCustomCheckboxEntryValueByCheckboxId((int) $matches[1]);
}
} my tests use |
@craigh you might have a broken implementation of |
@nicolas-grekas of course, you are correct 🎉 thank you for your keen insight and quick response! |
…ess v6.4.6 (#38013) - since symfony/property-access 6.4.6 the application crashed with a lot of exceptions like "Can't get a way to read the property ... in class ...", see symfony/symfony#54194
…ess v6.4.6 (#38013) - since symfony/property-access 6.4.6 the application crashed with a lot of exceptions like "Can't get a way to read the property ... in class ...", see symfony/symfony#54194
…ess v6.4.6 (#38013) - since symfony/property-access 6.4.6 the application crashed with a lot of exceptions like "Can't get a way to read the property ... in class ...", see symfony/symfony#54194
…ess v6.4.6 (#38013) - since symfony/property-access 6.4.6 the application crashed with a lot of exceptions like "Can't get a way to read the property ... in class ...", see symfony/symfony#54194
…ess v6.4.6 (#38013) - since symfony/property-access 6.4.6 the application crashed with a lot of exceptions like "Can't get a way to read the property ... in class ...", see symfony/symfony#54194
…ess v6.4.6 (#38013) - since symfony/property-access 6.4.6 the application crashed with a lot of exceptions like "Can't get a way to read the property ... in class ...", see symfony/symfony#54194
…ess v6.4.6 (#38013) - since symfony/property-access 6.4.6 the application crashed with a lot of exceptions like "Can't get a way to read the property ... in class ...", see symfony/symfony#54194
…ess v6.4.6 (#38013) - since symfony/property-access 6.4.6 the application crashed with a lot of exceptions like "Can't get a way to read the property ... in class ...", see symfony/symfony#54194
This is a BC break, I'm now getting:
Even if I have this, to access dynamic properties stored in a json column:
It's look like the magic getter is never called |
@fmonts same as above: you likely have a broken implementation of __isset, please have a look and try to fix it. |
I don't have any
to many entities... |
That's why then. You relied on a specific behavior of PropertyAccess, which is broken in the generic case (eg the |
This seems to break access to properties in Laravel Eloquent models when the value is I'm not sure if there is a 'standard' way to check for access there, because of the way ActiveRecord works (at least in Laravel). In Laravel it is always possible to set or get a property on the model.. |
…ess v6.4.6 (#38014) - since symfony/property-access 6.4.6 the application crashed with a lot of exceptions like "Can't get a way to read the property ... in class ...", see symfony/symfony#54194
…ess v6.4.6 (#38014) - since symfony/property-access 6.4.6 the application crashed with a lot of exceptions like "Can't get a way to read the property ... in class ...", see symfony/symfony#54194
…ess v6.4.6 (#38014) - since symfony/property-access 6.4.6 the application crashed with a lot of exceptions like "Can't get a way to read the property ... in class ...", see symfony/symfony#54194
…ess v6.4.6 (#38014) - since symfony/property-access 6.4.6 the application crashed with a lot of exceptions like "Can't get a way to read the property ... in class ...", see symfony/symfony#54194
…ess v6.4.6 (#38014) - since symfony/property-access 6.4.6 the application crashed with a lot of exceptions like "Can't get a way to read the property ... in class ...", see symfony/symfony#54194
…ess v6.4.6 (#38014) - since symfony/property-access 6.4.6 the application crashed with a lot of exceptions like "Can't get a way to read the property ... in class ...", see symfony/symfony#54194
…ess v6.4.6 (#38014) - since symfony/property-access 6.4.6 the application crashed with a lot of exceptions like "Can't get a way to read the property ... in class ...", see symfony/symfony#54194
Hi all, I faced an issue today trying to upgrade a SF 6.4 project regarding this point. I have a Dto with a property _foo as an array.
I have also a magic getter on this Dto like that.
Now with this PR, code break because of the PHP documentation said: __get() is utilized for reading data from inaccessible (protected or private) or non-existing properties. In regards of the php doc, I should be able to read this property using the magic method, so I'm confused with this "can't get a way to read the property" error. Is this because I'm wrong with my understanding on how I'm allowed to work with magic getter, or because this fix is now too strict and can results in false error on some edge cases like mine ? |
@u03c1 You also need to implement the |
Well, I have seen this same answer 2 or 3 times on this thread before I post, but my brain didn't connect and search an isset in my __get(), not an __isset(). 🤦 Thanks again. |
…ess v6.4.6 (#38014) - since symfony/property-access 6.4.6 the application crashed with a lot of exceptions like "Can't get a way to read the property ... in class ...", see symfony/symfony#54194
…ess v6.4.6 (#38013) - since symfony/property-access 6.4.6 the application crashed with a lot of exceptions like "Can't get a way to read the property ... in class ...", see symfony/symfony#54194
PropertyAccess and PropertyInfo make a few assumptions when magic methods are involved.
Namely they assume that if a
__get
method is defined, then any property name is accessible.This assumption is generally wrong, and this becomes more evident with the introduction of lazy objects.
The linked issue gives some more details.
In this PR, I tweak these assumptions in order to make less of them.
Note that there is no bullet-proof way to decide if a virtual property exists in PHP. We're missing an
__exists()
magic method for that. Because of this, I'm submitting this PR to 6.4 and not 5.4. Let 5.4 end its life quietly and ensure 6.4 works at its best with lazy ghosts, where they're mainstream.