Using the later versions of PHP can massively reduce the amount of boilerplate code in your application
If you have an application of any appreciable size, you will have used DTO (Data Transfer Object) classes to shuttle data around your application.
One of the main properties of a DTO class is that it is immutable. This means that it cannot be changed after it has been created. In PHP, we have to jump through a few hoops to create an immutable class due to the lack of native immutability in PHP itself.
Traditionally, creating an immutable class meant creating a class with private properties, and then having only getter methods to access these private properties, and no setter methods at all.
This meant that a typical DTO class consisted of pretty verbose boilerplate code when all we want it to actually do is carry data without fear of it being modified.
However, now with some of the newer features introduced in PHP 8.0 and later, we can hugely reduce the size of our DTO classes, significantly reducing the amount of boilerplate code in our app. Less code for the same functionality is always a good thing!
Let’s follow a typical DTO class through the various PHP versions to see how it has improved and evolved.
PHP 7.4
In PHP 7.4, a DTO had to be created using a lot of boilerplate code, separately declared private properties, and public methods to access the data in each property.
Here is our example DTO in its most verbose format:
Lengthy, isn’t it? Quite a lot of code to do, really very little.
PHP 8.0
With PHP 8.0, we saw the introduction of promoted constructor properties. This allows us to define the class property declarations at the same time as we declare the constructor method parameters.
This allows us to simplify the DTO class a lot. Here’s what it looks like in PHP 8.0:
It’s much better, isn’t it? Less code to read, parse, and maintain — so it’s a definite improvement.
However, we still have all those pesky methods for accessing private properties.
PHP 8.1
In PHP 8.1, we saw the introduction of the readonly keyword. This allows you to define a property in a class, but the readonly ensures that once it’s been set, it cannot be changed.
We can use this to our advantage by switching our class properties to be public but then also using the readonly keyword to continue providing the immutable behaviour that we are after. And then, of course, because the properties are public, we no longer have any need for the methods!
Wow — what an improvement. This is just 15 lines of code compared to the 63 lines for our class in PHP 7.4!
Can we do any better? Well, yes, a little, but we must wait a while until PHP 8.2 is released.
PHP 8.2
PHP 8.2 takes the readonly concept one step further by allowing the readonly keyword to be applied at the class level, so we don’t need to repeat it on every constructor parameter.
This is the same lines of code as PHP 8.1 but with less noise — it looks much neater.
Conclusion
Removing boilerplate code from your application is an easy way to reduce the code you must maintain. Particularly with classes such as DTOs where there isn’t any value provided by the boilerplate methods — they are just immutable data classes — it’s a huge improvement to be able to eliminate all this noise.
Features like this are one of the best reasons to upgrade to more modern versions of PHP, quite apart from the apparent performance and security benefits of newer versions.
I’ve been able to strip out thousands of lines of boilerplate code from some of my applications without changing their behaviour. Less code means fewer bugs, better performance, and lower memory usage to boot!
How To Eliminate Boilerplate Code With PHP 8.1 was originally published in Better Programming on Medium, where people are continuing the conversation by highlighting and responding to this story.