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

解决Laravel中Jalali转Georgian日期后控制器获原日期的问题

问题根源

模型的setTaskDateAttribute是Eloquent赋值修改器,它仅在给模型的TaskDate属性赋值(比如$task->TaskDate = $value或调用Task::create($attributes))时触发,自动转换值并存入数据库字段。它不会修改请求对象($request)里的原始数据,所以控制器中dd($request->TaskDate)看到原始Jalali日期是正常现象,但你存不进转换后日期的原因是:

  1. 控制器里的dd($request->TaskDate)直接终止了程序,后续模型写入逻辑根本没执行;
  2. 你的TaskService的create方法可能绕过了Eloquent模型,直接用DB门面操作数据库,导致修改器未被触发。

解决方案

1. 移除控制器中的终止代码,让流程执行到模型写入

控制器里的dd会打断程序,删掉它才能触发模型的修改器逻辑:

public function store(taskRequestStore $request,TaskService $service)
{
   // 移除这行终止代码
   // dd($request->TaskDate);
   // 建议用only替代all,更精准获取所需字段
   $attributes = $request->only(['office_id','TaskDate','Type','Priority_id']);
   // 变量名修正为$task,和业务逻辑匹配
   $task = $service->create($attributes);
}

2. 确保Service的create方法正确使用Eloquent模型

检查TaskService的create方法,必须通过Eloquent模型创建数据,才能触发修改器:

// TaskService.php 正确实现
public function create(array $attributes)
{
    // 调用模型的create方法,自动触发setTaskDateAttribute
    return \App\Models\Task::create($attributes);
}

如果是以下这种直接操作数据库的写法,会绕过模型修改器,必须改掉:

// 错误示例:避免直接用DB门面插入
public function create(array $attributes)
{
    return DB::table('tasks')->insert($attributes);
}

3. (可选)在请求类中提前转换日期

如果需要在控制器中直接拿到转换后的日期,可以在请求类的prepareForValidation方法中处理:

// app/Http/Requests/taskRequestStore.php
public function prepareForValidation()
{
    $rawDate = $this->input('TaskDate');
    $convertedDate = CalendarUtils::convertNumbers($rawDate, true);
    $convertedDate = CalendarUtils::createCarbonFromFormat('Y-m-d', $convertedDate)->format('Y-m-d');
    // 将转换后的数据合并到请求中
    $this->merge(['TaskDate' => $convertedDate]);
}

这种方式和模型修改器二选一即可,推荐用模型修改器,因为转换逻辑放在模型里更符合职责分离原则。


额外注意

  • 模型里的dd($this->TaskDate)必须删掉,否则每次赋值都会终止程序,无法完成写入;
  • 检查变量名一致性:控制器中的$office应该改为$task,避免业务逻辑混淆。

内容的提问来源于stack exchange,提问作者mahdi.gh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 05:11:30