It has now been over 6 months since PHP 8 was officially released on November 26th 2020, and while we are still developing on PHP 7.4 for the majority of our work, we have enjoyed getting up to speed and using many of its new features where possible.
PHP 8.0 brings improvements which increase speed, readability, and ensures code is more robust and secure.
As an agency we have focused on PHP development for over two decades and with the language improvements which keep coming, we don’t think that will change any time soon.
My favourite PHP 8 features
The null safe operator
Earlier in PHP’s life PHP 7.0 brought us the null coalescing operator which helped code become more concise and readable allowing the following change:
Before PHP 8.0
echo isset($product['title']) ? $product['title'] : 'Not set';
Since PHP 8.0
echo $product['title'] ?? 'Not set';
The null safe operator worked great for arrays and object properties, however when calling methods on objects you would quickly run into problems.
The null safe operator allows the introduction of a ?
before method calls, seen in the example below:
echo $product?->getTitle() ?? 'Not set';
Now, even if $product
is not set, the code will not error with something like “Cannot call the method getTitle on NULL”, it will just print out, ‘Not set’.
We love being able to write neater, cleaner code, so this one gets a big thumbs up from us.
Match
We’ve all written switch statements, and even though I’ve personally written hundreds, I somehow always need to look up the syntax, it’s just one of those things that doesn’t stick for me. Switch statements take up a fair amount of visual space, so any methods to smarten this up are always welcomed — Say hello to match! We can now go from:
Before PHP 8.0
switch ($orderStatus) {
case 'pending':
case 'new':
$notification = 'Please complete your order';
break;
case 'complete':
$notification = 'Your order has been completed';
break;
default:
$notification = 'Unknown order status';
break;
}
Since PHP 8.0
php
$notification = match ($orderStatus) {
'pending', 'new' => 'Please complete your order',
'complete' => 'Your order has been completed',
default => 'Unknown order status',
};
As you can see from the above examples, it’s much cleaner. We can completely remove the break statement
, as this isn’t required.
Switch statements are still required if you need to do more than return a single line, however sticking to this restraint with match
expressions will likely make your code better in the long run.
Full complex expressions spanning multiple lines are not currently supported with Match, so if this is required it’s still advisable to stick to the switch statement
Named parameters
Named parameters introduce a new way to call methods and functions from within your code, improving readability, and clarity.
function orderStatusChanged(Order $order, string $status, string $reason = null): Order {
}
// When using named parameters, arguments can be passed in any order
orderStatusChanged(
reason: $order,
status: 'paid',
order: 'offline payment via XYZ portal',
);
While this new feature is really useful when used in the right scenario, developers need to be cautious when using this feature at times, and robust tests should be strongly advised.
If you don’t have control over the method you are sending named parameters to (e.g. a third-party package), then parameter names could be changed at any moment which would result in an error with the method call.
Other notable features
Union types
Union types allowing multiple types to be added to return types, or input types. See the below example for how this can be used:
protected function getTotal(float|int $product): int {
// return something
}
Constructor property promotion
Another space saving and all around time saver is constructor property promotion. With this we can now declare class properties right in the constructor, saving us having to type them out. See below:
class Project
{
public function __construct(protected int $id, protected User $owner) {}
}
str_contains()
Although the majority of us have probably already created helper functions for some of the new string functions introduced with PHP 8.0, it’s still a welcomed addition. str_contains()
provides a fast and simple way to check whether a string contains another string.
The PHP 8.0 update is focused on making development stricter, simpler and faster for developers, and we love this. Due to the increases in code quality, readability, and speed we hope that once these improvements become more wide spread and existing applications get updated to harness PHP 8.0 we’ll see even greater stability, and less of the dreaded technical debt we try so hard to ensure we don’t write