You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Observer依赖注入异常:整数属性变为字符串类型

Laravel 11 + Filament:Observer中模型整数属性被转为字符串的问题分析

问题场景

在Laravel 11与Filament框架环境下,Payment模型的created事件Observer中,注入的$payment实例里,amount、days_added这类定义为整数类型的数据库字段,实际呈现为字符串类型。尝试通过模型的**属性转换(Attribute Casting)**配置未解决问题,最终调用refresh()方法重新从数据库拉取数据后,属性恢复为预期的整数类型。

相关代码

Payment Observer代码

class PaymentObserver implements ShouldHandleEventsAfterCommit
{
    /**
     * 处理Payment的"created"事件。
     */
    public function created(Payment $payment): void
    {
        $payment->refresh(); // 调用refresh()后属性恢复为整数类型
        $barbershop = Barbershop::find($payment->barbershop_id);
        $barbershop->status = BarbershopStatusEnum::ACTIVE;
        $barbershop->expired_date = Carbon::now()->addDays($payment->days_added);
        $barbershop->save();
    }
}

Filament创建Payment的Action代码

->action(function(Barbershop $barbershop, array $data){
    try{
        $data['user_id'] = Auth::user()->id;
        $barbershop->payments()->create($data);
        Notification::make()->title('Saved successfully')->success()->send();
    }catch(Exception $e){
        Notification::make()->title('Save Failed! ' . $e->getMessage())->danger()->send();
    }
})

原因分析

  1. Filament表单输入特性:Filament表单提交的数值类输入默认以字符串类型传递到$data数组中,当通过create($data)创建模型时,Laravel会直接将这些字符串值赋值给模型属性,此时模型实例的属性值保留了原始输入的类型。
  2. 属性转换触发时机:模型的$casts配置通常在从数据库读取数据或显式调用属性访问器时生效。刚创建的模型实例(未调用refresh())的属性值来自提交的原始数据,并未经过数据库返回值的类型转换,因此即使配置了属性转换,也可能未触发类型转换逻辑。
  3. refresh()的作用:调用refresh()会重新从数据库查询该模型记录,此时数据库返回的整数类型字段会被Laravel自动转换为PHP整数类型,从而修正属性类型不符的问题。

结论

该问题并非框架Bug,而是业务代码与框架特性的适配问题:

  • 若已配置模型属性转换但未生效,需检查$casts配置是否正确(例如确认字段名拼写、类型是否匹配);
  • 若表单输入的字符串类型值未被模型转换,可在Filament表单层对字段设置类型约束(例如使用numeric()规则),或在创建模型前手动转换$data中的数值类型;
  • 调用refresh()是快速解决问题的方案,但本质是通过重新拉取数据库数据来修正属性类型。

内容的提问来源于stack exchange,提问作者Junaris Alf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 23:35:13