[RFC] isReadable/isWriteable property reflection

php.internals

Larry Garfield

299 days ago
In other news, Ilija and I said a year ago that we'd take a swing at adding isReadable/isWriteable methods to ReflectionProperty. Took a while, but here we are. A strangely small RFC from us: https://wiki.php.net/rfc/isreadable-iswriteable
-- Larry Garfield larry@garfieldtech.com

Tim Düsterhus

298 days ago
Hi Am 2025-11-06 00:24, schrieb Larry Garfield:
> In other news, Ilija and I said a year ago that we'd take a swing at > adding isReadable/isWriteable methods to ReflectionProperty. Took a > while, but here we are. A strangely small RFC from us: > > https://wiki.php.net/rfc/isreadable-iswriteable
I dislike implicitly “scope-dependent” functions, since they effectively act like magic. This probably makes it harder to understand for humans and static analysis tools alike. I would therefore suggest making the `$scope` parameter required. A user can just pass `static::class` themselves and static analysis tools can use `class-string|null` instead of `class-string|"static"|null` as their expected parameter type. As for the magic method logic: I would suggest to ignore the presence of __get() and __set(). This more closely aligns with the direction PHP goes towards and is also easy to work around by checking with `method_exists()` whether any such a method exists - the reverse is not true. Best regards Tim Düsterhus

Larry Garfield

