PHP 8: New Match expression. How to use it?

PHP 8: New Match expression. How to use it?

PHP 8 introduced us to a new expression - 'match' - very powerful functionality that will often be a great alternative to the 'switch' statement. I say "often" here because both match and switch have their own uses, often not overlapping with each other. So let's take a look at the differences between the two.

PHP 8 introduced us to a new expression - 'match' - very powerful functionality that will often be a great alternative to the 'switch' statement. I say "often" here because both match and switch have their own uses, often not overlapping with each other. So let's take a look at the differences between the two. First, let's compare them. Here is one example of using the switch statement in the field of crm development:

switch($clientStatus) {

case 'Open':

case 'Not assigned':

$discount = null;

break;

case 'First buyer':

$discount = 10;

break;

case 'Second buyer':

$dicount = 20;

break;

case 'VIP':

$discount = 30;

break;

default:

$discount = 5;

break;

}

 

And here is how the assignment of a discount by customer status in match will look like:

 

$discount = match($clientStatus) {

'Open', 'Not assigned' => null,

'First buyer' => 10,

'Second buyer' => 20,

'VIP' => 30,

default => 5

}

 

As you can see from these two examples, match is significantly shorter in writing because:

 

  • It does not need the 'break' keyword;
  • It can combine several conditions into one, separated by commas;
  • It returns a value, so you can store it in a variable.

Therefore, from a syntactic point of view, match is much easier to write. However, if we dig deeper, we can see a lot more differences.

Match is an expression

'Match' is usually called an expression, while 'switch' is called a statement. In theory, there is a big difference between the two. An expression combines a value and a function call and can be assigned to a variable. In other words, it returns some value. Therefore, we can store the result of calling match in some kind of variable. In the case of a switch, this is not possible.

Lack of type casting

When comparing values, match also compares the types of the values. In other words, the comparison uses the === operator, while the switch uses ==.

Therefore, you may have situations where you want PHP to automatically cast types to the desired value. This is what explains in the first place why you cannot replace match instead of switch throughout your code.

$clientType = "2";

 

$redirectUrl = match($clientType) {

2 => '/discount',

3 => '/buy',

default => '/',

};

 

// $redirectUrl = '/'

 

Unknown values throw an error

If you omit the default keyword and when match cannot find any matches in the enumeration, PHP will throw an 'UnhandledMatchError' exception at runtime. Again, we see more restrictions, but all this protects developers from possible bugs.

 

$clientType = 5;

 

$redirectUrl = match($clientType) {

2 => '/discount',

3 => '/buy',

};

 

// UnhandledMatchError

 

Expression must fit on one line

You can only write one expression. Those, such an expression will cause you an error:

 

$a = 5;

 

$discount = match($clientStatus) {

'Open', 'Not assigned' => if ($a > 5) {

4

} else {

6

},

'First buyer' => 10,

}

 

In this case, you will need to at least use the ternary operator.

 

Combining conditions

I noted earlier that match lacks the break keyword; it also means that match does not allow matching conditions. But on the other hand, you can write several conditions on one line, separating them with commas:

 

$discount = match($clientStatus) {

'First buyer', 'Second buyer', 'VIP' => 10,

}

 

Challenging conditions and performance

When discussing the implementation of 'match' in the community, some developers said that there was no need to implement it, because the same can be done using regular arrays. Take a look at the example below when we want to find values where keys are regex search. Here we are using array notation:

 

$type = [

$this->matchRegex($line) => 'Good',

$this->matchesOtherRegex($line) => 'Bad'

][$search] ?? 'Unknown';

 

But there is a catch here - this approach will run all the regex functions during the construction of the array. Match, on the other hand, will run everything line by line, which is more performant.

 

Throwing Exceptions

Since we are talking about PHP 8, the exception can be thrown directly in the match itself:

$discount = match($clientStatus) {

'Open', 'Not assigned' => throw new DomainException('This type of client not allowed here!'),

'First buyer' => 10,

'Second buyer' => 20,

'VIP' => 30,

default => 5

}

 

So should you use switch or match?

In short, 'match' is a stricter and more modern version of its younger brother 'switch'.

There are cases where match offers a lot of flexibility, especially when we are talking about more complex conditions with multiple lines and type juggling. On the other hand, the regex check I mentioned above, constraints that guarantee fewer bugs, will make life easier for developers.

Honestly, I rarely used 'switch' before, due to its complex syntax. And these problems were solved by 'match'. Of course, it's not perfect yet, so there are times when you will use 'switch' and when you will use 'match'.