【PHP】match式とswitch文
match式について
・条件分岐に合致する値を返す。
・switchの場合には1対1で制約式を比較するが、matchは1対多で制約式を比較する。
・三項演算子のように値を評価する。
・制約式の比較は、厳密に型と値の一致をチェック(===)する。
・PHP 8.0.0 以降で利用可能。
・全ての場合を網羅している必要がある。
基本形とswitch文との比較
例えば、この場合の制約式は$food。$foodが条件式に合致すれば返却式を返します。制約式$foodがorangeなら、そこに合致するThis food is an orangeを返します。
また、どの条件にも合致しない場合、defaultを返します。
$foodが一つしかない場合に、一つ目のorangeの条件に合致すれば、以降の条件は呼び出されません。
<?php
$foods = [
'food1' => 'orange',
'food2' => 'melon',
];
foreach($foods as $res => $food){
$result[$res]['name'] = $food;
$result[$res]['msg'] = match ($food) {
'orange' => 'This food is an orange',
'bar' => 'This food is a bar',
'cake' => 'This food is a cake',
default => 'food not selected',
};
}
var_dump($result);
/*array(2) {
["food1"]=>
array(2) {
["name"]=>
string(6) "orange"
["msg"]=>
string(22) "This food is an orange"
}
["food2"]=>
array(2) {
["name"]=>
string(5) "melon"
["msg"]=>
string(17) "food not selected"
}
}*/
?>
これをswitch文に変えます。
$result[$res]['name'] = $food;
switch ($food) {
case 'orange':
$result[$res]['msg'] = 'This food is an orange';
break;
case 'bar':
$result[$res]['msg'] = 'This food is an bar';
break;
case 'cake':
$result[$res]['msg'] = 'This food is an cake';
break;
default:
$result[$res]['msg'] = 'food not selected';
}
出力結果は同じですが、switch文で行うのは緩やかな比較(==)です。
よって、以下の場合に違いが出ます。match式の場合には、厳密に比較(型も含めて)しているため、例えば、比較対象のintgerにstringが紛れてしまっている場合には、型が異なるためはじいてくれますが、switch文では緩やかな比較をしているため、そのまま通過してしまいます。
厳密に型チェックを行う場合には、match式を使用する方が良いように思います。
<?php
$numbers = [
'number1' => '0',
'number2' => 1,
];
foreach($numbers as $res => $number){
$result[$res]['name'] = $number;
$result[$res]['msg'] = match ($number) {
0 => 'This number is zero',
1 => 'This number is one',
2 => 'This number is two',
default => 'number not selected',
};
}
var_dump($result);
/*
array(2) {
["number1"]=>
array(2) {
["name"]=>
string(1) "0"
["msg"]=>
string(19) "number not selected"
}
["number2"]=>
array(2) {
["name"]=>
int(1)
["msg"]=>
string(18) "This number is one"
}
}
*/
?>
<?php
$numbers = [
'number1' => '0',
'number2' => 1,
];
foreach($numbers as $res => $number){
$result[$res]['name'] = $number;
switch ($number) {
case 0:
$result[$res]['msg'] = 'This number is zero';
break;
case 1:
$result[$res]['msg'] = 'This number is one';
break;
case 2:
$result[$res]['msg'] = 'This number is two';
break;
default:
$result[$res]['msg'] = 'number not selected';
}
}
var_dump($result);
/*
array(2) {
["number1"]=>
array(2) {
["name"]=>
string(1) "0"
["msg"]=>
string(19) "This number is zero"
}
["number2"]=>
array(2) {
["name"]=>
int(1)
["msg"]=>
string(18) "This number is one"
}
}
*/
?>