現在の言語: 日本語

戻る

match
判定関連

match 式においては、「数字以外(文字列など)を扱うことのデメリット」はほぼ解消されており、文字列でも積極的に使って問題ありません。
match 式は 「厳密な比較 (===)」 を行うため、型が違えば一致しません。
このため、文字列を扱っても型変換によるバグが起きる心配がなくなりました。
match は、条件がすべて整数や文字列の場合、
内部的に「ジャンプテーブル(ハッシュマップのようなもの)」として処理されるため、条件が増えても高速に動作します。
[PHP 7.2以降]
switch で文字列を使っても、内部で最適化されるようになりました。

[PHP 8.0以降]
match も同様に、文字列と整数のどちらを使っても高速に処理されます。

[match であえて「数字」を意識すべきケース]
以下のような場合は数字(あるいは Enum)を使うのが適切です。
状態(ステータス)の管理: HTTPステータスコード(200, 404など)や、
データベース上のフラグ(0: 停止, 1: 稼働)をあつかうケース
Enum(列挙型)の利用: PHP 8.1以降であれば、数字や文字列を直接使う代わりに
Enum を match で使うのが、推奨されます。

[サンプル]

copy
class test1
{
	function test1(int $kind, int $num1, int $num2):int
	{
		$result = 0;
		$result = match (true)
		{
			$kind === 0 => $num1 + $num2,
			$kind === 1 => $num1 - $num2,
			$kind === 2 => $num1 * $num2,
			default => $num1 / $num2,
		};
		return $result;
	}
	function test2($data):string
	{
		$result = "";
		try
		{
			$result = match($data)
			{
				1 => "num",
				"1" => "string",
				default => $this->judgeTest2(),
			};
		}
		catch (Exception $e)
		{
			$result = $e->getMessage();
		}
		return $result;
	}
	private function judgeTest2(){ return "test2 match error";}
	function test3():void
	{
		try 
		{
			$value = 3;
			$result = match ($value) 
			{
				1 => "success",
				default => throw new Exception("test3 match error"),
			};
			echo "this won't run.";
		} catch (Exception $e) {
			echo "error caught : " . $e->getMessage();
		}
		
		echo "this will run."; // プログラムは続行している
	}
	function test4():void
	{
		$status= "error";
		$result = match($status)
		{
			"success" => true,
			"error" => false,
			default => null,
		};
		if($result === false)
		{
			//matchで処理を終了させるケース
			exit("match end");
		}
	}
}
echo "<pre>";
$cls1= new test1();
echo $cls1->test1(0, 10, 2).PHP_EOL;//12
echo $cls1->test1(1, 10, 2).PHP_EOL;//8
echo $cls1->test1(2, 10, 2).PHP_EOL;//20
echo $cls1->test1(3, 10, 2).PHP_EOL;//5
echo "----------".PHP_EOL;
echo $cls1->test2(1).PHP_EOL;//num
echo $cls1->test2("1").PHP_EOL;//string
echo $cls1->test2(0).PHP_EOL;//test2 match error
//$cls1->test3();
//[test3を実行した場合は下記のログが出力されます]
/*
error caught : test3 match error
this will run.
*/
$cls1->test4();//match end
echo "</pre>";
copy
class test1
{ 
	function test1(int $kind, int $num1, int $num2):int 
	{ 
		$result = 0; 
		$result = match (true) 
		{ 
		$kind === 0 => $num1 + $num2, 
		$kind === 1 => $num1 - $num2, 
		$kind === 2 => $num1 * $num2, 
		default => $num1 / $num2, 
		}; 
		return $result; 
	} 
	function test2($data):string 
	{ 
		$result = ""; 
		try 
		{ 
			$result = match($data) 
			{ 
				1 => "num", 
				"1" => "string", 
				default => $this->judgeTest2(), 
			}; 
		} 
		catch (Exception $e) 
		{ 
			$result = $e->getMessage(); 
		} 
		return $result; 
	} 
	private function judgeTest2(){ return "test2 match error";}
	function test3():void
	{
		try
		{
			$value = 3;
			$result = match ($value)
			{
				1 => "success",
				default => throw new Exception("test3 match error"),
			};
			echo "this won't run.";
		} catch (Exception $e) {
			echo "error caught: " . $e->getMessage();
		}
		
		echo "this will run."; // The program continues.
	}
	function test4():void
	{
		$status= "error";
		$result = match($status)
		{
			"success" => true,
			"error" => false,
			default => null,
		};
		if($result === false)
		{
			//End processing with match
			exit("match end");
		}
	}
}
echo "<pre>";
$cls1= new test1();
echo $cls1->test1(0, 10, 2).PHP_EOL;//12
echo $cls1->test1(1, 10, 2).PHP_EOL;//8
echo $cls1->test1(2, 10, 2).PHP_EOL;//20
echo $cls1->test1(3, 10, 2).PHP_EOL;//5
echo "----------".PHP_EOL;
echo $cls1->test2(1).PHP_EOL;//num
echo $cls1->test2("1").PHP_EOL;//string
echo $cls1->test2(0).PHP_EOL;//test2 match error
//$cls1->test3();
//[The following log is output when test3 is executed]
/*
error caught: test3 match error
this will run.
*/
$cls1->test4();//match end
echo "</pre>";
echo "</pre>";

種類 switch match
評価 ステートメント(Statement) 式(Expression)
比較 通常の比較(==) 型を含めた厳密な比較(===)
戻り値 なし あり
終了処理 breakが必要 不要(自動終了)
例外 一致なしでもエラーにならない 一致なしでdefaultがないと例外になる

test4
try-catch を使っている場合は、例外が発生した瞬間に
catchブロックへジャンプし、プログラムは停止せずに続行されます。


戻る

著作権情報
ホームページおよびアプリ等に掲載されている情報等については、いかなる保障もいたしません。
ホームページおよびアプリ等を通じて入手したいかなる情報も複製、販売、出版または使用させたり、
または公開したりすることはできません。
当方は、ホームページおよびアプリ等を利用したいかなる理由によっての障害等が発生しても、
その結果ホームページおよびアプリ等を利用された本人または他の第三者が被った損害について
一切の責任を負わないものとします。