Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:129553 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 C89721A00BC for ; Thu, 4 Dec 2025 18:00:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1764871249; bh=YcJnrS0UMZ0lhyCsudx5rL7d5UyiJ5Qn7U9j90dECj0=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=FLIWnVojK8KTMSVc7EB/CUQmdERoCJ6Q7B4MJSXQNbd+7JkWgSnMWK3LSwJZe3n+e QUON0tTrz9aJwgWqQMxtWqz7QqnuLZ0UYSdkV+IjTkgJxZxP76T8JPEoftNzPBCX0+ Ev/PRJoWWPJxHK84MMQXF0F24+kaTKvSd/kR7ECPkQAMWBlH/xmpT75URc3MLNUblr /UEVPkSjC/uZP+wcmERpaikk/VKYKv2/Sx2c6vlWgfJW3wbNsSbbxk2jHKldISmZZQ jcKIJYPq0pBYUmzqE1DQ4ItPHV3NNnX663uI0wmDdtSEgNazbObIHqpQ0NT68M6E+B YIUJx7zj90RJA== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 4D0B0180086 for ; Thu, 4 Dec 2025 18:00:48 +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=0.6 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,FREEMAIL_FROM, HTML_MESSAGE,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from mail-qk1-f173.google.com (mail-qk1-f173.google.com [209.85.222.173]) (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 ; Thu, 4 Dec 2025 18:00:47 +0000 (UTC) Received: by mail-qk1-f173.google.com with SMTP id af79cd13be357-8b2f2c5ec36so124427485a.1 for ; Thu, 04 Dec 2025 10:00:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1764871242; x=1765476042; darn=lists.php.net; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=6Zld1LeGtQZc86ppMU0QMbsNcZlgeDSoSjpFAA+ZnlQ=; b=YFVVht6EiVGzcgOwHDgxdKcD0mX7mXPPi8BSqHxG5LoWZZFLwgslED8/ubfFgGVJ8z kxgXeKHOtr5cJpSZNaCDvV0RlqLGs8E36g4Xv7Ref0BasMti7y15BHaYsMCGduHIARiV PBa4YFFpgaVsDThgIchAa06FE9HXmFgkJ4m3WhCf/SkZnnWLf9LdjP1euSObve2CPxkl SF0NKdeEi33xbD/DrPVCj3PmYnwX+tLq3PNksadYfDgCL1nVpewVDuNmPUNL5PIpFh0q qQkQkPKflu/HkFNpEtHWWEAlWponmoG81v6LpsZdwuA4vxGCW0RfuR8E1ZhUWXr+pu7+ NQmg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764871242; x=1765476042; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=6Zld1LeGtQZc86ppMU0QMbsNcZlgeDSoSjpFAA+ZnlQ=; b=tKHP6Y922/zr3tQRt1C3CHxEK1yMD83933LBNBQlHpM5d2p0su+U3V2+74vClkcmXX ZfFChXoHaUbpQ8Z/oGaG1n3KbV7aYO9qEyz+hKKIKAhR1tc3r3Zqv5EB0yE+f18s4vae /bzR+ZZ9SDfQ0QBE090PyNNmCeKfHY2i5BXuho3WJiBnBI5tLNCh18y0J4oSLivycuvA xQ3dJCPFad6VUkgblcDN7dZA172NAFQWJMHW1+YZ71ujtNFjW1UoBBwCQUhEtBOsdh/a rs05bzXk2KECIdwraGECDNJqSpaw/creqMBkr0hsRh0f50GJxJeflWheu1xxeFfKpaHA IiDQ== X-Gm-Message-State: AOJu0YwYjrRbgvBC0DTqu4MP3hiLgGP+9yLMh89FxZk1Yjc4nCEa7Hl2 3nuYr8ny+C2ni/LHIbMDVUJmus8i9TiMiHaHgRjlsiWbG9ClNWZnS8fueyW7G0iSo40Qj4S5VSY PAlmQpiJGgnN6rn83XE/laJl1wc4DCNJB8SrSiOQ= X-Gm-Gg: ASbGnct3/d3IabDQ2gtmV3Z1m930O9vulyLjd7FiGMNxmIUseJ9aFlsIyUbQrbZP7bw wlkpUJEQ5wIXtfahp+S6Cp5rgW0yO4s5IyS8ffEzkin6RDWwcFBn1mRMt/Y0WWwazrGiHJe6oXQ rsZwM3V8eUwrQh4Z6bsjL9AU5b+SUMMlx2pccsOA7kfoERTgi7cf74+a17q7swG0VRRYIlfBq4B tqMXbKpt3cJDtpbuy7tbjmcJ7GMYbWmoDbwOODc6ocKEz53dXaBxlWRQzHLrHGpWUZQZtqDtV7W 0lfxTt5ZsoRTgQT2wSDmTrOAZef64oMqfDhKy8LLxFvhJieDGb7D7I6h6eLGLFXMK2Ph1g== X-Google-Smtp-Source: AGHT+IH3y7OqKhpBeCX77paWEOw62cb/0FDFhdKQkNHjrdIiEouznxa0HUqhxDtYm9zET4iHlmLnCcLYqFlp7sPs2ao= X-Received: by 2002:a05:620a:1987:b0:8b2:33f5:fa49 with SMTP id af79cd13be357-8b5e47d0225mr960371485a.14.1764871240423; Thu, 04 Dec 2025 10:00:40 -0800 (PST) Precedence: list list-help: list-unsubscribe: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 References: In-Reply-To: Date: Thu, 4 Dec 2025 19:00:29 +0100 X-Gm-Features: AWmQ_bmVOpMbDBhUtQY1Sb0LAFCYrC0ufP4MZ6LmR2CWidDGRVA_fmKvZc1aVM0 Message-ID: Subject: Re: [PHP-DEV] [RFC] isReadable/isWriteable property reflection To: Larry Garfield Cc: php internals Content-Type: multipart/alternative; boundary="0000000000005c1e110645241b9e" From: nicolas.grekas+php@gmail.com (Nicolas Grekas) --0000000000005c1e110645241b9e Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Le jeu. 4 d=C3=A9c. 2025 =C3=A0 18:03, Larry Garfield a =C3=A9crit : > On Thu, Dec 4, 2025, at 10:47 AM, Nicolas Grekas wrote: > > Le jeu. 4 d=C3=A9c. 2025 =C3=A0 17:39, Larry Garfield a > =C3=A9crit : > >> On Thu, Dec 4, 2025, at 8:05 AM, Nicolas Grekas wrote: > >> > Le jeu. 6 nov. 2025 =C3=A0 00:28, Larry Garfield > a =C3=A9crit : > >> >> In other news, Ilija and I said a year ago that we'd take a swing a= t > adding isReadable/isWriteable methods to ReflectionProperty. Took a whil= e, > but here we are. A strangely small RFC from us: > >> >> > >> >> https://wiki.php.net/rfc/isreadable-iswriteable > >> >> > >> > > >> > > >> > Thanks for this. > >> > I also think the auto-scope is [NOT] a good idea. You state that 90% > of use > >> > cases will need this but my experience doesn't back this claim. The > >> > only cases where I had to check for read/writeable were out of the > >> > local scope, so I'd say 100% of my experience goes against that 90% > >> > number ;) Joke aside, it'd be just fine to let ppl be explicit. > That's > >> > better than "oops I forgot to give the correct scope" bugs. > >> > > >> > About magic methods, one unsets a property only to have __get/__set > >> > called. Existing code works with this assumption. This means we have > to > >> > return true IMHO. Magic methods are just generic hooks also. Which > >> > means they should behave the same. > >> > > >> > Nicolas > >> > >> Well, the only people who seem to have an opinion don't like "static", > so we've removed it. RFC updated. > >> > >> As for __get/__set, that's so far one vote for ignore (Tim), and one > for always-true (Nicolas). Not a consensus. :-) > >> > >> Nicolas, can you clarify with an example if/how ignore would break > things? > >> > >> I think once we settle that question and the cooldown passes we're > ready for a vote, though at this point that means January. > >> > > > > I can try to build a synthetic example but the gist is: > > A class that starts with only properties and no __get() should be able > > to move to a __get()-based hooking in a later version without breaking > > code that uses isReadable(). > > That on its own should be enough to settle the desired behavior :) > > So you want to be able to transition from: > > class Foo > { > public private(set) string $name; > } > > To > > class Foo > { > private array $vals =3D []; > > public function __get(string $name) > { > return $this->vals[$name] ?? throw new Exception(); > } > } > > Is that right? Because both approaches would result in changes in some > situations there. > > If __get is ignored and the value is set, then a global isReadable check > will go from true to false in that transition. > > If __get always returns true and the value is still uninitialized, a > global isReadable check will go from false to true in that transition. > > Either way, that's not a fully safe transition to make. > > --Larry Garfield > Nah, I'm thinking about a scenario very close to what you talk about in the RFC: unset + __get From: class Foo { public int $abc; public function __construct() { $this->abc =3D stuff(); } } To: class Foo { public int $abc; public function __construct() { unset($this->abc); } public function __get($name) { if ('abc' =3D=3D=3D $name) { return $this->abc =3D stuff(); } } } --0000000000005c1e110645241b9e Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


