[RFC] Property accessors

php.internals

Nikita Popov

5 years ago
Hi internals, I'd like to present an RFC for property accessors: https://wiki.php.net/rfc/property_accessors Property accessors are like __get() and __set(), but for a single property. They also support read-only properties and properties with asymmetric visibility (public read, private write) as a side-effect. The proposal is modeled after C#-style accessors (also used by Swift), and syntactically similar to the previous https://wiki.php.net/rfc/propertygetsetsyntax-v1.2 proposal. While I put a lot of effort into both the proposal and the implementation, I've grown increasingly uncertain that this is the right direction for us to take. The proposal turned out to be significantly more complex than I originally anticipated (despite reducing the scope to only "get" and "set" accessors), and I'm sure there are some interactions I still haven't accounted for. I'm not convinced the value justifies the complexity. So, while I'm putting this up for discussion, it may be that I will not pursue landing it. I think a lot of the practical value of this accessors proposal would be captured by support for read-only (and/or private-write) properties. This has been discussed (and declined) in the past, but probably should be revisited. Regards, Nikita

Joe Watkins

5 years ago
I haven't read it properly yet (been watching a little), but I just wanted to say thanks for the refreshing honesty :) Cheers Joe On Tue, 4 May 2021 at 12:34, Nikita Popov <nikita.ppv@gmail.com> wrote:

Marco Pivetta

5 years ago
Hey NikiC, On Tue, May 4, 2021, 12:34 Nikita Popov <nikita.ppv@gmail.com> wrote:
> Hi internals, > > I'd like to present an RFC for property accessors: > https://wiki.php.net/rfc/property_accessors > > Property accessors are like __get() and __set(), but for a single property. > They also support read-only properties and properties with asymmetric > visibility (public read, private write) as a side-effect. > > The proposal is modeled after C#-style accessors (also used by Swift), and > syntactically similar to the previous > https://wiki.php.net/rfc/propertygetsetsyntax-v1.2 proposal. > > While I put a lot of effort into both the proposal and the implementation, > I've grown increasingly uncertain that this is the right direction for us > to take. The proposal turned out to be significantly more complex than I > originally anticipated (despite reducing the scope to only "get" and "set" > accessors), and I'm sure there are some interactions I still haven't > accounted for. I'm not convinced the value justifies the complexity. > > So, while I'm putting this up for discussion, it may be that I will not > pursue landing it. I think a lot of the practical value of this accessors > proposal would be captured by support for read-only (and/or private-write) > properties. This has been discussed (and declined) in the past, but > probably should be revisited. >
I've skimmed the RFC: it will take a lot of testing to see how much this impacts BC, but potentially a lot. A few things that came up so far: * instead of allowing by-ref `get` declaration, can we just kill it here, before it breeds again? I don't think I need to explain the woes of by-ref to internals, but removing the ability to declare new accessors by-ref would be a huge win for the engine and the language long-term. * what does an array cast of an object with accessors look like? I assume only properties backed by storage will appear? (Yes, the array cast is still the simplest/most useful pure API to inspect object state 😁) * what is the design decisions around same-visibility declarations causing compile errors in inheritance scenarios? Those would make BC unnecessarily complex, if a parent type declares a new accessor with the same name: variance is understandable, but same visibility errors seem a bit too much As for the rest: it needs more careful review. So far, good work!

Nikita Popov

