matchBehavior similar to
switch.
It is available as of PHP 8.0.0The
match expression branches evaluation based on an identity check of a value.
A match expression has a subject expression that is compared against multiple alternatives.
Unlike
switch:
1. it will evaluate to a value much like ternary expressions.
2. the comparison is an identity check (===) rather than a weak equality check (==)
The result of a match expression does not need to be used.
A match expression must be terminated by a semicolon.
<?php
$return_value = match (subject_expression) {
single_conditional_expression => return_expression,
conditional_expression1,
conditional_expression2 => return_expression,
};
?>
subject_expression
The expression to be analized.
single_conditional_expression => return_expression
The single conditional expression and the return value for it.
conditional_expression1
The first expression to be analized.
conditional_expression2 => return_expression
The second conditional expression and the return value for it.
EXERCISE
<?php
function wordify($x) {
return match ($x) {
0 => 'Zero',
1 => 'One',
2 => 'Two',
3 => 'Three',
4 => 'Four',
5 => 'Five',
6 => 'Six',
7 => 'Seven',
8 => 'Eight',
9 => 'Nine',
};
}
for ($i = 0; $i <= 5; $i++) {
print wordify($i) . "<br>";
}
?>
RESULT
Zero
One
Two
Three
Four
Five
Parse error ...
PHP prior to version 8.0.0.
EXERCISE
<?php
echo '- - - - - - - - - - - - - - -<br>';
function print_bool($bool) {
echo match ($bool) {
true => "true<br>",
false => "false<br>"
};
}
print_bool(true);
print_bool(false);
echo '- - - - - - - - - - - - - - -<br>';
function get_value($i) {
return match ($i) {
1 => 1,
2 => 2,
default => 'default',
};
}
echo get_value(0) . "<br>";
echo get_value(1) . "<br>";
echo get_value(2) . "<br>";
echo get_value(3) . "<br>";
echo '- - - - - - - - - - - - - - -<br>';
function get_range($i) {
return match (true) {
$i >= 50 => '50+',
$i >= 40 => '40-50',
$i >= 30 => '30-40',
$i >= 20 => '20-30',
$i >= 10 => '10-20',
default => '0-10',
};
}
echo get_range(22) . "<br>";
echo get_range(0) . "<br>";
echo get_range(59) . "<br>";
echo get_range(13) . "<br>";
echo get_range(39) . "<br>";
echo get_range(40) . "<br>";
echo '- - - - - - - - - - - - - - -<br>';
match (1) {
1 => print "Executed<br>",
};
echo '- - - - - - - - - - - - - - -<br>';
?>
RESULT
- - - - - - - - - - - - - - -
true
false
- - - - - - - - - - - - - - -
default
1
2
default
- - - - - - - - - - - - - - -
20-30
0-10
50+
10-20
30-40
40-50
- - - - - - - - - - - - - - -
Executed
- - - - - - - - - - - - - - -
Parse error ...
PHP prior to version 8.0.0.
EXERCISE
<?php
echo '- - - - - - - - - - - - - - -<br>';
$x = match (true) {};
echo '- - - - - - - - - - - - - - -<br>';
?>
RESULT
Fatal error ...
PHP version 8.0.0.
Parse error ...
PHP prior to version 8.0.0.
EXERCISE
<?php
echo '- - - - - - - - - - - - - - -<br>';
function get_value1($i) {
return match ($i) {
1 => 1,
2 => 2,
};
}
echo get_value1(1) . "<br>";
echo get_value1(2) . "<br>";
echo get_value1(3) . "<br>";
echo '- - - - - - - - - - - - - - -<br>';
?>
RESULT
- - - - - - - - - - - - - - -
1
2
Fatal error ...
PHP version 8.0.0.
Parse error ...
PHP prior to version 8.0.0.
EXERCISE
<?php
echo '5.1
<br> - - - <br>';
function is_working_day($day) {
return match ($day) {
1, 7 => false,
2, 3, 4, 5, 6 => true,
};
}
for ($i = 1; $i <= 7; $i++) {
var_dump(is_working_day($i));
echo '<br>';
}
echo '<br>5.2
<br> - - -<br>';
function dump_and_return($string) {
var_dump($string);
echo '<br>';
return $string;
}
var_dump(match ('foo') {
'foo' => dump_and_return('foo'),
'bar' => dump_and_return('bar'),
});
echo '<br><br>5.3
<br> - - -<br>';
function wrong() {
throw new Exception();
}
var_dump(match (0) {
null => wrong(),
false => wrong(),
0.0 => wrong(),
[] => wrong(),
'' => wrong(),
0 => 'int',
});
echo '<br>';
function get_value() {
return 0;
}
var_dump(match (get_value()) {
null => wrong(),
false => wrong(),
0.0 => wrong(),
[] => wrong(),
'' => wrong(),
0 => 'int',
default => 'default',
});
echo '<br><br>5.4
<br> - - -<br>';
function wrong1() {
throw new Exception();
}
function test_int($char) {
return match ($char) {
0 => wrong1(),
1 => wrong1(),
2 => wrong1(),
3 => wrong1(),
4 => wrong1(),
5 => wrong1(),
6 => wrong1(),
7 => wrong1(),
8 => wrong1(),
9 => wrong1(),
default => 'Not matched',
};
}
foreach (range(0, 9) as $int) {
var_dump((string) $int);
echo '<br>';
var_dump(test_int((string) $int));
echo '<br>';
}
function test_string($int) {
return match ($int) {
'0' => wrong1(),
'1' => wrong1(),
'2' => wrong1(),
'3' => wrong1(),
'4' => wrong1(),
'5' => wrong1(),
'6' => wrong1(),
'7' => wrong1(),
'8' => wrong1(),
'9' => wrong1(),
default => 'Not matched',
};
}
foreach (range(0, 9) as $int) {
var_dump($int);
echo '<br>';
var_dump(test_string($int));
echo '<br>';
}
echo '<br>5.5
<br> - - -<br>';
function wrong2() {
throw new Exception();
}
echo match (true) {
'truthy' => wrong2(),
['truthy'] => wrong2(),
new stdClass() => wrong2(),
1 => wrong2(),
1.0 => wrong2(),
true => "true<br>",
};
echo '<br>5.6
<br> - - -<br>';
function wrong3() {
throw new Exception();
}
echo match (false) {
'' => wrong3(),
[] => wrong3(),
0 => wrong3(),
0.0 => wrong3(),
false => "false<br>",
};
echo '<br>5.7
<br> - - -<br>';
$value = 1;
echo match ($value) {
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
1 => 6,
};
echo "<br>";
echo match ($value) {
2, 1 => '2, 1',
1 => 1,
3 => 3,
4 => 4,
5 => 5,
};
echo "<br>";
echo match ($value) {
1, 1 => '1, 1',
2, 2 => '2, 2',
3, 3 => '3, 3',
4, 4 => '4, 4',
5, 5 => '5, 5',
};
echo "<br>";
echo match ($value) {
1 => 1,
1 => 2,
};
echo "<br>";
echo match ($value) {
2, 1 => '2, 1',
1 => 1,
};
echo "<br>";
echo match ($value) {
1, 1 => '1, 1',
1 => 1,
};
echo "<br>";
echo '<br>5.8
<br> - - -<br>';
function test($value) {
echo match ($value) {
1 => '1 int',
'1' => '1 string',
2 => '2 int',
'2' => '2 string',
3 => '3 int',
'3' => '3 string',
4 => '4 int',
'4' => '4 string',
5 => '5 int',
'5' => '5 string',
};
echo "<br>";
}
test(1);
test('1');
test(2);
test('2');
test(3);
test('3');
test(4);
test('4');
test(5);
test('5');
echo '<br>5.9
<br> - - -<br>';
function print_bool($bool) {
echo match ($bool) {
false,
0,
=> "false<br>",
true,
1,
=> "true<br>",
default,
=> "not bool<br>",
};
}
print_bool(false);
print_bool(0);
print_bool(true);
print_bool(1);
print_bool(2);
print_bool('foo');
echo ' - - -<br>';
?>
RESULT
5.1
- - -
bool(false)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(false)
5.2
- - -
string(3) "foo"
string(3) "foo"
5.3
- - -
string(3) "int"
string(3) "int"
5.4
- - -
string(1) "0"
string(11) "Not matched"
string(1) "1"
string(11) "Not matched"
string(1) "2"
string(11) "Not matched"
string(1) "3"
string(11) "Not matched"
string(1) "4"
string(11) "Not matched"
string(1) "5"
string(11) "Not matched"
string(1) "6"
string(11) "Not matched"
string(1) "7"
string(11) "Not matched"
string(1) "8"
string(11) "Not matched"
string(1) "9"
string(11) "Not matched"
int(0)
string(11) "Not matched"
int(1)
string(11) "Not matched"
int(2)
string(11) "Not matched"
int(3)
string(11) "Not matched"
int(4)
string(11) "Not matched"
int(5)
string(11) "Not matched"
int(6)
string(11) "Not matched"
int(7)
string(11) "Not matched"
int(8)
string(11) "Not matched"
int(9)
string(11) "Not matched"
5.5
- - -
true
5.6
- - -
false
5.7
- - -
1
2, 1
1, 1
1
2, 1
1, 1
5.8
- - -
1 int
1 string
2 int
2 string
3 int
3 string
4 int
4 string
5 int
5 string
5.9
- - -
false
false
true
true
not bool
not bool
- - -
The above results are displayed when the PHP version is 8.0.0 or higher.
When in previous versions, precisely because match is not defined Parse error ... is then displayed.
EXERCISE
<?php
echo ' - - - <br>';
assert((function () {
match ('foo') {
'foo', 'bar' => false,
'baz' => 'a',
default => 'b',
};
})());
echo ' - - -<br>';
?>
EXERCISE
<?php
echo ' - - - <br>';
// opcache can't be certain
// Test::usesRef is actually this method
if (!class_exists('Test')) {
class Test {
public static function usesRef(&$x) {
$x = 'modified';
}
public static function usesValue($x) {
echo "usesValue $x<br>";
}
}
}
function main() {
$i = 0;
Test::usesValue(match(true) { true => $i });
echo "i is $i<br>";
$j = 1;
Test::usesRef(match(true) { true => $j });
echo "j is $j<br>";
}
main();
echo ' - - -<br>';
?>
EXERCISE
<?php
echo ' - - - <br>';
// opcache can't be certain
// Test::usesRef is actually this method
if (!class_exists('Test')) {
class Test {
public static function usesRef(&$x) {
$x = 'modified';
}
public static function usesValue($x) {
echo "usesValue $x<br>";
}
}
}
function main(int $i): int {
Test::usesValue(match(true) { true => $i });
Test::usesValue(match($i) { 42 => $i });
var_dump($i);
Test::usesRef(match(true) { true => $i });
var_dump($i);
}
try {
main(42);
} catch (Error $e) {
printf("Caught %s<br>", $e->getMessage());
};
echo ' - - -<br>';
?>
EXERCISE
<?php
echo ' - - - <br>';
set_error_handler(function ($errno, $message) {
throw new Exception("Custom error handler: $message");
});
echo match ($undefVar) {
default => "This should not get printed
with or without opcache<br>",
1, 2, 3, 4, 5 => "Also should not be printed<br>",
};
echo "unreachable<br>";
echo ' - - -<br>';
?>
EXERCISE
<?php
echo ' - - - <br>';
try {
var_dump(match(true) {
1, 2, 3, 4, 5 => 'foo',
});
} catch (Error $e) {
var_dump((string) $e);
}
echo '<br><br>';
try {
var_dump(match(6) {
1, 2, 3, 4, 5 => 'foo',
});
} catch (Error $e) {
var_dump((string) $e);
}
echo '<br><br>';
try {
var_dump(match('3') {
1, 2, 3, 4, 5 => 'foo',
});
} catch (Error $e) {
var_dump((string) $e);
}
echo '<br><br>';
var_dump(match(3) {
1, 2, 3, 4, 5 => 'foo',
});
echo '<br><br>';
var_dump(match(true) {
1, 2, 3, 4, 5 => 'foo',
default => 'bar',
});
echo '<br><br>';
var_dump(match(6) {
1, 2, 3, 4, 5 => 'foo',
default => 'bar',
});
echo '<br><br>';
var_dump(match('3') {
1, 2, 3, 4, 5 => 'foo',
default => 'bar',
});
echo '<br><br>';
var_dump(match(3) {
1, 2, 3, 4, 5 => 'foo',
default => 'bar',
});
echo '<br>- - -<br>';
?>
EXERCISE
<?php
echo ' - - - <br>';
match (1) {
default => 'foo',
1 => 'bar',
2 => 'baz',
default => 'qux',
};
echo '<br>- - -<br>';
?>