
PHP 有switch语句,可以根据不同的情况执行不同的代码块。自 PHP 8.0 以来,我们可以使用与switch语句类似的match表达式。
match 表达式允许你将一个值与多个条件进行比较,并返回给定的结果(尽管不一定必须返回结果)。它类似于 switch 语句,因为你可以基于不同条件定义“分支”。
然而,一个关键区别是 match 表达式使用严格比较(===),而 switch 语句使用宽松比较(==)。
假设我们有switch语句,根据错误代码打印一条消息。
$errorCode = 2;
switch ($errorCode) {
case1:
echo'Access denied';
break;
case2:
echo'Incorrect password';
break;
case3:
echo'Invalid format';
break;
}
这段代码可以使用match表达式重写如下:
$errorCode = 2;
echo match ($errorCode) {
1 => 'Access denied',
2 => 'Incorrect password',
3 => 'Invalid format',
};
让我们来看一个基本示例,假设我们想根据用户的角色设置一条消息:
// 假设我们已经从数据库中检索了用户
$user = User::find(1);
$message = match ($user->role) {
'admin' => '欢迎,管理员!',
'user' => '你好,用户!',
default => '你好,访客!',
};
echo $message;
在这里,我们定义了三个分支:两个精确匹配和一个默认分支。如果 $user->role 匹配 'admin',它将返回相应的消息。
match 表达式的强大之处在于,你可以在分支中使用条件。这允许你在 match 语句的分支中评估条件。
例如:
$status = match (true) {
$order->isPending() => '待处理',
$order->isShipped() => '已发货',
$order->isDelivered() => '已交付',
default => '未知状态',
};
注意,我们在这里匹配 true,这允许每个分支评估一个条件。只有第一个为真的分支将被执行。
我发现 match 表达式与 PHP 枚举搭配得特别好。
假设我们有一个表示用户状态的枚举:
enum UserStatus: string
{
case Active = 'active';
case Inactive = 'inactive';
case Suspended = 'suspended';
}
现在,我们可以使用 match 来根据状态返回友好名称:
$status = UserStatus::Active;
$friendlyStatus = match ($status) {
UserStatus::Active => '活跃',
UserStatus::Inactive => '非活跃',
UserStatus::Suspended => '已暂停',
default => '未知',
};
在我的 opinion 中,将 match 表达式与枚举这样搭配是一种保持代码干净且易维护的好方法。我觉得它们配合得非常好。
另一个实用示例是使用 match 作为简单工厂来实例化驱动程序:
$driver = $_ENV['DB_DRIVER'] ?? 'mysql';
$db = match ($driver) {
'mysql', 'mariadb' => new MySQLDriver(),
'pgsql' => new PostgreSQLDriver(),
'sqlite' => new SQLiteDriver(),
default => throw new InvalidArgumentException("不支持的驱动: $driver"),
};
在上例中,我们定义了 4 个分支。前三个分支检查 $driver 变量是否匹配支持的驱动,如果是,则返回相应驱动类的实例。默认分支抛出异常。
希望这篇文章为你提供了 PHP 中 match 表达式的快速概述,以及一些实际示例,展示如何在自己的代码中使用它。
match 比 switch 更强大、更安全,因为它强制严格类型比较,并且可以直接返回结果,而无需额外的变量。
感谢阅读!如果这篇文章对你有帮助,请分享或订阅我的 newsletter 以获取更多 PHP 提示。