5 years ago
On Tue, May 4, 2021 at 12:58 PM Marco Pivetta <ocramius@gmail.com> wrote:
> Hey NikiC, > > On Tue, May 4, 2021, 12:34 Nikita Popov <nikita.ppv@gmail.com> wrote: > >> Hi internals, >> >> I'd like to present an RFC for property accessors: >> https://wiki.php.net/rfc/property_accessors >> >> Property accessors are like __get() and __set(), but for a single >> property. >> They also support read-only properties and properties with asymmetric >> visibility (public read, private write) as a side-effect. >> >> The proposal is modeled after C#-style accessors (also used by Swift), and >> syntactically similar to the previous >> https://wiki.php.net/rfc/propertygetsetsyntax-v1.2 proposal. >> >> While I put a lot of effort into both the proposal and the implementation, >> I've grown increasingly uncertain that this is the right direction for us >> to take. The proposal turned out to be significantly more complex than I >> originally anticipated (despite reducing the scope to only "get" and "set" >> accessors), and I'm sure there are some interactions I still haven't >> accounted for. I'm not convinced the value justifies the complexity. >> >> So, while I'm putting this up for discussion, it may be that I will not >> pursue landing it. I think a lot of the practical value of this accessors >> proposal would be captured by support for read-only (and/or private-write) >> properties. This has been discussed (and declined) in the past, but >> probably should be revisited. >> > > I've skimmed the RFC: it will take a lot of testing to see how much this > impacts BC, but potentially a lot. > > A few things that came up so far: > > * instead of allowing by-ref `get` declaration, can we just kill it here, > before it breeds again? I don't think I need to explain the woes of by-ref > to internals, but removing the ability to declare new accessors by-ref > would be a huge win for the engine and the language long-term. >
The primary functionality by-ref get is needed for are operations on arrays, such as $foo->bar[] = $val. This probably isn't particularly important for explicit accessors, but may be a non-trivial limitation for implicit ones. For example, you wouldn't be able to have a "public get, private set" on an array property, for all practical purposes. Of course, we could allow that to work fine for implicit accessors, without any by-value vs by-reference get distinction. Would probably open up questions regarding compatibility during inheritance though. Of course, I am generally sympathetic towards killing references with fire :) * what does an array cast of an object with accessors look like? I assume
> only properties backed by storage will appear? (Yes, the array cast is > still the simplest/most useful pure API to inspect object state 😁) >
That's correct. This is mentioned in https://wiki.php.net/rfc/property_accessors#var_dump_array_cast_foreach_etc (I've renamed the section to make it clearer.) * what is the design decisions around same-visibility declarations causing
> compile errors in inheritance scenarios? Those would make BC unnecessarily > complex, if a parent type declares a new accessor with the same name: > variance is understandable, but same visibility errors seem a bit too much >
I'm not sure which error you're referring to here. Could you share an example (or point me to the example in the RFC)? Regards, Nikita

Marco Pivetta

