Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:128374 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by lists.php.net (Postfix) with ESMTPS id 98C341A00BC for ; Sat, 2 Aug 2025 19:13:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1754161902; bh=Aztt0MbgVfcGNq0LE5HTQeLf2Kg6XBvG7lI9lraXa5M=; h=Date:From:To:Cc:In-Reply-To:References:Subject:From; b=HB5d33eYh/6XaKeK4B0j5gj5vwdtE4nLWokp4o9lw503EO+4ps3Lalw0IT7WaBmSD sSz3SDRp4Fics5ImvOnBbdtAKeD/9V7puqOUZTLSJvpqUg7LOPgVM5FaT5xkaUvEUX ZF+msV//68AUEizTUMKSoOyi4QWd7Gjx1JZZCWXO+ehIba8xE6mvquYdAWy5+dhseD /yWoqNJYf79k78jhBkGHv0PDk0jcbqEUiGtwrm+NdIidDI2ajK87hfnUDdC8gP4C3V 3HzBNlpKQArfBkCmXzK9H6jwEwEJZymlj0C8oVeyaUh8HH05Jql5gztqiFq6KEgQRI TPkGYjJ8gi8oQ== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 4AFFD180061 for ; Sat, 2 Aug 2025 19:11:41 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_MISSING,HTML_MESSAGE, RCVD_IN_DNSWL_LOW,SPF_HELO_PASS,SPF_PASS autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: Error (Cannot connect to unix socket '/var/run/clamav/clamd.ctl': connect: Connection refused) X-Envelope-From: Received: from fhigh-b1-smtp.messagingengine.com (fhigh-b1-smtp.messagingengine.com [202.12.124.152]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Sat, 2 Aug 2025 19:11:40 +0000 (UTC) Received: from phl-compute-05.internal (phl-compute-05.phl.internal [10.202.2.45]) by mailfhigh.stl.internal (Postfix) with ESMTP id 6FA857A0339; Sat, 2 Aug 2025 15:13:21 -0400 (EDT) Received: from phl-imap-05 ([10.202.2.95]) by phl-compute-05.internal (MEProxy); Sat, 02 Aug 2025 15:13:21 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bottled.codes; h=cc:cc:content-type:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=fm1; t=1754162001; x= 1754248401; bh=Aztt0MbgVfcGNq0LE5HTQeLf2Kg6XBvG7lI9lraXa5M=; b=O CLayIMqjVscW8yaTWkFImUdZfURBJ/6GS1kGEqGgOpWhmBb6hJDVPhsKR7aJntS6 evSzqsyhkrEbdjiqysQ98QpIBcZuWUok74KNm9tp9atP7WSQUCW0b4muorGwXi76 ByMsHwkQo/XY6KJ8zfjYOJJ9t391AP5S29bEmVi3dXnl6xky/XHRQuEMDFL7AjY4 RNS7MQ74zwemZ+p9m1jdM6dc1jZRu2QM9oLp3ng2LtQZ9eBgHrpe4kQ8Lg187Wms 0sU5J17dPeLJuaVdTjZ/L7B1pQVetZYe+s8SSCMXI6o1E64IsA+J0heKSxkj35yn v7vqX+h1R5WihjHp1qGsw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm3; t= 1754162001; x=1754248401; bh=Aztt0MbgVfcGNq0LE5HTQeLf2Kg6XBvG7lI 9lraXa5M=; b=I48PBIc61IGjlZvHCRzCavqrKHq+VPQAIEH8ltG+5s3EB8TfcjX UhGAOSuWdasNN1XmqlbnMQ1VRvLsfDqcUmbWsSKvLyzQ/t02T4/MN8MVhJmNl5YP yYvTvjgJ9LzszQVfGYlU9wEa87uIIG5/J8P2aQkMHwV8aKS9iSqpK76r+T/y1Uav nCvkW0z5l16U419gD+Y/IKiPB6nLEmgaltFa26CIqKnzvzzGhbgjiygVwSUOk1qW CtWy/xCT1kRV+fTryN5cPItTWngDku4zdMjfnQpwiFngMjJ/Gmn1AVALZ6FiGp6/ S7/kj/EvQ+Pyn2qiVyTmrxZh3kn3FRp3G+Q== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeffedrtdefgddutdejfeekucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfurfetoffkrfgpnffqhgenuceu rghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmnegouf hushhpvggtthffohhmrghinhculdegledmnecujfgurhepofggfffhvfevkfgjfhfutges rgdtreerredtjeenucfhrhhomhepfdftohgsucfnrghnuggvrhhsfdcuoehrohgssegsoh htthhlvggurdgtohguvghsqeenucggtffrrghtthgvrhhnpeevieeguefhtddtteeuvddu feejieehtefhuedujefgvddtveegheehhefftdefjeenucffohhmrghinhepfehvgehlrd horhhgpdhgihhthhhusgdrtghomhdpphhrohhgrhgrmhhiiidrtghomhenucevlhhushht vghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehrohgssegsohhtthhlvg gurdgtohguvghspdhnsggprhgtphhtthhopedvpdhmohguvgepshhmthhpohhuthdprhgt phhtthhopegurhgvrghlvggtshesghhmrghilhdrtghomhdprhgtphhtthhopehinhhtvg hrnhgrlhhssehlihhsthhsrdhphhhprdhnvght X-ME-Proxy: Feedback-ID: ifab94697:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id 0688E1820074; Sat, 2 Aug 2025 15:13:20 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface Precedence: list list-help: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 X-ThreadId: ApgyNlIcRpMw Date: Sat, 02 Aug 2025 21:12:59 +0200 To: =?UTF-8?Q?Alexandru_P=C4=83tr=C4=83nescu?= Cc: "PHP internals" Message-ID: <900d2936-6afd-4eed-b08a-1540d124273a@app.fastmail.com> In-Reply-To: References: <2d516e15-2fc7-4ac4-b9c2-7146ac01cfb1@app.fastmail.com> <8c60c0b8-8826-49a4-80ba-973ff833fff7@app.fastmail.com> Subject: Re: [PHP-DEV] Protected inheritance hierarchies Content-Type: multipart/alternative; boundary=5ec7e560813c4beb86e12b8f684486e0 From: rob@bottled.codes ("Rob Landers") --5ec7e560813c4beb86e12b8f684486e0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On Sat, Aug 2, 2025, at 19:04, Alexandru P=C4=83tr=C4=83nescu wrote: >=20 >=20 > On Sat, Aug 2, 2025, 17:10 Rob Landers wrote: >> __ >>=20 >>=20 >> On Sat, Aug 2, 2025, at 16:04, Alexandru P=C4=83tr=C4=83nescu wrote: >>>=20 >>>=20 >>> On Sat, Aug 2, 2025 at 12:10=E2=80=AFPM Rob Landers wrote: >>>> __ >>>> On Tue, Jul 29, 2025, at 20:11, Jonathan Vollebregt wrote: >>>>> I came across this edge case today: >>>>>=20 >>>>> https://3v4l.org/R3Q8D >>>>>=20 >>>>> Both psalm and phpstan think this code is A-OK (Once you add the=20 >>>>> requisite type hints) but it causes fatal errors way back to PHP 5= .0.0 >>>>>=20 >>>>> ...... >>>>=20 >>>> It's not an edge case, in C2, you redefine a protected variable wit= h 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/0S= RWb#v8.4.10 >>>>=20 >>>> 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. >>>>=20 >>>> =E2=80=94 Rob >>>=20 >>>=20 >>> Hi Rob, >>>=20 >>> 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 p= roperty, as the child one replaces the parent one. >>> So basically the child property overrides the parent property rather= than shadowing it. >>>=20 >>> True shadowing (two slots) only occurs when the parent property is d= eclared private. >>>=20 >>> It's just that when redefining, it stores the declaring class, and s= o there is this sibling class access issue. >>>=20 >>> I'm wondering now if the access shouldn't be relaxed, in case we hav= e the parent class that initially defined the property. >>>=20 >>> Of course, we should focus on non-static properties, as static ones = are different things, and there is some shadowing there. >>>=20 >>> --=20 >>> Alex >>=20 >> Hi Alex, >>=20 >> I=E2=80=99m not sure what you mean? https://3v4l.org/WKILh#v8.4.10 >>=20 >> There is clearly shadowing going on. >>=20 >>=20 >=20 > Hi Rob, >=20 > As I said, let's leave aside the static case, as the question from Jon= athan was not about that. >=20 > 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 wit= h the value 2, > please show me an example where you could get from an instance of clas= s C the value 1 of the parent class property that you think it's shadowe= d. > Bonus point, if you manage that, you could also set it to something el= se, and so have a hidden storage for any object of class C that is not r= eally visible normally. >=20 > As far as I know, there is no way to achieve that, and the reason is b= ecause at runtime the objects have a single slot for the protected prope= rty; the child class property overrides the parent class property when r= edeclared, and does not shadow it. > But please prove me wrong. >=20 >=20 > Thanks, > Alex >=20 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=E2=80=99m 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 =C2=B7 Issue #47 =C2=B7= Crell/Serde .=20 > Could it be considered a bug that my first example produces a fatal=20 > error instead of trying to access the shadowed parent property that it=20 > has access to and is typed to use? Other languages (such as C#, Java, etc: https://www.programiz.com/online= -compiler/0ud6UO24mHOTU) don=E2=80=99t allow you to access protected pro= perties/methods on sibling classes. This is because "protected" is usual= ly 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 b= ug, the bug is that you can access a sibling=E2=80=99s protected propert= ies, at all. =E2=80=94 Rob --5ec7e560813c4beb86e12b8f684486e0 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable
On Sat, Aug = 2, 2025, at 19:04, Alexandru P=C4=83tr=C4=83nescu wrote:


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



