PHP 8 is out soon, what are the new features and how easy is it to upgrade?

PHP 8 is out on November 26th, it's a major version so let's look at what's changed

Image for blog post PHP 8 is out soon, what are the new features and how easy is it to upgrade?

The last major PHP version change was 5.6 to 7, a change that, in our opinion, cemented PHP's future. The performance increases and new features in the 7 update meant that code was running faster and more efficiently, the implications of this were huge when you consider how much of the web is run by PHP. The upcoming version 8, to be released on November 26th 2020, isn't going to be quite as dramatic a change but it will be bringing some significant changes to the PHP runtime. We'll take a look at some of the more interesting changes.

JIT - 'Just in Time' Compilation

Perhaps one of the most anticipated changes in PHP8 is the JIT. JIT is an acronym for 'Just In Time' and essentially what this means for PHP is that parts of the code are cached as machine code so that it doesn't need to be recompiled each time the code is run.

For anyone not familiar with how PHP works it's essentially an interpreted scripting language which means that each time PHP code is executed via a web server or console command it is read by the PHP parser and then compiled to PHP opcodes that can be run by the PHP engine. PHP's opcache already speeds this process up by caching a copy of the compiled opcodes for re-use, so when a PHP script is called a second time the parsed and compiled opcodes will be returned from the cache, rather than generated again, this speeds things up dramatically.

So, whilst this process is already pretty fast a large chunk of PHP's execution time is in the runtime running opcodes, the process which actually turns the opcodes into machine runnable code. This is where the JIT comes in, it monitors running opcodes and when parts of the code are run over and over they can be marked as 'hot' and the machine code for these parts can be cached and executed instead.

Whilst this sounds like a game changer unfortunately the impact is only significant on code that runs repeated complex calculations, this generally isn't the use case for PHP in the world of the HTTP request / response cycle. So, unless you have a PHP application that's running intense maths calculations you probably won't see much of a difference from the JIT. That said, it's no reason to not be happy about it, it just means that PHP can now probably be used in applications where it wouldn't before.

Union Types

This is something that will give a bit more type safety to parts of PHP where multiple types can be accepted or returned by functions. PHP can already return or accept nullable types using the ? syntax:

public function getSomething(?Type $type): ?OtherType;

 The new Union Types allow you to do things like:

public function getSomething(TypeA|TypeB $type): OtherTypeA|OtherTypeB;

You can also still use the nullable ? or now also explicitly write |null. This doesn't give you the same benefits of using interfaces but does mean that you can rely on what's actually passed into your functions.

Nullsafe Operator

This is a really welcome addition to the language, especially for users of frameworks with ORMs that use relationships between models. It essentially allows you to return null (short circuit) from a chain of property accesses or method calls. If you look at the RFC for this operator, this code:

function f($o) {
$o2 = $o->mayFail1();
if ($o2 === null) {
return null;
}

$o3 = $o2->mayFail2();
if ($o3 === null) {
return null;
}

$o4 = $o3->mayFail3();
if ($o4 === null) {
return null;
}

return $o4->mayFail4();
}

 Becomes

function f($o) {
return $o?->mayFail1()?->mayFail2()?->mayFail3()?->mayFail4();
}

What's happening here is the chained method calls are able to short circuit and return null at any point, this stops the next chained call from trying to execute and raising an exception. This will lead to a huge reduction in ugly PHP code, especially in frameworks like Laravel where you can have property accesses across several objects/relationships where one could return null.

Attributes

Something that until now has been solved by using PHP DocBlocks, attributes provide a way to add meta data to classes, properties and methods. This will standardise the way that attributes are accessed and used and should provide some interesting ways to add configuration and meta data to classes.

Named Arguments

This one has caused some controversy in the PHP world. Essentially the change adds the ability to 'name' function arguments so that functions can be called with specific arguments provided. This solves two 'problems' in PHP, firstly it removes ugly code like:

function myFunc(Foo $object, bool $active, bool $new = false, string $message = '');
myFunc($someObject, true, false, 'some text');

With named arguments the function call will look like:

myFunc('object': $myObject, 'active': true, 'new': true, 'message': 'some text');

But it could also look like this:

myFunc('object': $myObject, 'active': true, 'message': 'here is some information');

This function call is much better in that it allows us to see clearly which argument is which and it also allows us to skip over the argument that has a default boolean value, before we would have to set this value in order to add the message.

Constructor Property Promotion

This is another one that will clean up a lot of overly verbose classes by removing the property declaration and setting that happens in lots of classes.

class Car 
{
public Engine $engine;

public int $horsepower;

public function __construct(Engine $engine, int $horsepower) {
$this->engine = $engine;
$this->horsepower = $horsepower;
}
}

By just adding the property visibility to the construtor this becomes:

class Car 
{
public function __construct(public Engine $engine, public int $horsepower) {}
}

Much less code. I think this one might take a bit of getting used to, it looks great on these code examples but when you're dealing with a class that has lots of properties with only a few set in the constructor it might be less readable.

The Match Expression

An expression similar to the much hated 'switch' statement. Match will take a value and return a value that 'matches' the input key.

$gradePerformance = match ($grade) {
1 => 'poor',
2 => 'ok',
3 => 'great',
default => 'grade value not valid',
};

Match uses strict comparison so it won't match '1' passed in. It looks pretty useful and a nice alternative to switch statements.

So, all in all some nice new additions to the language, there's a fair bit more that's changing but we've covered the major parts that most PHP developers will be interested in. I think the adoption of this will take a while, we're not going to see the end of PHP 7 for quite a while yet.

Upgrading to PHP 8

Given the changes to the language upgrading to PHP 8 will need to be carefully tested on your application before upgading your production versions. If your application is properly tested then you should be able to confidently upgrade and fix any incompatibilities. It looks like applications running on later PHP 7 versions shouldn't need too many changes to run on PHP 8, there are some changes in the core PHP library that might cause strange issues though, so once again thorough testing should ensure that your application can migrate smoothly.

If you're still running PHP5.6 then the jump to 8 might be tricky. There were significant changes in PHP 7 that required a lot of work migrating some PHP 5 based applications, these issues obviously still stand in the migration to PHP 8. That said you should be able to migrate your applications directly to PHP 8 bypassing 7.

We'll be upgrading our client's applications in due course, we're hoping that a couple will see some significant gains from the JIT, we'll blog again once we've upgraded them.

If you need help migrating your applications get in touch.


Article Category Tags

PHP Web Development Code