5 years ago
Hey NikiC, <http://ocramius.github.com/> On Tue, May 4, 2021 at 4:21 PM Nikita Popov <nikita.ppv@gmail.com> wrote:
> On Tue, May 4, 2021 at 12:58 PM Marco Pivetta <ocramius@gmail.com> wrote: > >> Hey NikiC, >> >> On Tue, May 4, 2021, 12:34 Nikita Popov <nikita.ppv@gmail.com> wrote: >> >>> Hi internals, >>> >>> I'd like to present an RFC for property accessors: >>> https://wiki.php.net/rfc/property_accessors >>> >>> Property accessors are like __get() and __set(), but for a single >>> property. >>> They also support read-only properties and properties with asymmetric >>> visibility (public read, private write) as a side-effect. >>> >>> The proposal is modeled after C#-style accessors (also used by Swift), >>> and >>> syntactically similar to the previous >>> https://wiki.php.net/rfc/propertygetsetsyntax-v1.2 proposal. >>> >>> While I put a lot of effort into both the proposal and the >>> implementation, >>> I've grown increasingly uncertain that this is the right direction for us >>> to take. The proposal turned out to be significantly more complex than I >>> originally anticipated (despite reducing the scope to only "get" and >>> "set" >>> accessors), and I'm sure there are some interactions I still haven't >>> accounted for. I'm not convinced the value justifies the complexity. >>> >>> So, while I'm putting this up for discussion, it may be that I will not >>> pursue landing it. I think a lot of the practical value of this accessors >>> proposal would be captured by support for read-only (and/or >>> private-write) >>> properties. This has been discussed (and declined) in the past, but >>> probably should be revisited. >>> >> >> I've skimmed the RFC: it will take a lot of testing to see how much this >> impacts BC, but potentially a lot. >> >> A few things that came up so far: >> >> * instead of allowing by-ref `get` declaration, can we just kill it >> here, before it breeds again? I don't think I need to explain the woes of >> by-ref to internals, but removing the ability to declare new accessors >> by-ref would be a huge win for the engine and the language long-term. >> > > The primary functionality by-ref get is needed for are operations on > arrays, such as $foo->bar[] = $val. This probably isn't particularly > important for explicit accessors, but may be a non-trivial limitation for > implicit ones. For example, you wouldn't be able to have a "public get, > private set" on an array property, for all practical purposes. Of course, > we could allow that to work fine for implicit accessors, without any > by-value vs by-reference get distinction. Would probably open up questions > regarding compatibility during inheritance though. > > Of course, I am generally sympathetic towards killing references with fire > :) >
I'd strongly advise killing by-ref array push there: it's an acceptable limitation, for the amount of benefit we get :P In fact, people doing `__get` now are already familiar with "Indirect modification of overloaded property" (https://3v4l.org/6dTXK) As for use-cases around using by-ref, it is true that some of my libraries use by-ref to shadow/override object properties, but I'd rather kill the library than have by-ref proliferation.
> * what does an array cast of an object with accessors look like? I assume >> only properties backed by storage will appear? (Yes, the array cast is >> still the simplest/most useful pure API to inspect object state 😁) >> > > That's correct. This is mentioned in > https://wiki.php.net/rfc/property_accessors#var_dump_array_cast_foreach_etc > (I've renamed the section to make it clearer.) >
Thanks! Perhaps I missed it :-)
> * what is the design decisions around same-visibility declarations >> causing compile errors in inheritance scenarios? Those would make BC >> unnecessarily complex, if a parent type declares a new accessor with the >> same name: variance is understandable, but same visibility errors seem a >> bit too much >> > > I'm not sure which error you're referring to here. Could you share an > example (or point me to the example in the RFC)? >
From this example: class Test { // Illegal: "public get" has higher visibility than "private $prop". private string $prop { public get; set; } // Illegal: "public get" has same visibility as "public $prop". // This visibility modifier is redundant and must be omitted. public string $prop { public get; private set; }} I'd perhaps mis-interpreted the error? Why is `public get` illegal? Also, is the example missing inheritance? Marco Pivetta http://twitter.com/Ocramius http://ocramius.github.com/

Robert Korulczyk

5 years ago
W dniu 04.05.2021 o 18:32, Marco Pivetta pisze:
> I'd strongly advise killing by-ref array push there: it's an acceptable > limitation, for the amount of benefit we get :P > In fact, people doing `__get` now are already familiar with "Indirect > modification of overloaded property" (https://3v4l.org/6dTXK)
They are familiar, but this is not a reason to cripple property accessors concept with the same limitation as `__get()`. "Indirect modification" is really annoying, and using reference to bypass it looks more like a dirty hack than real solution. If we can avoid "Indirect modification" for implicit accessors without involving references, then it is definitely worth it. And this is important for explicit accessors too - in my case like 90% virtual properties are some kind of conversion between string and array, where getter returns array generated from string. It would be great to handle this too, even if it will be only syntactic sugar, where `$object->property['key'] = 'value';` will be equivalent of this dance: $temp = $object->property; $temp['key'] = 'value'; $object->property = $temp; Regards, Robert Korulczyk

Dik Takken

5 years ago
On 04-05-2021 12:57, Marco Pivetta wrote:
> * instead of allowing by-ref `get` declaration, can we just kill it here, > before it breeds again? I don't think I need to explain the woes of by-ref > to internals, but removing the ability to declare new accessors by-ref > would be a huge win for the engine and the language long-term.
Would killing it imply that the following example from the RFC: $test->prop[] = 42; behaves differently depending on 'prop' being either a regular class property or a property with associated get accessor? Regards, Dik Takken

Olle Härstedt

5 years ago
2021-05-04 12:33 GMT+02:00, Nikita Popov <nikita.ppv@gmail.com>:
> Hi internals, > > I'd like to present an RFC for property accessors: > https://wiki.php.net/rfc/property_accessors > > Property accessors are like __get() and __set(), but for a single property. > They also support read-only properties and properties with asymmetric > visibility (public read, private write) as a side-effect. > > The proposal is modeled after C#-style accessors (also used by Swift), and > syntactically similar to the previous > https://wiki.php.net/rfc/propertygetsetsyntax-v1.2 proposal. > > While I put a lot of effort into both the proposal and the implementation, > I've grown increasingly uncertain that this is the right direction for us > to take. The proposal turned out to be significantly more complex than I > originally anticipated (despite reducing the scope to only "get" and "set" > accessors), and I'm sure there are some interactions I still haven't > accounted for. I'm not convinced the value justifies the complexity. > > So, while I'm putting this up for discussion, it may be that I will not > pursue landing it. I think a lot of the practical value of this accessors > proposal would be captured by support for read-only (and/or private-write) > properties. This has been discussed (and declined) in the past, but > probably should be revisited. > > Regards, > Nikita >
Hi, In general I'm no fan of trivial getters and setters at all in OOP. I think a better solution is provided by: * readonly properties (or write-once, in the constructor) * namespace- or package-internal accessing; "internal" as an alternative to public/private Especially when getters and setters do not upheld any particular invariants or check validation. Note that namespace-internal access cannot be provided by getters and setters (though technically it's a big and hard change to PHP, AFAIK). Olle

Olle Härstedt

5 years ago
2021-05-04 15:57 GMT+02:00, Olle Härstedt <olleharstedt@gmail.com>:
> 2021-05-04 12:33 GMT+02:00, Nikita Popov <nikita.ppv@gmail.com>: >> Hi internals, >> >> I'd like to present an RFC for property accessors: >> https://wiki.php.net/rfc/property_accessors >> >> Property accessors are like __get() and __set(), but for a single >> property. >> They also support read-only properties and properties with asymmetric >> visibility (public read, private write) as a side-effect. >> >> The proposal is modeled after C#-style accessors (also used by Swift), >> and >> syntactically similar to the previous >> https://wiki.php.net/rfc/propertygetsetsyntax-v1.2 proposal. >> >> While I put a lot of effort into both the proposal and the >> implementation, >> I've grown increasingly uncertain that this is the right direction for us >> to take. The proposal turned out to be significantly more complex than I >> originally anticipated (despite reducing the scope to only "get" and >> "set" >> accessors), and I'm sure there are some interactions I still haven't >> accounted for. I'm not convinced the value justifies the complexity. >> >> So, while I'm putting this up for discussion, it may be that I will not >> pursue landing it. I think a lot of the practical value of this accessors >> proposal would be captured by support for read-only (and/or >> private-write) >> properties. This has been discussed (and declined) in the past, but >> probably should be revisited. >> >> Regards, >> Nikita >> > > Hi, > > In general I'm no fan of trivial getters and setters at all in OOP. I > think a better solution is provided by: > > * readonly properties (or write-once, in the constructor) > * namespace- or package-internal accessing; "internal" as an > alternative to public/private > > Especially when getters and setters do not upheld any particular > invariants or check validation. > > Note that namespace-internal access cannot be provided by getters and > setters (though technically it's a big and hard change to PHP, AFAIK). > > Olle
Or maybe I shouldn't be a complete idiot and actually carefully read the RFC before any knee-jerk reaction. Disregard. Olle