On Sat, Aug 2, 2025, at 16:04,= Alexandru P=C4=83tr=C4=83nescu wrote:


On Sat, Aug 2, 2025 at 12:10=E2= =80=AFPM Rob Landers <rob@bottled.codes> wrote:

On Tue= , Jul 29, 2025, at 20:11, Jonathan Vollebregt wrote:
I came across this edge case today:


Both psalm and phpstan think t= his 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 a= nd shadowed the original $v. That $v is different than C's $v. It's easi= est 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 th= an using private access), but it exists and takes up memory; just access= ing it is the hard part.

=E2=80=94 Rob
<= /blockquote>


Hi Rob,

I'm pretty sure that there is no shadowing happening in the exam= ple.
When the child instance is created, there is just on= e slot for the property, as the child one replaces the parent one.
=
So basically the child property overrides the parent property=20=0A= =0Arather than shadowing it.

True shadowi= ng (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.
<= div>
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 propert= ies, as static ones are different things, and there is some shadowing th= ere.

-- 
Alex
<= /blockquote>

Hi Alex,

I=E2=80= =99m not sure what you mean? https://3v4l.org/WKILh#v8.4.10=

There is clearly shadowing going on.
=



Hi Rob,

As I said, l= et'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 propert= y with the value 2,
please show me an example whe= re you could get from an instance of class C the value 1 of the parent c= lass 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 v= isible normally.

As f= ar 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; t= he child class property overrides the parent class property when redecla= red, and does not shadow it.
But please prove me = wrong.


Thanks,
Alex


I mentioned in my first reply, there is no w= ay to get an instance-level property unshadowed. It is there though (acc= ording to inheritance.c, if I=E2=80=99m reading it right, it is still ac= cessible, just not from user-land).

In any case= , there are lots of interesting footguns with properties and inheritance= : Problem with abstract nested object =C2=B7 Issue #47 =C2=B7 = Crell/Serde

Could it be considered a bug that my first example produces a fatal&nb= sp;
error instead of trying to access the shadowed parent prop= erty that it 
has access to and is typed to use?

Other languages (such as C#, Java, etc:&nb= sp;h= ttps://www.programiz.com/online-compiler/0ud6UO24mHOTU) don=E2=80=99= t allow you to access protected properties/methods on sibling classes. T= his is because "protected" is usually used in the context of inheritance= ; access is usually restricted to "myself" or "children" and a sibling i= s neither of those. If there is a bug, the bug is that you can access a = sibling=E2=80=99s protected properties, at all.

=E2=80=94 Rob --5ec7e560813c4beb86e12b8f684486e0--