Laravel中PHP match语句匹配失败问题求助
问题根源分析
你的$order->status返回的是NewOrderStatus类的实例对象,但你在match中使用的三个匹配项都和这个对象的类型/值不匹配。PHP的match是严格类型匹配(值和类型必须完全一致才会命中分支),所以所有分支都不触发,最终返回default的null。
逐个解释匹配失败原因:
OrderStatuses::New:这是OrderStatuses枚举的实例,和NewOrderStatus对象属于完全不同的类,类型不匹配,无法命中。NewOrderStatus::class:这是一个字符串(类的全限定名称),而你匹配的是对象实例,字符串和对象类型不符,无法命中。'new':这是字符串类型,同样和NewOrderStatus对象类型不符,无法命中。
可行解决方案
根据你的代码架构,以下几种方式都可以解决问题:
方案1:直接匹配对象类型(PHP 8.0+支持)
利用match可以匹配表达式的特性,用instanceof检查对象类型:
$status = $order->status; $newOrder = match(true) { $status instanceof NewOrderStatus => (new NewToPaidTransition)->execute($order), $status instanceof PendingOrderStatus => // 对应业务逻辑 // 其他状态分支... default => null, };
方案2:给状态类绑定枚举关联
在OrderStatus基类中定义抽象方法,让每个子类返回对应的OrderStatuses枚举实例,通过枚举值匹配:
// 修改OrderStatus基类 abstract class OrderStatus { protected Order $order; public function __construct(Order $order) { $this->order = $order; } // 定义抽象方法,子类必须实现 abstract public function getEnum(): OrderStatuses; } // NewOrderStatus子类实现 class NewOrderStatus extends OrderStatus { public function getEnum(): OrderStatuses { return OrderStatuses::New; } } // 匹配代码 $newOrder = match ($order->status->getEnum()) { OrderStatuses::New => (new NewToPaidTransition)->execute($order), OrderStatuses::Pending => // 对应业务逻辑 // 其他枚举分支... default => null, };
方案3:给状态类添加状态标识常量
在每个OrderStatus子类中定义对应的状态常量,通过常量值匹配:
// NewOrderStatus子类 class NewOrderStatus extends OrderStatus { public const STATUS = 'new'; } // PendingOrderStatus子类 class PendingOrderStatus extends OrderStatus { public const STATUS = 'pending'; } // 匹配代码 $newOrder = match ($order->status::STATUS) { 'new' => (new NewToPaidTransition)->execute($order), 'pending' => // 对应业务逻辑 // 其他状态值分支... default => null, };
内容的提问来源于stack exchange,提问作者MrCujo
相关产品推荐
相关产品推荐