Larry Garfield

5 years ago
On Tue, May 4, 2021, at 5:33 AM, Nikita Popov wrote:
> Hi internals, > > I'd like to present an RFC for property accessors: > https://wiki.php.net/rfc/property_accessors > > Property accessors are like __get() and __set(), but for a single property. > They also support read-only properties and properties with asymmetric > visibility (public read, private write) as a side-effect. > > The proposal is modeled after C#-style accessors (also used by Swift), and > syntactically similar to the previous > https://wiki.php.net/rfc/propertygetsetsyntax-v1.2 proposal. > > While I put a lot of effort into both the proposal and the implementation, > I've grown increasingly uncertain that this is the right direction for us > to take. The proposal turned out to be significantly more complex than I > originally anticipated (despite reducing the scope to only "get" and "set" > accessors), and I'm sure there are some interactions I still haven't > accounted for. I'm not convinced the value justifies the complexity. > > So, while I'm putting this up for discussion, it may be that I will not > pursue landing it. I think a lot of the practical value of this accessors > proposal would be captured by support for read-only (and/or private-write) > properties. This has been discussed (and declined) in the past, but > probably should be revisited. > > Regards, > Nikita
This is an amazingly detailed RFC, and I love most of it. Thank you, Nikita! Regarding complexity, can you elaborate on what the most complex/tricky/problematic parts are? I'm mainly wondering if there are any parts that could be changed/slightly scaled back that would reduce the complexity more than it reduces capability. (Eg, removing guard and lazy for now is a good call, IMO, since both can be emulated with the other two.) All else equal, though, I would favor including all of it. I would say that the visibility controls get us 70% of the benefit, not 80/90%, but I do agree that those are hugely beneficial in and of themselves. *IF* you decide to scale it back, I would strongly recommend simply dropping the explicit accessors support and leaving the rest of the syntax the same. That way we know it's forward-compatible should we decide in the future to re-introduce explicit accessors. Some other questions: 1. Do setters have arbitrary access to the object? Can they read/set arbitrary other values? I'm thinking of something like this: class Person { private string $firstName; private string $lastName; private string $nickname; private int $age; public string $fullName { get { return "$this->firstName $this->lastName"; } set($fullName) { if ($this->age > 50) throw new Exception('You are too old to change your name.'); [$this->firstName, $this->lastName] = explode(' ', $fullName); $this->nickname = substr(0, 5, $this->firstName); } } } (A contrived example, obviously.) 2. My knee-jerk thought is to agree with Marco and avoid references entirely, for the sake of everyone's sanity. However, it is implied that &get is the only way to properly handle array property accessors. Am I understanding that correctly? If not, can you expand on array handling? I'd happily jettison references if arrays can still be supported nicely without them. 3. The partial incompatibility with constructor promotion is understandable, but disappointing. Is it at all possible to modify the promotion logic such that if a property is already defined with accessors, you can still promote it without a syntax error? I am thinking of this case: class Test { private int _$foo; public int $foo { get { return $this->_foo; } set ($foo) { if ($foo < 0) throw new InvalidArgumentException('Must be positive.'); $this->_foo = $foo; } } public function __construct(public int $foo) {} } (Though a guard would be nicer, as it avoids the second variable, but there are other considerations there.) 4. I still don't love $value being a magic name in setters. Being able to specify it explicitly is nice, and I would probably always use that myself (and push for it in coding standards), but would it be feasible to default it instead to the name of the variable? Since that variable name cannot be a backing variable, we know that it won't conflict with anything, but it would be more self-documenting. Thanks again, and I do hope you can be convinced all this effort is worth bringing to a vote. :-) --Larry Garfield

