It's here, just in time for Christmas! I'm not sure how many will be using PHP8 in production this year, but that's not to say many of us aren't already trying it on smaller side projects to get a taste of some of the new features.
My favourite so far, the new match()
expression.
Many other programming languages including Haskell, Erlang, and Elm, have a similar feature, but previously PHP only had the switch statement.
The switch
statement is fine, but you have a few things to be mindful of.
Firstly a switch
doesn't return a value, it's not an expression, although you can return early from a switch
statement
switch ($operation) {
case 'nop':
return $this->nop();
case 'acc':
$this->acc($argument);
case 'jmp':
return $this->jmp($argument);
}
With a match
this becomes much terser
return match ($operation) {
'nop' => $this->nop(),
'acc' => $this->acc($argument),
'jmp' => $this->jmp($argument),
};
It's also easier to prevent mistakes, like forgetting to return on the "acc"
branch in the previous switch
example.
A match can match multiple values, if they are comma separated, so I could write the above as
return match ($operation) {
'nop' => $this->nop(),
'acc', 'jmp' => $this->{$operation}($argument),
};
Although in this case I'm not sure it's particularly easier to read.
There is a default
branch you can use if you want to specify what should be returned if there is no match. You can also use arbitrary functions for comparisons in the match conditions.
function validateEmail(string $email): string
{
return match (true) {
str_contains($email, '@example.com') => 'an example email',
$email === filter_var($email, FILTER_VALIDATE_EMAIL) => 'a valid email',
default => throw new InvalidArgumentException('Invalid email address')
};
}
var_dump(validateEmail('hello@example.com')); // returns 'an example email'
var_dump(validateEmail('foo@bar.com')); // returns 'a valid email'
var_dump(validateEmail('invalid email')); // throws InvalidArgumentException
In this example I'm also taking advantage of being able to throw exceptions in
We also get a new UnhandledMatchError
if we forget to declare a path. This can be somewhat useful, like the PHP7 TypeError
, as the exception includes the type of value we tried to match, but not the value itself.
It would be really cool to be able to do partial matches or some kind of destructuring in the future, not sure if this going to be at all possible, something like
class A {
public function __construct(public int $n) {}
}
class B {
public function __construct(public int $n) {}
}
$x = new A(1); // or new B(2);
match ($x) {
new A($n) => $n,
new B($n) => $n,
};
Top comments (0)