Le=C2=A0jeu. 4 = d=C3=A9c. 2025 =C3=A0=C2=A018:03, Larry Garfield <larry@garfieldtech.com> a =C3=A9crit=C2=A0:
<= /div>
On Thu, Dec 4, 2025,= at 10:47 AM, Nicolas Grekas wrote:
> Le jeu. 4 d=C3=A9c. 2025 =C3=A0 17:39, Larry Garfield <larry@garfieldtech.com&= gt; a =C3=A9crit :
>> On Thu, Dec 4, 2025, at 8:05 AM, Nicolas Grekas wrote:
>> > Le jeu. 6 nov. 2025 =C3=A0 00:28, Larry Garfield <larry@garfieldtech.com= > a =C3=A9crit :
>> >> In other news, Ilija and I said a year ago that we'd = take a swing at adding isReadable/isWriteable methods to ReflectionProperty= .=C2=A0 Took a while, but here we are.=C2=A0 A strangely small RFC from us:=
>> >>
>> >> https://wiki.php.net/rfc/isreadable= -iswriteable
>> >>
>> >
>> >
>> > Thanks for this.
>> > I also think the auto-scope is [NOT] a good idea. You state t= hat 90% of use
>> > cases will need this but my experience doesn't back this = claim. The
>> > only cases where I had to check for read/writeable were out o= f the
>> > local scope, so I'd say 100% of my experience goes agains= t that 90%
>> > number ;) Joke aside, it'd be just fine to let ppl be exp= licit. That's
>> > better than "oops I forgot to give the correct scope&quo= t; bugs.
>> >
>> > About magic methods, one unsets a property only to have __get= /__set
>> > called. Existing code works with this assumption. This means = we have to
>> > return true IMHO. Magic methods are just generic hooks also. = Which
>> > means they should behave the same.
>> >
>> > Nicolas
>>
>> Well, the only people who seem to have an opinion don't like &= quot;static", so we've removed it.=C2=A0 RFC updated.
>>
>> As for __get/__set, that's so far one vote for ignore (Tim), a= nd one for always-true (Nicolas).=C2=A0 Not a consensus. :-)
>>
>> Nicolas, can you clarify with an example if/how ignore would break= things?=C2=A0
>>
>> I think once we settle that question and the cooldown passes we= 9;re ready for a vote, though at this point that means January.
>>
>
> I can try to build a synthetic example but the gist is:
> A class that starts with only properties and no __get() should be able=
> to move to a __get()-based hooking in a later version without breaking=
> code that uses isReadable().
> That on its own should be enough to settle the desired behavior :)

