4 ms·
> Property hooks mean that some language magic will turn a property access into a call to methods. __get / __set was doing that already and some frameworks ver
by chx 2y ago
> Property hooks mean that some language magic will turn a property access into a call to methods.
__get / __set was doing that already and some frameworks very heavily rely on those.
> It implies that `$this->x` has a different meaning if it's inside a hook or outside hooks.
this is a valid critique but hopefully hooks will be super short and this won't be a major issue. Indeed, if your get is not an arrow function -- which only allows one statement -- then it needs a good thinking over whether this is indeed the best solution. Ie if your get is so complicated then perhaps a helper method is best and then you have get => $this->foo($this->thing) and that's the only place where $this->thing is special.
- idoubtit 2y ago> hopefully hooks will be super short and this won't be a major issue. Even if a PHP project has a policy of short hooks, I think hooks impede clarity. public string $countryCode { set (string $countryCode) { $this->countryCode = strtoupper($countryCode); $this->country = nameCountry($this->countryCode); } get => ... In this short hook, the first line of the setter obviously uses the underlying property. But the second line of the setter... Does `$this->country =` use the setter even if it's in a hook (but not a `country` hook)? Does reading `$this->countryCode` use the getter hook, even it's from a `countryCode` hook? If not, is there a way to call the `countryCode` getter from this setter? If quickly parsed the doc and the RFC, so I don't have answers (I suppose it's yes, no, no). But even if I knew how this code behaved, I would still think it's much more complex than plain methods.
- chx 2y ago> Does `$this->country =` use the setter even if it's in a hook (but not a `country` hook)? To me it is obvious hooks won't use other hooks because that could lead to an infinite loop in a hurry > Does reading `$this->countryCode` use the getter hook, even it's from a `countryCode` hook? same > If not, is there a way to call the `countryCode` getter from this setter? There is although it's a bit tricky and not intuitive but I feel this falls under the "it is enough this is possible, there's no need for it to be easy": "Be aware, the detection logic works on $this->[propertyName] directly at compile time, not on dynamic forms of it like $prop = 'beep'; $this->$prop. That will not trigger a backing value." Using dynamic properties in what should be simple code should be rare enough this is not a problem. It's like a bridge convention, the benefits vastly outweigh the drawbacks.
- c0wb0yc0d3r 2y ago> Does `$this->country =` use the setter even if it's in a hook (but not a `country` hook)? To me it is obvious hooks won't use other hooks because that could lead to an infinite loop in a hurry I would expect hooks for properties other than `$this->contryCode` to be called inside of a `$this->contryCode` hook. Btw the docs that are linked in the post[0] seem to be clearer than the example in the announcement. Reads less ambiguously to me. [0]: https://www.php.net/manual/en/migration84.new-features.php#migration84.new-features.core.property-hooks https://www.php.net/manual/en/migration84.new-features.php#m...
- alt227 2y agoYou are corect that the docs read much clearer. Why would they muddy the concept in the release post?
- patates 2y ago> To me it is obvious hooks won't use other hooks because that could lead to an infinite loop in a hurry Yet in Javascript: test = { set a(x) { this.b = x }, get a() { return 2 }, set b(x) { this.c = 10 }} Object { a: Getter & Setter, b: Setter } test.a = 10 10 test Object { a: Getter & Setter, b: Setter, c: 10 } and yes it's possible to make infinite loops.
- Gabrys1 2y agoWhy would you write such code though? If you want to store an underlying properly, use a differently named (and private) one: public string $countryCode { set (string $countryCode) { $this->_countryCode = strtoupper($countryCode); $this->country = nameCountry($this->_countryCode); }