Olle Härstedt

5 years ago
2021-05-04 12:33 GMT+02:00, Nikita Popov <nikita.ppv@gmail.com>:
> Hi internals, > > I'd like to present an RFC for property accessors: > https://wiki.php.net/rfc/property_accessors > > Property accessors are like __get() and __set(), but for a single property. > They also support read-only properties and properties with asymmetric > visibility (public read, private write) as a side-effect. > > The proposal is modeled after C#-style accessors (also used by Swift), and > syntactically similar to the previous > https://wiki.php.net/rfc/propertygetsetsyntax-v1.2 proposal. > > While I put a lot of effort into both the proposal and the implementation, > I've grown increasingly uncertain that this is the right direction for us > to take. The proposal turned out to be significantly more complex than I > originally anticipated (despite reducing the scope to only "get" and "set" > accessors), and I'm sure there are some interactions I still haven't > accounted for. I'm not convinced the value justifies the complexity. > > So, while I'm putting this up for discussion, it may be that I will not > pursue landing it. I think a lot of the practical value of this accessors > proposal would be captured by support for read-only (and/or private-write) > properties. This has been discussed (and declined) in the past, but > probably should be revisited. > > Regards, > Nikita >
Is this a typo? get() {} // Must not have parameter list But there are no parameters...? Olle

Dik Takken

