Hi folks. Based on earlier discussions, we've made a number of changes to the RFC that should address some of the concerns people raised. We also had some very fruitful discussions off-list with several developers from the Foundation, which led to what we feel are some solid improvements.
https://wiki.php.net/rfc/property-hooks Smaller changes: 1. We've added a PropertyHookType enum for use in reflection, which lets us get rid of a possible exception. 2. get_mangled_object_vars()'s behavior is now defined to be the same as an array, ie, skip hooks. 3. A final property with a final hook is no longer an error. It's just silently redundant, like for methods. 5. Made explict what happens with recursive hook calls and method calls from a hook. The behavior here is the same as for __get/__set. 6. Made support for #[\Override] explicit. 7. Added an FAQ regarding the property-centric approach rather than method-centric approach. 8. Clarified that the parent::$foo::get() syntax works on a parent property regardless of whether it has hooks. 9. Clarified that untyped properties are supported. (Though, it's 2024, please don't use untyped properties.) 10. Clarified that interface properties cannot specify a wider write-type, for simplicity. That could be considered as a future add-on with no BC breaks. 11. Provided an explanation of how to interpret the parent-hook access syntax. 12. Added an FAQ item explaining why a 'virtual' keyword is not feasible. Larger changes: 0. As noted a while ago, $field has been removed. 1. I've added an FAQ question regarding the parent::$foo::get() syntax, and why it is. 2. The $foo => expression shorthand has been removed. The legal shorthands are now: public string $foo { get => evaluates to a value; set => assigns this value; } 3. The set shorthand (with => ) now means "write this value instead". The non-shorthand version (set { } ) is always return void, so you have to assign the value yourself but you get more flexibility. Having updated the examples accordingly, I think this is actually a really nice and intuitive trade-off, as it makes the common transformation and validation cases (eg, in constructor promotion) even easier to follow with no redundancy. 4. On a set hook, the user may specify both a type and name, or neither. (That is, set {} or set (Foo $newFoo). If not specified, it defaults to the type of the property and $value, as before. 5. I restructured how the content in 2, 3, 4 is presented and moved some stuff around so that it flows more logically (I think). 6. The restrictions around references have been softened. Specifically, references are only disallowed if a backed property has a set hook. If it has only a get, or if it's a virtual property, references are allowed. We also added a future-scope section on a possible way to support assigning by reference in the future, if there is sufficient need. 7. Interfaces may now require a &get hook, or just 'get'. A class may use a &get hook on a 'get' interface declaration. This is the same logic as already exists for methods; we're just copying it. Hopefully the above changes should resolve most outstanding concerns. I do think the updated shorthand handling is better overall, so I'm happy with it. There also seems to be little consensus so far on naming this thing hooks vs accessors. Absent a consensus, we'll probably stick with hooks to avoid the effort of renaming all the things. Thank you everyone for the feedback so far, and if you still have some, please say so. (Even if it's just to say that you're happy with the RFC now so we feel more comfortable bringing it to a vote.) --Larry Garfield