
在 Laravel 9 + PHP 8.1 中,当模型字段使用字符串枚举(enum)并配置了 $casts 后,资源类中直接访问该字段会返回对象而非原始值;需显式调用 ->value 获取底层字符串,否则 JSON 序列化将输出空数组。
在 laravel 9 + php 8.1 中,当模型字段使用字符串枚举(`enum`)并配置了 `$casts` 后,资源类中直接访问该字段会返回对象而非原始值;需显式调用 `->value` 获取底层字符串,否则 json 序列化将输出空数组。
当你将 Eloquent 模型的字段(如 status)声明为字符串枚举并配置 protected $casts = ['status' => OrderStatuses::class] 时,Laravel 会在读取属性时自动将数据库中的字符串值(如 'paid')转换为对应的枚举实例(如 OrderStatuses::Paid)。这本身是完全正确的——但问题出在后续的 序列化环节。
JsonResource 的 toArray() 方法最终会通过 PHP 的 json_encode() 输出响应。而默认情况下,枚举实例(如 OrderStatuses::Paid)不实现 JsonSerializable 接口,也没有定义 __toString(),因此 json_encode() 无法将其转换为有效 JSON 值,最终退化为一个空对象 {} —— 在数组上下文中则表现为 [](即你看到的 "status" => [])。
✅ 正确且简洁的解决方案是:在资源中显式访问枚举的 ->value 属性:
class OrdersResource extends JsonResource
{
public function toArray($request): array
{
return [
'id' => (string)$this->id,
'type' => 'orders',
'attributes' => [
'status' => $this->status->value, // ✅ 关键修复:获取原始字符串值
'payment_type' => $this->payment_type,
'payment_transaction_no' => $this->payment_transaction_no,
'subtotal' => $this->subtotal,
'taxes' => $this->taxes,
'total' => $this->total,
'items' => OrderItemsResource::collection($this->whenLoaded('orderItems')),
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
]
];
}
}
⚠️ 注意事项:
-
移除冗余的
Attribute访问器:你已在$casts中声明了OrderStatuses::class,Laravel 已能正确完成从数据库值到枚举实例的转换。额外定义的status()访问器不仅不必要,还可能引发冲突(例如它返回的是OrderStatus实例而非OrderStatuses枚举),这正是导致$this->status类型为PaidOrderStatus(而非OrderStatuses::Paid)的根本原因。请删除该访问器,确保模型字段返回的是纯枚举实例。 -
若你确实需要在资源中返回状态的语义化标签(如
'Paid'而非'paid'),可在枚举中添加label()方法:enum OrderStatuses: string { case New = 'new'; case Pending = 'pending'; case Canceled = 'canceled'; case Paid = 'paid'; case PaymentFailed = 'payment-failed'; public function label(): string { return match($this) { self::New => 'New', self::Pending => 'Pending', self::Canceled => 'Canceled', self::Paid => 'Paid', self::PaymentFailed => 'Payment Failed', }; } }然后在资源中使用
$this->status->label()。
总结:Laravel 枚举字段在资源中显示为空数组,本质是序列化失败。只需坚持“枚举用于类型安全,序列化时取 .value”这一原则,并清理掉干扰性的访问器逻辑,即可获得清晰、可靠、符合 REST 规范的 API 响应。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











