idoubtit
a day ago
I'm just a PHP programmer for work, but I worry about the orientation PHP has chosen. As French people say: better is the enemy of good (Le mieux est l'ennemi du bien). The two new language features bring a higher language complexity for dubious gains. I hope I won't have to work with these.
Property hooks mean that some language magic will turn a property access into a call to methods. It implies that `$this->x` has a different meaning if it's inside a hook or outside hooks. I've used this kind of feature (getters/setters) with JS code (and with Moose/Perl decades ago), and I wasn't convinced. Plain methods are more explicit, have less cognitive charge, and are easier to extend.
On the bright side, I'm glad that the language is still thriving. In 2021, I was worried when the foundation was created, especially as I read that Nikita Popov had left. He was the creator of PHP's JIT code, and at the time the only developer who could fully understand it. But it seems there was no need to worry. PHP is now longer "the elephant in the room" of web programming, but it's still a good language, with many active developers at its core.
ok123456
20 hours ago
This feature has been in C# since about 2.0, and it's been an overall positive. It reduces boilerplate and inconsistencies in different programmers doing the boiler-plate differently.
It also gives static analysis tools semantic information about the structure of your classes. It can group pairs of methods that deal with the encapsulation of fields.
crowcroft
19 hours ago
I am also in favour of the change. I would argue though that because it's been in C# for so long, then yes it reduces inconsistencies across programmers/codebases, but introducing it to a language as mature as PHP is now though, might not have the same outcome.
ok123456
19 hours ago
I used it immediately in my C# code at the time. It was a breath of fresh air not to have code that looked like "enterprise" java.
signal11
18 hours ago
It’s interesting to consider the “magic” criticism in the context of languages like Zig, where devs actively want no hidden control flow. And Properties beyond simple { get; set; } are definitely hidden control flow.
But as you said — it’s been there in C# for a while and imho it’s a good abstraction over getters and setters. Even 2005-era IDEs could manage it fine, making it easy to access the property’s get/set code, so that it wasn’t really magical.
Maybe it’s a culture thing — most C# devs use IDEs. Not sure what PHP devs use, but I suspect tools like PhpStorm will make this easy to work with somehow. Devs using no-LSP editors will likely have a different view.
amerkhalid
16 hours ago
> Maybe it’s a culture thing — most C# devs use IDEs. Not sure what PHP devs use, but I suspect tools like PhpStorm will make this easy to work with somehow. Devs using no-LSP editors will likely have a different view.
This is probably one of the big factors. I am also not a huge fan of “magic” even though I use IDE (vscode). I started off as a PHP dev, directly editing files on production server using vi. Any “magic” simply slowed me down.
Years later, now I can simply cmd+click to anywhere in code but it feels a bit off to me. Perhaps, I still miss my old days of dev.
neonsunset
15 hours ago
How do you expect properties to interact with IDEs?
The argument that C# choosing to offer features that lead to terser implementation seems orthogonal to where you write it. Behavior in property getters and setters may as well be completely hidden from the caller. But the standard expectation is that accessing and/or setting a property should be cheap and not involve much logic, which most of the code out there adheres to.
(and personally I'm finding it to be a more productive experience than any dynamically typed language which always feels like stone age regardless of the environment)
lmm
10 hours ago
> How do you expect properties to interact with IDEs?
An IDE can highlight non-basic properties in a different colour from basic properties, or underline them or something. That would be difficult for an editor to do as part of normal syntax highlighting.
int_19h
15 hours ago
Properties have been in C# since the very first version. And those, in turn, were largely inspired by Delphi, with the honorable mention of Visual Basic.
brtkdotse
20 hours ago
My experience is that 99% of the work related to geters and seters is handled by the IDE
ok123456
20 hours ago
This encapsulation style for OOP is standard; the language should support it and not require additional design patterns or IDE tools.
An argument could be made for adding a sigil so the class user knows this isn't a dumb field, but then if someone wants to upgrade a dumb field to this, as Python encourages, they would need to modify every use.
James_K
18 hours ago
Every step on the path to bloat is justified.
munk-a
17 hours ago
And yet in this wonderful laboratory of a multitude of languages the growth of a language doesn't destroy as much as it offers a larger variety of choice - with good features being stolen by other languages and less good features remaining niche and unique.
James_K
12 hours ago
Look at C++ or Perl, languages with many features that are quite frequently hated. When you add features, you force users to learn those features. It is not just a "variety of choice" because you know that other people will also take some of those choices and you'll probably have to edit their code at some point. Features are not just added to the language, but imposed on its users. The need to add features to a language is a sign that what you already have is insufficient. Features should be added to the bottom of a language, increasing its expressive power, rather than to the top of the language forming cruft around the edges. It would be much more productive for us to collectively abandon PHP in favour of sane languages, ones which don't require the continual addition of more features to cover their foundational shortcomings.
theendisney
10 hours ago
The imposed part was funny. I hope I wont have to use anything new. I only had a mild panic attack reading they changed exit() but it was a false alarm.
Why is it that after the human life span expires all of the code should be thrown away?
I remember when my host updated and php could no longer be opened with <? and my websites spilled their guts all over the screen.
Shorel
20 hours ago
I just checked the code samples from the article/post.
Property hooks look awesome, they fix something that's my main pain point in PHP nowadays.
All these getters and setters manually coded make it feel like Java. Just completely boring and unusable without some fancy IDE that types all that boilerplate.
It is one great feature of C# that I'm glad PHP is adopting. This code is also easier to extend than the Java-like sea of getters and setters.
(I don't consider any mention of JS code as a valid comparison, if anything we are better ignoring JS existence unless forced to do some frontend)
manarth
5 hours ago
"All these getters and setters manually coded make it feel like Java."
Project Lombok has solved that issue of manual boiler-plate getters and setters in Java. If you program regularly in Java it's worth having in your toolbox.brazzy
5 hours ago
Or, for immutable entities, just use records. Part of the language since 2020: https://docs.oracle.com/en/java/javase/14/language/records.h...
Admittedly they come with some restrictions, but also some additional benefits.
munk-a
17 hours ago
While these are certainly a better option automatically generated default getters and setters have been pretty do-able through magic methods for a while now - and with the more robust reflection we now have access to they can be implemented in a safe manner. I'm still pretty happy to hear we're getting it as a baked in feature.
klaussilveira
19 hours ago
I feel the opposite: this brings simplicity and pragmatism back to PHP. Gone are the years of bowing to the verbosity of Java, sacrificing a dynamic powerful language at the altar of 1995's OOP paradigms.
cutler
19 hours ago
Seriously? Since 5.3 PHP has worshiped at the alter of Java OOP to the extent that writing PHP code is now an exercise in pseudo-Java.
klaussilveira
19 hours ago
Yes, that is correct. And this release marks a point where the language is officially moving away from that.
thrw42A8N
4 hours ago
How? It just got way more invested into OOP... It's now much harder to understand my code at a glance. The Java feeling isn't because I have to write a lot of code, it's how the code works.
stephenr
4 hours ago
> It's now much harder to understand my code at a glance.
Why? Property hooks aren't mandatory. If you want to keep using explicit getter/setter methods, you can do that. If you want to keep using implicit getter/setter hooks via __get/__set, you can do that. If you want to keep using plain property access, you can do that.
All this does, is allow features that previously relied on the black box of __get/__set to be exposed as real properties. This massively improves the scenario for anything that works via reflection, and makes a whole suite of bugs related to unintended behaviour, simply impossible.
thrw42A8N
3 hours ago
Others will use them and I will need to use their libraries. Get and set magic methods were a mistake too. Same with reflection. Again and again, deeper into the Java 6-land, while Java itself went away a decade ago.
stephenr
3 hours ago
> Others will use them and I will need to use their libraries.
From the outside it's just a property access. The whole point is you don't need to worry about whether it's a direct access or a getter/setter with logic, even if it changes from one to the other between versions.
> Get and set magic methods were a mistake too.
They're definitely not ideal, and thanks to this change they're no longer required for the vast majority of cases.
> Same with reflection.
Reflection is a mistake?
thrw42A8N
an hour ago
I need to worry about it if I'm using it in an app. In what job you don't need to worry about what code are you executing? This is the whole point. It makes my job much harder to do, much more hidden and arcane - not worth it to save few characters.
Yes, reflection is a mistake. It's a hotfix for problems caused by OOP. It's not actually necessary.
TypeScript is a good example. Some people write it like Java/C#, with classes, inheritance, reflection, dependency injection. Usually I can get that code down to 20-30% of original size after I cut out the last class (then I forbid the keyword in linter), and none of that is actually necessary or improved the situation.
beberlei
a day ago
Just to set the record straight, Nikita is not the creator of the PHP JIT code, that is Dmitry and he is employed by Zend owned by Perforce working mostly on this.
idoubtit
a day ago
Thanks for correcting me, and sorry for the error. I should have checked before writing.
jacobyoder
20 hours ago
I'd tried to put together an RFC years ago to introduce groovy-style accessors in PHP.
$this->foo
would look for a getFoo() method, and execute if it existed, or not if not. Felt like that was easier to reason about, fwiw, but I couldn't get it off the ground. Even then, there were multiple C#-style get/set proposals floating around, so this style seems to be the one more people like. Not a fan of the style, personally, and probably won't use these much directly any time soon. If it helps people maintaining libraries that I use to deliver code that is cleaner and more productive to them... I'm OK with that.
wvenable
18 hours ago
I'm not a fan of that kind of magic in my languages but such a thing was already easily doable in PHP. You could just have a base class that implements __get and __set so that $this->foo automatically calls $this->getFoo().
mgkimsal
17 hours ago
can't do that if you declare the properties on the class. __get only works for undefined properties.
wvenable
17 hours ago
Well don't do that then. :)
hks0
6 hours ago
That advice doesn't always work in real life; otherwise for every compiler or linter check in any language, we could drop all those checks and tell the programmers not to do that.
E.g. if a base class declares a variable it can potentially break its children. Whose at fault here?
I agree with your original comment though. And if the bypass of exisitng fields is badly wanted, somehow marking __get to disregard them makes more sense to me.
munk-a
16 hours ago
Or, alternatively, use `__call`
9dev
14 hours ago
Doctor, doctor, it always hurts when I press here…
notresidenter
16 hours ago
This has existed for so long though, through `__get`, `__set` and other methods, the ArrayAccess interface, the `__call` and `__callStatic` methods.
This way, at least, it's much more explicit. And this should probably only be used inside frameworks anyway, and not in "user-land" code.
keyle
12 hours ago
I agree with what you wrote and I am familiar with that saying.
PHP to me, professionally, is nothing without Laravel. So as long as Laravel doesn't become more obtuse than it already is, it's all good.
I really dislike getters and setters, particularly when they allow async code. Now all the sudden you have a massive performance risk, it's all too typical to see junior devs doing expensive stuff in getters and now the whole application, exponentially, becomes slower.
Anything that _may_ involves magic is dangerous in large code bases.
conradfr
a day ago
Don't you get tired of managing getters/setters in your entities?
cutler
19 hours ago
Entities, shrentities - it's all just data.
mgkimsal
20 hours ago
aren't you just managing them in a new syntax now?
joshmanders
15 hours ago
The difference with property hooks and userland getter/setters is that you're now just doing
echo $obj->prop
$obj->prop = 'bar';
not echo $obj->getProp();
$obj->setProp('bar');
stephenr
4 hours ago
A big part of this is about code that's consumed by third parties: i.e. library code.
Previously, it was very common to not expose a public property directly, even if it required no setter logic, because any future change to add setter logic would mean it has to become a setter method.
This results in potentially dozens of boilerplate getter/setter methods, that provide no actual benefit, but are necessary to avoid potential BC breaks in a future version of the library.
With property hooks, the property doesn't need to define any getter/setter logic initially - and adding a hook later to the `set` action doesn't change the way other code calls it.
So no, it isn't just "new syntax" now - it's a case of largely not needing to write/generate any of that boilerplate any more - it's just not needed, regardless of how that property's behaviour changes in future.
whalesalad
18 hours ago
stockholm syndrome is real
immibis
10 hours ago
This comment is referring to the practice of always writing getters and setters even when they are not needed, then feeling frustrated by the amount of boilerplate.
tcfhgj
18 hours ago
which getters/setters?
alt227
20 hours ago
I agree. PHP is such a simple language to follow but now with these property hooks, if you dont fully understand how they work then the code becomes unreadable due to the magic.
Worse than that, it is possible to read it wrongly which is going to cause many nasty headaches for amateur developers of the future trying to debug PHP code.
wvenable
18 hours ago
PHP has had the ability to dynamically handle properties for decades so this doesn't hurt readability -- in fact, it makes it better.
giraffe_lady
20 hours ago
I wrote php exclusively only for about two years early in my career but have had to come back to it periodically every once in a while. I find it one of the most difficult languages to be a visitor in. The way variable, array, and class semantics mix can make it hard to decipher the exact behavior of a chunk of code. Especially if you have a mix of "old" procedural and modern OO php, which the projects I work on do.
I'm not bringing this up as a particular criticism of the language, I think it's fine. It is also an experience I have with lisp, where it is fun and easy to write but hard to read when coming back to it after a while away. I just don't think php is a simple language, on several levels. The semantics that I mentioned, combined with the mixing of paradigms, and the large and inconsistent standard library. You can write simple php but it takes a lot of discipline.
alt227
19 hours ago
> Especially if you have a mix of "old" procedural and modern OO php
I guess thats a result of such wildly changing features in each version change. Each major version of PHP has brought in such drastic changes of concept and semantic that it is easy to start mixing them together and get confused looking code.
However I find this in a lot of other systems. Look at node.js, every release changes things so much that people regularly rewrite their entire code base multiple times to take advantages of the new features. Do a google search for guides on node programming a specific issue, and depending on how old it is it you will get wildly differnt approches and results. Popular and highly developed languages change often, and this will always cause issues between old and new.
giraffe_lady
19 hours ago
I agree. I think for largely cultural and timing reasons, and also its success, there are a lot more long-lived php codebases for this to play out in compared to most languages.
I also think possibly node is our generation's php, with it being so fast-changing and there not being a community consensus about framework. So every complex node project is, like pre-laravel php, essentially a totally unique ad-hoc framework composed of a mix of libraries. Ruby and python aren't better languages than php or node, and rails and django aren't perfect, but to a large extent those languages avoid this problem just because everyone is using the same solutions.
wbl
18 hours ago
T_PAAMAYIM_NEKUDOTIM, mysql_real_es ape2, parse_str, etc.
duskwuff
16 hours ago
> mysql_real_escape2
Blame MySQL for that name, not PHP.
https://dev.mysql.com/doc/c-api/8.4/en/mysql-real-escape-str...
(And, if you're doing modern PHP, it's just PDO->quote().)
munk-a
16 hours ago
I'm not certain about OP's objection but for me it's less the function name and more the terrible history of how PHP tried to automatically fix SQL injection and instead made everything a thousand times worse. If you're not using bound parameters for user data you're taking a huge risk and making your life multitudes more difficult. PHP's PDO is by far the better option at this point but it suffers from poor enough usability that I've built my own wrapper for it at two different companies.
Dylan16807
10 hours ago
> the terrible history of how PHP tried to automatically fix SQL injection and instead made everything a thousand times worse
Are you thinking of stuff like magic quotes? mysql_real_escape is not part of an automatic anything. You manually use it to quote each value.
hparadiz
16 hours ago
Writing a wrapper for PDO is standard operating procedure for various good reasons.
wbl
16 hours ago
Why should I blame MySQL? It's the PHP developers that decided to introduce it and not change the name, plus have several functions that don't do the right thing as well.
cess11
3 hours ago
This hasn't been an issue for like fifteen years or whatever.
In hindsight I think it's a good thing, it's a pea that keeps princesses at a distance from the language.
chx
a day 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
a day 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.
Gabrys1
17 hours ago
Why 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); }
chx
a day 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
a day 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#m...
alt227
20 hours ago
You are corect that the docs read much clearer. Why would they muddy the concept in the release post?
patates
18 hours 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.
reaperducer
14 hours ago
The two new language features bring a higher language complexity for dubious gains.
For a long time now, PHP has been on a trajectory of trying to be everything to everyone, constantly bolting on features from every language that happens to drift by.
My observation has been that the people who are deeply invested in PHP are tired of being hazed online for using a "toy" language, so they're trying to adopt all of the complexity and problems of other languages, rather than just keeping things simple, which is what used to be PHP's primary strength.
cess11
3 hours ago
PHP was never particularly simple, it has always had a diverse standard library and lots of similar but subtly different builtins and a rather funky type system and so on.
It's not for people that compulsively talk about category theory and lenses five minutes into every programming conversation.
dubcanada
a day ago
None of this is required. You can still write spaghetti code perfectly fine.
smarkov
a day ago
Of course it's not required but when you start pushing the boundaries of a language with the goal of achieving a clean interface, obscure features you wouldn't normally resort to become appealing. I dislike all of the magic around Laravel's Eloquent ORM - model relationships, query builder, abuse of ForwardsCalls trait, etc, but at the same time I can appreciate how "clean" it all looks once it's put together.