On Sat, Aug 2, 2025, at 19:04, Alexandru Pătrănescu wrote: > > > On Sat, Aug 2, 2025, 17:10 Rob Landers <rob@bottled.codes> wrote: >> __ >> >> >> On Sat, Aug 2, 2025, at 16:04, Alexandru Pătrănescu wrote: >>> >>> >>> On Sat, Aug 2, 2025 at 12:10 PM Rob Landers <rob@bottled.codes> wrote: >>>> __ >>>> On Tue, Jul 29, 2025, at 20:11, Jonathan Vollebregt wrote: >>>>> I came across this edge case today: >>>>> >>>>> https://3v4l.org/R3Q8D >>>>> >>>>> Both psalm and phpstan think this code is A-OK (Once you add the >>>>> requisite type hints) but it causes fatal errors way back to PHP 5.0.0 >>>>> >>>>> ...<snip>... >>>> >>>> It's not an edge case, in C2, you redefine a protected variable with the >>>> same name and shadowed the original $v. That $v is different than C's $v. >>>> It's easiest to see this with static access: https://3v4l.org/0SRWb#v8.4.10 >>>> >>>> However, I don't know of any way to unshadow a property from $this to >>>> access the ancestor's value (other than using private access), but it >>>> exists and takes up memory; just accessing it is the hard part. >>>> >>>> — Rob >>> >>> >>> Hi Rob, >>> >>> I'm pretty sure that there is no shadowing happening in the example. >>> When the child instance is created, there is just one slot for the >>> property, as the child one replaces the parent one. >>> So basically the child property overrides the parent property rather than >>> shadowing it. >>> >>> True shadowing (two slots) only occurs when the parent property is declared >>> private. >>> >>> It's just that when redefining, it stores the declaring class, and so there >>> is this sibling class access issue. >>> >>> I'm wondering now if the access shouldn't be relaxed, in case we have the >>> parent class that initially defined the property. >>> >>> Of course, we should focus on non-static properties, as static ones are >>> different things, and there is some shadowing there. >>> >>> -- >>> Alex >> >> Hi Alex, >> >> I’m not sure what you mean? https://3v4l.org/WKILh#v8.4.10 >> >> There is clearly shadowing going on. >> >> > > Hi Rob, > > As I said, let's leave aside the static case, as the question from Jonathan > was not about that. > > Given the class P that defines a protected property with value 1, > and a class C that extends P and re-defines the protected property with the > value 2, > please show me an example where you could get from an instance of class C the > value 1 of the parent class property that you think it's shadowed. > Bonus point, if you manage that, you could also set it to something else, and > so have a hidden storage for any object of class C that is not really visible > normally. > > As far as I know, there is no way to achieve that, and the reason is because > at runtime the objects have a single slot for the protected property; the > child class property overrides the parent class property when redeclared, and > does not shadow it. > But please prove me wrong. > > > Thanks, > Alex >
I mentioned in my first reply, there is no way to get an instance-level property unshadowed. It is there though (according to inheritance.c, if I’m reading it right, it is still accessible, just not from user-land). In any case, there are lots of interesting footguns with properties and inheritance: Problem with abstract nested object · Issue #47 · Crell/Serde <https://github.com/Crell/Serde/issues/47#issuecomment-1890966829>. > Could it be considered a bug that my first example produces a fatal > error instead of trying to access the shadowed parent property that it > has access to and is typed to use? Other languages (such as C#, Java, etc: https://www.programiz.com/online-compiler/0ud6UO24mHOTU) don’t allow you to access protected properties/methods on sibling classes. This is because "protected" is usually used in the context of inheritance; access is usually restricted to "myself" or "children" and a sibling is neither of those. If there is a bug, the bug is that you can access a sibling’s protected properties, at all. — Rob