I: Introduction.
Recently, php version 8.0 has been officially released, according to experts, php has quite a lot of breakthrough technology to increase the linkage and improve processing speed. So, together we find out what’s new in php8.0.
I: New features.
1: Union types.
Given PHP’s dynamically typed nature, there are many cases where conjugation can be useful. Simply put, we can set multiple data types for the input and output of the function.
public function foo(Foo|Bar $input): int|float;
But Note that void can never be a union type, as it indicates “no return value at all”. Furthermore, the nullable
merger can be written using |null
or using ?
Existing symbols:
1 2 3 4 | public function foo(Foo|null $foo): void; public function bar(?Bar $bar): void; |
2: JIT
The JIT compiler – in time – promises a significant performance improvement, although not always in the context of web requests. I’ve done benchmarks on real-world web applications and it doesn’t seem like the JIT makes much of a difference, if any, on those types of PHP projects.
You can learn more about JIT here .
3: The nullsafe operator
If you are familiar with the null binding operator , you are familiar with its shortcomings: it doesn’t work on method calls. Instead, you need to mediate check or rely on the optional
helper provided by some framework:
1 2 3 4 | $startDate = $booking->getStartDate(); $dateAsString = $startDate ? $startDate->asDateTimeString() : null; |
With the addition of the nullsafe operator, we can now have null binding on methods!
$dateAsString = $booking->getStartDate()?->asDateTimeString();
You can read all about the nullsafe operator here .
4: Assign a parameter value.
Named arguments allow you to pass values into a function, by specifying the name of the value, so you don’t have to consider their order, and you can also ignore optional parameters!
1 2 3 4 5 6 7 8 9 10 | function foo(string $a, string $b, ?string $c = null, ?string $d = null) { /* … */ } foo( b: 'value b', a: 'value a', d: 'value d', ); |
5: Attributes
Attributes, often called annotations in other languages, provide a way to add meta data to classes without having to parse docblocks.
For a quick look, here is an example of what the properties look like, from RFC:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | use AppAttributesExampleAttribute; #[ExampleAttribute] class Foo { #[ExampleAttribute] public const FOO = 'foo'; #[ExampleAttribute] public $x; #[ExampleAttribute] public function foo(#[ExampleAttribute] $bar) { } } |
1 2 3 4 5 6 7 8 9 10 11 | #[Attribute] class ExampleAttribute { public $value; public function __construct($value) { $this->value = $value; } } |
Note that this base Attribute was called PhpAttributet in the original RFC, but was later changed by another RFC.
6: Match expression
You could call it the big brother of the expression switch
: match
can return a value, does not require a break
statement, can match a condition, use a strict type comparison, and doesn’t do any coercion. any style.
It looks like this:
1 2 3 4 5 | $result = match($input) { 0 => "hello", '1', '2', '3' => "world", }; |
7: Constructor property promotion
This RFC adds syntax lines to create value or data objects. Instead of specifying the properties of the class and a constructor for them, PHP can now combine them into one.
Instead of doing this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class Money { public Currency $currency; public int $amount; public function __construct( Currency $currency, int $amount, ) { $this->currency = $currency; $this->amount = $amount; } } |
Now you can do the following:
1 2 3 4 5 6 7 8 | class Money { public function __construct( public Currency $currency, public int $amount, ) {} } |
8: New static
return type
While it was possible to return self
, static
not a valid return type until PHP 8. Given PHP’s dynamically imported nature, this is a feature that will be useful for many developers.
1 2 3 4 5 6 7 8 | class Foo { public function test(): static { return new static(); } } |
9: New mixed type
Some people may call it a necessary crime: mixed
types cause many people to have mixed feelings. However, there is a very good argument for solving this problem: a missing type can make a lot of sense in PHP:
- A function returns nothing or null
- We are expecting one of many categories
- We are expecting a suggested non-type in PHP
Because of the above reasons, it is a good thing that mixed
types are added. mixed
itself means one of the following:
- array
- bool
- callable
- int
- float
- null
- object
- resource
- string
Note that it’s mixed
can also be used as a parameter or property type, not just as a return type.
Also note that since mixed
already includes null, null is not allowed to make it null. The following will cause the error:
1 2 3 | // Fatal error: Mixed types cannot be nullable, null is already part of the mixed type. function bar(): ?mixed {} |
10: Throw expression
This RFC changes throw
from a statement to an expression, which makes it possible to throw exceptions in many new places:
1 2 3 4 | $triggerError = fn () => throw new MyError(); $foo = $bar['offset'] ?? throw new OffsetDoesNotExist('offset'); |
11: Non-capturing catches
With old versions we write catch like this:
1 2 3 4 5 6 | try { // Something goes wrong } catch (MySpecialException $exception) { Log::error("Something went wrong"); } |
With version 8.0 we just need to write like this:
1 2 3 4 5 6 | try { // Something goes wrong } catch (MySpecialException) { Log::error("Something went wrong"); } |
III: Summary. Above I mentioned 11 changes I think we often use. There are some more changes I will update in the following article. thanks!
IV: Reference.