So you want to be able to transition from:

class Foo
{
=C2=A0 public private(set) string $name;
}

To

class Foo
{
=C2=A0 private array $vals =3D [];

=C2=A0 public function __get(string $name)
=C2=A0 {
=C2=A0 =C2=A0 return $this->vals[$name] ?? throw new Exception();
=C2=A0 }
}

Is that right?=C2=A0 Because both approaches would result in changes in som= e situations there.

If __get is ignored and the value is set, then a global isReadable check wi= ll go from true to false in that transition.

If __get always returns true and the value is still uninitialized, a global= isReadable check will go from false to true in that transition.

Either way, that's not a fully safe transition to make.

--Larry Garfield

Nah, I'm thinking= =C2=A0about a scenario very close to what you talk about in the RFC: unset= =C2=A0+ __get

From:
class Foo
= {
=C2=A0 =C2=A0 public int $abc;

=C2=A0 = =C2=A0 public function __construct()
=C2=A0 =C2=A0 {
= =C2=A0 =C2=A0 =C2=A0 =C2=A0 $this->abc =3D stuff();
=C2=A0 =C2= =A0 }
}

To:
class Foo
{
=C2=A0 =C2=A0 public int $abc;

= =C2=A0 =C2=A0 public function __construct()
=C2=A0 =C2=A0 {
=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 unset($this->abc);
=C2=A0 =C2= =A0 }

=C2=A0 =C2=A0 public function __get($na= me)
=C2=A0 =C2=A0 {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (= 9;abc' =3D=3D=3D $name) {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 return $this->abc =3D stuff();
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 }
=C2=A0 =C2=A0 }
}

--0000000000005c1e110645241b9e--