5 years ago
On 04-05-2021 12:33, Nikita Popov wrote:
> Hi internals, > > I'd like to present an RFC for property accessors: > https://wiki.php.net/rfc/property_accessors
Wow. Thanks for all the effort you put into this!
> While I put a lot of effort into both the proposal and the implementation, > I've grown increasingly uncertain that this is the right direction for us > to take. The proposal turned out to be significantly more complex than I > originally anticipated (despite reducing the scope to only "get" and "set" > accessors), and I'm sure there are some interactions I still haven't > accounted for. I'm not convinced the value justifies the complexity.
I think property accessors could be a huge enhancement to the language and may significantly change the look of PHP code in the long run. To fully appreciate what property accessors could do to PHP it may be useful to compare PHP to other languages that already have property accessors. In my case, I use both PHP and Python. By comparing how I use these two languages I can attempt to project how property accessors may change the way I use PHP. When I compare how I design APIs in PHP and Python, I expect to be exposing more public properties and fewer class methods. That will result in less library code. When I compare how I use APIs in PHP versus Python, I expect to be doing more direct property accessing and less method calling. That will make code look less cluttered in general. The complexity may very well be worth it when fully considering the impact it could have on how the language is used. Regards, Dik Takken

Matthew Brown

5 years ago
On Tue, 4 May 2021 at 06:34, Nikita Popov <nikita.ppv@gmail.com> wrote:
> Hi internals, > > I'd like to present an RFC for property accessors: > https://wiki.php.net/rfc/property_accessors > > Property accessors are like __get() and __set(), but for a single property. > They also support read-only properties and properties with asymmetric > visibility (public read, private write) as a side-effect. > > The proposal is modeled after C#-style accessors (also used by Swift), and > syntactically similar to the previous > https://wiki.php.net/rfc/propertygetsetsyntax-v1.2 proposal. > > While I put a lot of effort into both the proposal and the implementation, > I've grown increasingly uncertain that this is the right direction for us > to take. The proposal turned out to be significantly more complex than I > originally anticipated (despite reducing the scope to only "get" and "set" > accessors), and I'm sure there are some interactions I still haven't > accounted for. I'm not convinced the value justifies the complexity. > > So, while I'm putting this up for discussion, it may be that I will not > pursue landing it. I think a lot of the practical value of this accessors > proposal would be captured by support for read-only (and/or private-write) > properties. This has been discussed (and declined) in the past, but > probably should be revisited. > > Regards, > Nikita >
I don't have a vote, but I've worked on a few ActiveRecord-style ORMs in PHP, and this is the sort of feature that would make me want to rewrite everything to take advantage of it. I've used property accessors in C# and really appreciated them. The 20% increase in performance over magic getters and setters is a nice bonus. Allowing the creation of engine-enforced private-set properties is another bonus, even though I'm already able to enforce that in my projects via static analysis. Best wishes, Matt

Larry Garfield

5 years ago
On Tue, May 4, 2021, at 5:33 AM, Nikita Popov wrote:
> Hi internals, > > I'd like to present an RFC for property accessors: > https://wiki.php.net/rfc/property_accessors > > Property accessors are like __get() and __set(), but for a single property. > They also support read-only properties and properties with asymmetric > visibility (public read, private write) as a side-effect. > > The proposal is modeled after C#-style accessors (also used by Swift), and > syntactically similar to the previous > https://wiki.php.net/rfc/propertygetsetsyntax-v1.2 proposal. > > While I put a lot of effort into both the proposal and the implementation, > I've grown increasingly uncertain that this is the right direction for us > to take. The proposal turned out to be significantly more complex than I > originally anticipated (despite reducing the scope to only "get" and "set" > accessors), and I'm sure there are some interactions I still haven't > accounted for. I'm not convinced the value justifies the complexity. > > So, while I'm putting this up for discussion, it may be that I will not > pursue landing it. I think a lot of the practical value of this accessors > proposal would be captured by support for read-only (and/or private-write) > properties. This has been discussed (and declined) in the past, but > probably should be revisited. > > Regards, > Nikita
Another question: I skimmed through the PR and its tests, and I didn't see any tests around attributes. How do you envision attributes interacting with accessor-using properties? I suppose there's no change for implicit accessors, but what happens for explicit accessors? --Larry Garfield

