Skip to content

Conversation

JeroenVanOort
Copy link
Contributor

No description provided.


public function hasProperty(ClassReflection $classReflection, string $propertyName): bool
{
if ($classReflection->hasNativeProperty($propertyName)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only for subclasses of stdClass. Ask $classReflection->isSubclassOf.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why only for subclasses of stdClass? I'm trying to understand but I don't at the moment.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because only stdClass behaves like this. We cannot be sure how others implement __get/__set behaviour.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do I understand you correctly when I think that this is a use case?

class Foo { private $bar = 43; public function __get($name) { return 42; } } $foo = new Foo(); $foo->bar; // 42, not 43 nor access to a private property

Shouldn't we solve this by looking at visibility? Because even if Foo were a subclass of stdClass, this would still result in an error. And it would be broader than just sublcasses of stdClass.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is a valid use-case I'm talking about.

If $bar was public, UniversalObjectCratesClassReflectionExtension isn't even executed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I'm starting to get this, although I don't think we should check if the class we're working on is a subclass of stdClass, because those don't appear to behave different from a class that is not a subclass of stdClass:

class A extends \stdClass { private $bar = 43; public function __get($name) { return 42; } } class B extends \stdClass { private $bar = 43; } class C { private $bar = 43; public function __get($name) { return 42; } } class D { private $bar = 43; } $a = new A(); $b = new B(); $c = new C(); $d = new D(); echo $a->bar; // 42, not 43 echo $b->bar; // Cannot access private property B::$bar echo $c->bar; // 42, not 43 echo $d->bar; // Cannot access private property D::$bar

Instead of checking if a native property exists, we should probably check if the __get method doesn't. Otherwise, $a->bar and $c->bar would falsely be reported as problematic when A and B are configured as universal crate objects.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Class A is an edgecase we don't have to care about. (extends stdClass + custom __get)
Class B is the case I want to get solved in this PR.
Class C currently works (and should not get broken by this PR).
Class D does not have __get method, should not be added to universalObjectCrateClasses.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can also solve A with one more if statement but it's not necessary.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C will not get falsely reported because C does not extend stdClass.

@ondrejmirtes
Copy link
Member

Please open the PR again if you decide to work on it. Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants