On Sat, Aug 2, 2025, at 22:17, Rob Landers <rob@bottled.codes> wrote:

> 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
>

> If there is a bug, the bug is that you can access a sibling’s protected
properties, at all.

In 2006 the absence of this feature was fixed as a bug and meged in PHP
5.2: https://bugs.php.net/bug.php?id=37632
In 2020 Nikita Popov agreed that this is expected:
https://x.com/nikita_ppv/status/1261633126687805440

So one way is to explicitly mention this feature in the Visibility docs
<https://www.php.net/manual/en/language.oop5.visibility.php> and fix the
redeclaration issue to make things consistent.

The other way is to deprecate sibling relations.

-- 
Valentin

Reply via email to