DEV Community

Discussion on: PHP Typed Properties: Think Twice.

Collapse
 
blackcat27 profile image
Josh Kitchens • Edited

Both of these examples are flawed.

First, you shouldn't be using public fields. Full stop. It breaks encapsulation, leaks implementation details of the class, and means your class can find itself in an unknown or inconsistent state at any time due to outside influence.

Php doesn't offer properties like C# and other languages, which are really just shorthand for getters and setters. Which is the preferred pattern for exposing private fields.

And to address your point about "double type checking". That's EXACTLY what you're getting. Php only checks types at the compilation stage for typed arguments and returns. Type hints offer no such safety. And even if they did, should you forget the type hint, php will happily let you assign an argument typed as a string into a field you meant to be an int. With the typed field, that's no longer possible.

And your argument for not being able to add additional constraints is also flawed. It has nothing to do with interfaces themselves, just bad interface design. Again, it's the breaking encapsulation and exposing direct fields which causes the problems you bring up. It has nothing to do with typed fields.

There's no "trade off" to be had with typed fields. There's just good code and bad code. And this is bad code.

Collapse
 
mindplay profile image
Rasmus Schultz • Edited

Both of these examples are flawed.

It's all one example, going through iterations with changing requirements.

First, you shouldn't be using public fields. Full stop. It breaks encapsulation, leaks implementation details of the class, and means your class can find itself in an unknown or inconsistent state at any time due to outside influence.

By design. (Outside influence is what's desired with a mutable model.)

The initial requirement is that price be an integer and description be a string, both being mutable.

The first and second code sample equally satisfy those requirements.

Php doesn't offer properties like C# and other languages, which are really just shorthand for getters and setters. Which is the preferred pattern for exposing private fields.

In C#.

But as you pointed out, PHP doesn't offer accessors.

The preferred (only) pattern in PHP at the moment is getter/setter methods - and we're now getting an alternative (public, type-hinted properties) which can satisfy the requirements of the first example, but can't satisfy the new requirements (abstraction, validation) introduced in the following examples.

And to address your point about "double type checking". That's EXACTLY what you're getting.

The point was, if the input to setPrice() has already been type-checked, you don't need the extra type-check when setting the property - your class is already safe from incorrect mutation.

(If you want an extra layer of safety against bugs in your own implementation, sure, a type-hinted private field provides that extra safety. Personally, I'm getting that guarantee from static analysis already with a doc-block.)

Php only checks types at the compilation stage for typed arguments and returns. Type hints offer no such safety.

Did you mean doc-blocks?

PHP checks all static type-hints at run-time, including property type-hints introduced by the RFC. (It's an interpreted language - there's no compilation stage during which assignments could be checked for correctness.)

And your argument for not being able to add additional constraints is also flawed. It has nothing to do with interfaces themselves, just bad interface design. Again, it's the breaking encapsulation and exposing direct fields which causes the problems you bring up. It has nothing to do with typed fields.

There's no "trade off" to be had with typed fields.

There is in the example I used.

It's very likely a lot of PHP developers were excited about this feature so they could simplify models with trivial constraints in this manner.

There are other articles out there already presenting exactly this opportunity with very similar examples.

The point of this article was to make sure these people understand the trade-offs they're making in terms of being able to iterate to meet new requirements.

There's just good code and bad code. And this is bad code.

It seems you read the article making your own assumptions about the requirements for each example. The code in these examples satisfy the requirements for each of those examples at the time - the point was to illustrate how simple requirements often change towards more complex requirements.

You seem to be angry or offended about something, I'm not exactly sure what?

I think for the most part you've just completely misunderstood what I'm trying to say with this article. As mentioned, there are already other articles proposing the kind of change in the first example - in fact, it's similar to the example shown in the RFC itself.

I'm just trying to help people understand the consequences of making such a change.