Hendra Gunawan

5 years ago
Hi internals, I am new here. Let me make a suggestion for this one of mostly asked feature: class MyOldOrdinaryObject { public string $prop1 { get use getProp1; set use setProp1; } public string $prop2 { get use prefixProp2; set use prop2Sufix; } // pre existing methods // same function signature with corresponding accessor // method name is irrelevant public function getProp1(): string {/* ... */} public function setProp1(string $val): void {/* ... */} public function prefixProp2(): string {/* ... */} public function prop2Sufix(string $val): void {/* ... */} } This way: * without forcing them to use the new ones, users can choose whether to use old ones or new ones. * code duplication can be prevented, if we decided to preserve the old ones. * the accessors are more tidy and readable, if we decided to move out all multiline accessors. As far as I understand, the difference between "set" and "guard" is: with "set", we have freedom and responsibility to allocate a space. Additionally, we have to choose whether to use "set" or "guard", not both. It is a sad decision that "guard" has to be eliminated to reduce complexity. In my opinion, it is valuable that we can write code more concise than before: class MyOldOrdinaryObject { public string $prop1 { get; guard use commonGuard; } public string $prop2 { get; guard use commonGuard; } // Assuming that prop1 & prop2 have the same validity rules. // The visibility is private in order to prevent users accessing it. // Due to loss of space allocation and difference of function signature, // this method cannot be used in concert with "set". private function commonGuard(): void {/* ... */} } With this capability, the complex accessor in constructor problem can be solved: class MyValueObject { public function __construct( public string $prop1 { get; private guard use guard1; } public string $prop2 { get; private guard use guard2; } public string $prop3 { get; private guard use commonGuard; } public string $prop4 { get; private guard use commonGuard; } ){} private function guard1(): void {/* ... */} private function guard2(): void {/* ... */} private function commonGuard(): void {/* ... */} } I hope that "guard" can be included again. I don't understand the internals of PHP VM. I think the mechanism of this is compiler assisted copy-paste (same as traits), but only the function body and the visibility is overridden based on accessors definition. Regards, Hendra Gunawan. On Sat, May 8, 2021 at 5:16 AM Larry Garfield <larry@garfieldtech.com> wrote:

Mike Schinkel

5 years ago
> On May 4, 2021, at 6:33 AM, Nikita Popov <nikita.ppv@gmail.com> wrote: > > Hi internals, > > I'd like to present an RFC for property accessors: > https://wiki.php.net/rfc/property_accessors > > Property accessors are like __get() and __set(), but for a single property. > They also support read-only properties and properties with asymmetric > visibility (public read, private write) as a side-effect. > > The proposal is modeled after C#-style accessors (also used by Swift), and > syntactically similar to the previous > https://wiki.php.net/rfc/propertygetsetsyntax-v1.2 proposal. > > While I put a lot of effort into both the proposal and the implementation, > I've grown increasingly uncertain that this is the right direction for us > to take. The proposal turned out to be significantly more complex than I > originally anticipated (despite reducing the scope to only "get" and "set" > accessors), and I'm sure there are some interactions I still haven't > accounted for. I'm not convinced the value justifies the complexity.
This is an amazingly comprehensive proposal and I commend you for all the effort.
> So, while I'm putting this up for discussion, it may be that I will not > pursue landing it. I think a lot of the practical value of this accessors > proposal would be captured by support for read-only (and/or private-write) > properties. This has been discussed (and declined) in the past, but > probably should be revisited.
Adding property accessors to PHP could significantly improve robustness in userland code. The KEY benefit is how userland classes could evolve in complexity as required *without* breaking a classes' API. That benefit cannot be overstated IMO. If this proposal needs to change, I hope you continue to ensure it can provide zero breakage during evolution of userland code. -Mike P.S. I also concur with Larry Garfield and am uncomfortable with the magic `$value` variable. I would prefer to always be explicitly specified in parens on — e.g. `set($var)` — if it needs to be used in the RHS of an assignment inside the set block. But this is a trivial concern compared to the KEY benefit mentioned above.

Trevor Rowbotham

5 years ago
‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ On Tuesday, May 4th, 2021 at 6:33 AM, Nikita Popov nikita.ppv@gmail.com wrote:
> Hi internals, > > I'd like to present an RFC for property accessors: > > https://wiki.php.net/rfc/property_accessors > > Property accessors are like __get() and __set(), but for a single property. > > They also support read-only properties and properties with asymmetric > > visibility (public read, private write) as a side-effect. > > The proposal is modeled after C#-style accessors (also used by Swift), and > > syntactically similar to the previous > > https://wiki.php.net/rfc/propertygetsetsyntax-v1.2 proposal. > > While I put a lot of effort into both the proposal and the implementation, > > I've grown increasingly uncertain that this is the right direction for us > > to take. The proposal turned out to be significantly more complex than I > > originally anticipated (despite reducing the scope to only "get" and "set" > > accessors), and I'm sure there are some interactions I still haven't > > accounted for. I'm not convinced the value justifies the complexity. > > So, while I'm putting this up for discussion, it may be that I will not > > pursue landing it. I think a lot of the practical value of this accessors > > proposal would be captured by support for read-only (and/or private-write) > > properties. This has been discussed (and declined) in the past, but > > probably should be revisited. > > Regards, > > Nikita
Hi, Thank you for the effort put forth in this RFC. I have a few questions after having read it. Will these properties work with the property_exists() function? I don't see it mentioned in the RFC, and seeing as how the function does not work with properties defined in __get() and __set(), the answer to this isn't obvious to me. The RFC also mentions that calling isset() on a write-only property will throw an Error exception. Should a new function along the lines of property_is_readable(), which returns true if the property is readable in the current scope, (and possibly its mirror function property_is_writable()) be introduced? Going through the Reflection API feels overly verbose and error prone to find out if a property is readable/writable. - Trevor

Hendra Gunawan

5 years ago
Hi internals,
> > I'd like to present an RFC for property accessors: > > https://wiki.php.net/rfc/property_accessors
Hi internals, I am new here. Thank you Nikita for this wonderful proposal. A few days ago, I sent an identical message to this thread but I am not sure it was sent properly. So I sent it back here. Sorry about this. Let me make a suggestion for this one of mostly asked feature: class MyOldOrdinaryObject { public string $prop1 { get use getProp1; set use setProp1; } public string $prop2 { get use prefixProp2; set use prop2Sufix; } // pre existing methods // same function signature with corresponding accessor // method name is irrelevant public function getProp1(): string {/* ... */} public function setProp1(string $val): void {/* ... */} public function prefixProp2(): string {/* ... */} public function prop2Sufix(string $val): void {/* ... */} } This way: * without forcing them to use the new ones, users can choose whether to use old ones or new ones. * code duplication can be prevented, if we decided to preserve the old ones. * the accessors are more tidy and readable, if we decided to move out all multiline accessors. As far as I understand, the difference between "set" and "guard" is: with "set", we have freedom and responsibility to allocate a space. Additionally, we have to choose whether to use "set" or "guard", not both. It is a sad decision that "guard" has to be eliminated to reduce complexity. In my opinion, it is valuable that we can write code more concise than before: class MyOldOrdinaryObject { public string $prop1 { get; guard use commonGuard; } public string $prop2 { get; guard use commonGuard; } // Assuming that prop1 & prop2 have the same validity rules. // The visibility is private in order to prevent users accessing it. // Due to loss of space allocation and difference of function // signature, this method cannot be used in concert with "set". private function commonGuard(): void {/* ... */} } With this capability, the complex accessor in constructor problem can be solved class MyValueObject { public function __construct( public string $prop1 { get; private guard use guard1; } public string $prop2 { get; private guard use guard2; } public string $prop3 { get; private guard use commonGuard; } public string $prop4 { get; private guard use commonGuard; } ){} private function guard1(): void {/* ... */} private function guard2(): void {/* ... */} private function commonGuard(): void {/* ... */} } I hope that "guard" can be included again. I don't understand the internals of the engine. I think the mechanism of this is compiler assisted copy-paste (same as traits), but only the function body and the visibility is overridden based on accessors definition. Regards, Hendra Gunawan.