298 days ago
On Fri, Nov 7, 2025, at 5:03 AM, Tim Düsterhus wrote:
> Hi > > Am 2025-11-06 00:24, schrieb Larry Garfield: >> In other news, Ilija and I said a year ago that we'd take a swing at >> adding isReadable/isWriteable methods to ReflectionProperty. Took a >> while, but here we are. A strangely small RFC from us: >> >> https://wiki.php.net/rfc/isreadable-iswriteable > > I dislike implicitly “scope-dependent” functions, since they effectively > act like magic. This probably makes it harder to understand for humans > and static analysis tools alike. I would therefore suggest making the > `$scope` parameter required. A user can just pass `static::class` > themselves and static analysis tools can use `class-string|null` instead > of `class-string|"static"|null` as their expected parameter type.
Given that the 90% or more case is likely to be "from my current context", making that the default seems the most ergonomic. (The counter argument, I suppose, is that this is hardly going to be a super-common routine to call so ergonomics don't matter.) stack-inspection isn't new. `Closure::getCurrent()` is the most recent example, so we don't think it's especially problematic. If there's a preference for avoiding magic strings, it would be easy enough to use an enum instead. Something like: enum CallerScope { case Caller; case Global; } function isReadable(string|CallerScope $scope = CallerScope::Caller, ?object $objecg = null) { ... } `Caller` would still do the same stack inspection, but it makes the type more tightly controlled and eliminates a nullable.
> As for the magic method logic: I would suggest to ignore the presence of > __get() and __set(). This more closely aligns with the direction PHP > goes towards and is also easy to work around by checking with > `method_exists()` whether any such a method exists - the reverse is not > true.
thumbs-up.gif --Larry Garfield

Tim Düsterhus

296 days ago
Hi On 11/7/25 20:12, Larry Garfield wrote:
> (The counter argument, I suppose, is that this is hardly going to be a super-common routine to call so ergonomics don't matter.)
Yes. I expect this to mostly be useful deep within frameworks or specialized libraries. The type of code where these functions are likely to be used are very likely to be functions with an above-average complexity and having explicit code there will help keep the complexity low. Also it's not like `static::class` is particularly complicated to use. One issue I'm seeing with the “magic context” logic is that the code will suddenly break when the call to `->isReadable()` is moved into a helper function. Particularly when you consider the __get() use case that I mentioned below: Folks that are interested in wanting to learn whether there's a property that is actually readable *or* a magic getter might want to put this combined logic into a helper - and then the implicit scope will no longer work.
> stack-inspection isn't new. `Closure::getCurrent()` is the most recent example, so we don't think it's especially problematic.
The difference is that `Closure::getCurrent()` is a single-purpose function that is explicitly defined to operate on the current scope. It specifically throws an Error when misused. `->isReadable()` OTOH will silently misbehave. AFAICT it would also be the first reflection function that has dynamic behavior.
> If there's a preference for avoiding magic strings, it would be easy enough to use an enum instead. Something like:
My issue is not primarily with the “magic string”, but with the quite significant behavioral difference depending on the parameter value. Best regards Tim Düsterhus

Nicolas Grekas

271 days ago
Le jeu. 6 nov. 2025 à 00:28, Larry Garfield <larry@garfieldtech.com> a écrit :
> In other news, Ilija and I said a year ago that we'd take a swing at > adding isReadable/isWriteable methods to ReflectionProperty. Took a while, > 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 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

Nicolas Grekas

271 days ago
Sorry, typo: I also think the auto-scope is a *not* good idea Le jeu. 4 déc. 2025 à 15:05, Nicolas Grekas <nicolas.grekas+php@gmail.com> a écrit :

Larry Garfield

271 days ago
On Thu, Dec 4, 2025, at 8:05 AM, Nicolas Grekas wrote:
> Le jeu. 6 nov. 2025 à 00:28, Larry Garfield <larry@garfieldtech.com> a écrit : >> In other news, Ilija and I said a year ago that we'd take a swing at adding isReadable/isWriteable methods to ReflectionProperty. Took a while, 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. --Larry Garfield

Nicolas Grekas

271 days ago
Le jeu. 4 déc. 2025 à 17:39, Larry Garfield <larry@garfieldtech.com> a écrit :
> On Thu, Dec 4, 2025, at 8:05 AM, Nicolas Grekas wrote: > > Le jeu. 6 nov. 2025 à 00:28, Larry Garfield <larry@garfieldtech.com> a > écrit : > >> In other news, Ilija and I said a year ago that we'd take a swing at > adding isReadable/isWriteable methods to ReflectionProperty. Took a while, > 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 :)

Larry Garfield

271 days ago
On Thu, Dec 4, 2025, at 10:47 AM, Nicolas Grekas wrote:
> Le jeu. 4 déc. 2025 à 17:39, Larry Garfield <larry@garfieldtech.com> a écrit : >> On Thu, Dec 4, 2025, at 8:05 AM, Nicolas Grekas wrote: >> > Le jeu. 6 nov. 2025 à 00:28, Larry Garfield <larry@garfieldtech.com> a écrit : >> >> In other news, Ilija and I said a year ago that we'd take a swing at adding isReadable/isWriteable methods to ReflectionProperty. Took a while, 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 = []; 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

Nicolas Grekas

271 days ago
Le jeu. 4 déc. 2025 à 18:03, Larry Garfield <larry@garfieldtech.com> a écrit :
> On Thu, Dec 4, 2025, at 10:47 AM, Nicolas Grekas wrote: > > Le jeu. 4 déc. 2025 à 17:39, Larry Garfield <larry@garfieldtech.com> a > écrit : > >> On Thu, Dec 4, 2025, at 8:05 AM, Nicolas Grekas wrote: > >> > Le jeu. 6 nov. 2025 à 00:28, Larry Garfield <larry@garfieldtech.com> > a écrit : > >> >> In other news, Ilija and I said a year ago that we'd take a swing at > adding isReadable/isWriteable methods to ReflectionProperty. Took a while, > 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 = []; > > 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 = stuff(); } } To: class Foo { public int $abc; public function __construct() { unset($this->abc); } public function __get($name) { if ('abc' === $name) { return $this->abc = stuff(); } } }

Bob Weinand

270 days ago
Hey Larry, On 6.11.2025 00:24:52, Larry Garfield wrote:
> In other news, Ilija and I said a year ago that we'd take a swing at adding isReadable/isWriteable methods to ReflectionProperty. Took a while, but here we are. A strangely small RFC from us: > > https://wiki.php.net/rfc/isreadable-iswriteable
Have you considered returning false on isReadable() and isWritable() for methods, whose only statement is throwing? I.e. when a getter or setter unconditionally throws without any other statements present, they are not marked as readable or writable. Otherwise this essentially "punishes" providing better exceptions in a getter or setter, and serves also cases where the LSP inheritance forces presence of a getter/setter, but still shall not be allowed on the specific instance. Thanks, Bob

Larry Garfield

262 days ago
On Thu, Dec 4, 2025, at 2:54 PM, Bob Weinand wrote:
> Hey Larry, > > On 6.11.2025 00:24:52, Larry Garfield wrote: >> In other news, Ilija and I said a year ago that we'd take a swing at adding isReadable/isWriteable methods to ReflectionProperty. Took a while, but here we are. A strangely small RFC from us: >> >> https://wiki.php.net/rfc/isreadable-iswriteable > > > Have you considered returning false on isReadable() and isWritable() for > methods, whose only statement is throwing? I.e. when a getter or setter > unconditionally throws without any other statements present, they are > not marked as readable or writable. > > Otherwise this essentially "punishes" providing better exceptions in a > getter or setter, and serves also cases where the LSP inheritance forces > presence of a getter/setter, but still shall not be allowed on the > specific instance. > > > Thanks, > Bob
Hi Bob. We've discussed it privately, and feel it would be an unprecedented amount of magic behavior to introduce in what is otherwise a fairly small utility RFC. Nowhere else does PHP do that kind of deep runtime introspection, and it's a rabbit hole much larger than we want to tackle. It's also a non-trivial problem to solve. For `throw new Exception();`, the opcodes look something like `V1 = NEW; DO_FCALL; THROW V1;.` That's fairly straight-forward. But what about: * throw new Exception(getErrorMessage()); * throw new Exception(cond() ? 'Message 1' : 'Message 2'); * $message = getErrorMessage(); throw new Exception($message); * if (cond()) { $message = 'Message 1'; } else { $message = 'Message 2'; } throw new Exception($message); It's very hard to draw an arbitrary line to decide what is and what isn't allowed. Handling these cases correctly would require a significant amount of complexity, and would still be incomplete. If making small, seemingly benign changes can break the exception detection, that's arguably worse than no detection at all. For now we'd rather just avoid that rabbit hole. --Larry Garfield

Larry Garfield

258 days ago
On Wed, Nov 5, 2025, at 5:24 PM, Larry Garfield wrote:
> In other news, Ilija and I said a year ago that we'd take a swing at > adding isReadable/isWriteable methods to ReflectionProperty. Took a > while, but here we are. A strangely small RFC from us: > > https://wiki.php.net/rfc/isreadable-iswriteable
A few updates based on the discussion here: * We now account for static properties. (What a concept.) * The `static` magic string is gone. * We have decided on an approach for magic methods. The updated RFC text explains it in more detail, but in short, "if __isset(), then use that to determine readable. Otherwise, __get() implies readable. __set() implies writeable." That should handle the use cases Nicolas was interested in. We consider the RFC feature complete at this point. Baring any further substantive discussion, expect a vote in January after the blackout period ends. --Larry Garfield

Tim Düsterhus

258 days ago
Hi Am 2025-12-17 16:26, schrieb Larry Garfield:
> * We have decided on an approach for magic methods. The updated RFC > text explains it in more detail, but in short, "if __isset(), then use > that to determine readable. Otherwise, __get() implies readable. > __set() implies writeable." That should handle the use cases Nicolas > was interested in.
That works for me. I didn't feel particularly strongly either way.
> We consider the RFC feature complete at this point. Baring any further > substantive discussion, expect a vote in January after the blackout > period ends.
I don't have further comments about the semantics themselves, but have one further clarification question:
> The property has not been unset(). If it has, follow the same __isset > check as above
Should this read “the same __get check” instead? And one note with regard to process: Don't forget to add a link to the discussion (https://news-web.php.net/php.internals/129101) to the RFC. Best regards Tim Düsterhus

Larry Garfield

257 days ago
On Wed, Dec 17, 2025, at 12:02 PM, Tim Düsterhus wrote:
> Hi > > Am 2025-12-17 16:26, schrieb Larry Garfield: >> * We have decided on an approach for magic methods. The updated RFC >> text explains it in more detail, but in short, "if __isset(), then use >> that to determine readable. Otherwise, __get() implies readable. >> __set() implies writeable." That should handle the use cases Nicolas >> was interested in. > > That works for me. I didn't feel particularly strongly either way. > >> We consider the RFC feature complete at this point. Baring any further >> substantive discussion, expect a vote in January after the blackout >> period ends. > > I don't have further comments about the semantics themselves, but have > one further clarification question: > >> The property has not been unset(). If it has, follow the same __isset >> check as above > > Should this read “the same __get check” instead?
Hm, yes, you are correct. Updated.
> And one note with regard to process: Don't forget to add a link to the > discussion (https://news-web.php.net/php.internals/129101) to the RFC.
Added. Oh, and one other note: It turns out that in English, both "writeable" and "writable" are nominally valid. The latter seems more common (and my spellchecker only recognizing the latter), so we've standardized on the non-E version throughout the RFC. (The code already was.) --Larry Garfield

Tim Düsterhus

257 days ago
Hi Am 2025-12-17 20:48, schrieb Larry Garfield:
> Oh, and one other note: It turns out that in English, both "writeable" > and "writable" are nominally valid. The latter seems more common (and > my spellchecker only recognizing the latter), so we've standardized on > the non-E version throughout the RFC. (The code already was.)
As a non-native speaker, I confirm that “writable” without the “e” is what looks more familiar to me. It's also consistent with https://www.php.net/manual/en/function.is-writable.php (although that one has an alias https://www.php.net/manual/en/function.is-writeable.php - but since the one with the “e” is the alias, it is the less preferable variant). Best regards Tim Düsterhus

Nicolas Grekas

257 days ago
Le mer. 17 déc. 2025 à 16:29, Larry Garfield <larry@garfieldtech.com> a écrit :
> On Wed, Nov 5, 2025, at 5:24 PM, Larry Garfield wrote: > > In other news, Ilija and I said a year ago that we'd take a swing at > > adding isReadable/isWriteable methods to ReflectionProperty. Took a > > while, but here we are. A strangely small RFC from us: > > > > https://wiki.php.net/rfc/isreadable-iswriteable > > A few updates based on the discussion here: > > * We now account for static properties. (What a concept.) > * The `static` magic string is gone. > * We have decided on an approach for magic methods. The updated RFC text > explains it in more detail, but in short, "if __isset(), then use that to > determine readable. Otherwise, __get() implies readable. __set() implies > writeable." That should handle the use cases Nicolas was interested in. > > We consider the RFC feature complete at this point. Baring any further > substantive discussion, expect a vote in January after the blackout period > ends. >
Hi, thanks for the update! I read the updated description and that looks great to me, thanks. Nicolas

Larry Garfield

230 days ago
On Wed, Nov 5, 2025, at 5:24 PM, Larry Garfield wrote:
> In other news, Ilija and I said a year ago that we'd take a swing at > adding isReadable/isWriteable methods to ReflectionProperty. Took a > while, but here we are. A strangely small RFC from us: > > https://wiki.php.net/rfc/isreadable-iswriteable
Hi folks. The holiday blackout period is over, and there's nothing else really to discuss on this PR, so consider this an Intent to Vote notice for the isReadable RFC. I'll call the vote later this week, baring any new serious constructive feedback. --Larry Garfield

Claude Pache

229 days ago
> Le 13 janv. 2026 à 22:30, Larry Garfield <larry@garfieldtech.com> a écrit : > > On Wed, Nov 5, 2025, at 5:24 PM, Larry Garfield wrote: >> In other news, Ilija and I said a year ago that we'd take a swing at >> adding isReadable/isWriteable methods to ReflectionProperty. Took a >> while, but here we are. A strangely small RFC from us: >> >> https://wiki.php.net/rfc/isreadable-iswriteable > > Hi folks. > > The holiday blackout period is over, and there's nothing else really to discuss on this PR, so consider this an Intent to Vote notice for the isReadable RFC. > > I'll call the vote later this week, baring any new serious constructive feedback. > > --Larry Garfield
Hi, The RFC says:
> To use “my current scope,” the static::class construct is an easy way to specify “whatever class this code is running in.”
The code is running in `self::class` or `__CLASS__`, not in `static::class`. ------ As noted in the RFC, `isReadable()` will give unavoidable false-positives (returning `true` although attempt to read the property will error). But there is also a false-negative: ```php class C { function __construct( readonly private mixed $foo ) { } function __get($x) { if ($x === 'foo') { return $this->foo; } throw new Error('Undefined property '.$x); } function __isset($x) { if ($x === 'foo') return isset($this->foo); // not `true`, otherwise `isset(new C(null)->foo)` will return an incorrect result. } return false; } } $c = new C(null); // will return false, although it is readable var_dump(new ReflectionProperty($c, 'foo')->isReadable(null, $c)); ``` One could skip the `__isset()` check in order to avoid the false-negative, at the cost of more false-positives. I don’t know what is best, because I tend to avoid `__get()` like the plague anyway. —Claude

Larry Garfield

228 days ago
On Wed, Jan 14, 2026, at 2:00 PM, Claude Pache wrote:
>> Le 13 janv. 2026 à 22:30, Larry Garfield <larry@garfieldtech.com> a écrit : >> >> On Wed, Nov 5, 2025, at 5:24 PM, Larry Garfield wrote: >>> In other news, Ilija and I said a year ago that we'd take a swing at >>> adding isReadable/isWriteable methods to ReflectionProperty. Took a >>> while, but here we are. A strangely small RFC from us: >>> >>> https://wiki.php.net/rfc/isreadable-iswriteable >> >> Hi folks. >> >> The holiday blackout period is over, and there's nothing else really to discuss on this PR, so consider this an Intent to Vote notice for the isReadable RFC. >> >> I'll call the vote later this week, baring any new serious constructive feedback. >> >> --Larry Garfield > > Hi, > > The RFC says: > >> To use “my current scope,” the `static::class` construct is an easy way to specify “whatever class this code is running in.” > > The code is running in `self::class` or `__CLASS__`, not in `static::class`.
Hm, good point. I've changed to to `self::class`, which I believe should only be an Editorial change. (There's no change to the design, just to the explanation, and it's arguably a typo.) I'll give it another day before opening the vote just in case.
> As noted in the RFC, `isReadable()` will give unavoidable > false-positives (returning `true` although attempt to read the property > will error). But there is also a false-negative: > > ```php > class C { > > function __construct( > readonly private mixed $foo > ) { } > > function __get($x) { > if ($x === 'foo') { > return $this->foo; > } > throw new Error('Undefined property '.$x); > } > > function __isset($x) { > if ($x === 'foo') > return isset($this->foo); // not `true`, otherwise > `isset(new C(null)->foo)` will return an incorrect result. > } > return false; > } > } > > $c = new C(null); > > // will return false, although it is readable > var_dump(new ReflectionProperty($c, 'foo')->isReadable(null, $c)); > ``` > > One could skip the `__isset()` check in order to avoid the > false-negative, at the cost of more false-positives. I don’t know what > is best, because I tend to avoid `__get()` like the plague anyway.
As discussed earlier in the thread and noted in the RFC, as long as hooks and __get support arbitrary code, we can never guarantee no false positives or negatives. Based on the earlier discussion, the current setup seems like the best balance for the expected typical cases. So we'd rather stick with how it is now. --Larry Garfield