PHP 8 added two small features that clean up two very common patterns: choosing between several values, and safely reading a property that might not exist.
match compares with strict equality (===, no type juggling), never falls through to the next case, and returns a value directly instead of needing break in every branch.
$statusText = match ($statusCode) {
200, 201 => 'Success',
404 => 'Not Found',
500 => 'Server Error',
default => 'Unknown Status',
};| switch | match |
|---|---|
| Loose comparison (==) | Strict comparison (===) |
| Falls through without break | Never falls through |
| A statement — doesn't return a value | An expression — returns a value directly |
| An unmatched case with no default is silently skipped | An unmatched case with no default throws an error |
Without it, reading a property several levels deep on something that might be null requires a chain of manual checks.
// The old way
$city = null;
if ($user !== null) {
if ($user->address !== null) {
$city = $user->address->city;
}
}With ?->, the whole expression short-circuits to null the moment any link in the chain is null, without a single manual check.
// The null-safe way
$city = $user?->address?->city;What ?-> does not do
The null-safe operator only protects against the exact chain it's used on — a typo in a property name still causes a normal error. It replaces null-checking, not all error handling.