向Laravel服务器发送ISO格式JSON日期时提示‘trailing data’问题
嘿,这个'trailing data'错误我之前碰到过好几次,基本都是Carbon日期解析失败导致的——Laravel尝试把你通过GraphQL传过来的日期字符串转成Carbon实例时,字符串里有Carbon认不出来的多余内容,或者格式完全不符合预期。结合你的模型代码,我给你梳理几个最靠谱的排查和解决方向:
1. 先查传入的日期格式对不对
Laravel的日期字段默认认的是Y-m-d H:i:s这种格式(比如2024-05-20 14:30:00),但如果你传的是带时区的ISO格式(比如2024-05-20T14:30:00+08:00)、带毫秒的格式(2024-05-20 14:30:00.123),甚至末尾带空格的字符串,都可能触发这个错误。
你可以先确认GraphQL请求里archivedAt的具体值是什么。如果是ISO这类非默认格式,有两种解决方式:
方式一:在模型里指定日期格式
要么给所有日期字段统一设置格式,要么单独给archivedAt做自定义解析:
class Contact extends Model { protected $table = 'Contacts'; protected $dates = [ 'createdAt', 'updatedAt', 'archivedAt' ]; // 全局指定ISO 8601格式,适配带时区的日期 protected $dateFormat = 'Y-m-d\TH:i:sP'; // 或者只为archivedAt写个自定义setter(处理赋值时的解析) public function setArchivedAtAttribute($value) { // 先把任意合法日期转成Laravel默认格式 $this->attributes['archived_at'] = \Carbon\Carbon::parse($value)->toDateTimeString(); } }
方式二:在GraphQL Resolver里预处理日期
如果你用的是Lighthouse这类GraphQL包,可以在Resolver里先把日期转成正确格式再传给模型:
public function updateContact($root, array $args) { if (isset($args['archivedAt'])) { // 把传入的日期转成Laravel能直接识别的格式 $args['archivedAt'] = \Carbon\Carbon::parse($args['archivedAt'])->toDateTimeString(); } return Contact::updateOrCreate(['id' => $args['id']], $args); }
2. 检查模型字段和数据库字段的命名对应
你的模型里用的是驼峰archivedAt,但Laravel默认会把模型的驼峰属性自动转成蛇形的数据库字段(也就是archived_at)。如果你的数据库里实际是驼峰的archivedAt,那得关掉这个自动转换:
class Contact extends Model { protected $table = 'Contacts'; protected $snakeAttributes = false; // 关闭驼峰转蛇形的自动映射 protected $dates = [ 'createdAt', 'updatedAt', 'archivedAt' ]; }
要是数据库字段确实是archived_at,那这个问题不大,但如果因为映射问题导致日期值没正确传递,也可能触发解析错误,这点可以顺便确认下。
3. 排查日期字符串里的多余字符
有时候前端传的日期会带多余的空格、引号或者其他奇怪字符,比如"2024-05-20 14:30:00 "(末尾多了个空格),Carbon一解析就会报'trailing data'。这种情况可以在setter里先做清理:
public function setArchivedAtAttribute($value) { // 先去掉首尾多余字符,再解析 $cleanDate = trim($value); $this->attributes['archived_at'] = \Carbon\Carbon::parse($cleanDate)->toDateTimeString(); }
优先从日期格式这个方向排查,这是最常见的诱因。如果还解决不了,把你GraphQL请求的JSON负载贴出来,我再帮你细查~
内容的提问来源于stack exchange,提问作者marked-down

