Laravel中Carbon时间比较报错:Unsupported operand types求助
验证码时间校验报错:Unsupported operand types: Illuminate\Support\Carbon - Illuminate\Support\Carbon
我写了一个signInWithToken方法,用来给用户手机号发送临时验证码验证账号:
public function signInWithToken() { if(Session::has('nextStep') && Session::has('foundUser')) { $user = User::where('usr_mobile_phone', Session::get('foundUser'))->first(); if(Session::has('codeSent')){ $nowTime = now(); $sentTime = Session::get('codeSent'); if($nowTime >= $sentTime){ $user->activeCode()->delete(); Session::forget('codeSent'); } }else{ $code = ActiveCode::generateCode($user); $user->notify(new ActiveCodeNotification($code, Session::get('foundUser'))); Session::put('codeSent', now()->addMinutes(10)); } return view('frontend.auth.token'); }else{ abort(404); } }
首次生成验证码时,会把codeSent存入会话,值是当前时间加10分钟。后续需要检查这个会话是否存在,判断当前时间是否超过会话里的时间,如果验证码生成超过10分钟,就删除数据库里的验证码并清除会话:
$nowTime = now(); $sentTime = Session::get('codeSent'); if($nowTime >= $sentTime){ $user->activeCode()->delete(); Session::forget('codeSent'); }
但执行时触发错误:Unsupported operand types: Illuminate\Support\Carbon - Illuminate\Support\Carbon
已知问题出在sentTime和nowTime无法直接运算,求正确的时间校验方式。
问题原因
把Carbon对象直接存入Session时,Laravel序列化存储后,取出时可能无法正确还原为Carbon实例,导致两个对象无法直接用>=运算符进行比较运算。
解决方案
提供两种可行处理方式:
方式一:存入时间戳而非Carbon对象
存入Session时将Carbon对象转为时间戳:
// 存入会话的代码修改为 Session::put('codeSent', now()->addMinutes(10)->getTimestamp());
校验时将当前时间也转为时间戳再比较:
$nowTime = now()->getTimestamp(); $sentTime = Session::get('codeSent'); if($nowTime >= $sentTime){ $user->activeCode()->delete(); Session::forget('codeSent'); }
方式二:取出时重新转为Carbon实例
如果坚持存储Carbon对象,取出时用Carbon::parse()还原实例,再用Carbon内置的比较方法:
$nowTime = now(); $sentTime = \Carbon\Carbon::parse(Session::get('codeSent')); if($nowTime->greaterThanOrEqualTo($sentTime)){ $user->activeCode()->delete(); Session::forget('codeSent'); }
也可以用更简洁的写法:
if(\Carbon\Carbon::now()->gte($sentTime)){ $user->activeCode()->delete(); Session::forget('codeSent'); }
内容的提问来源于stack exchange,提问作者Pouya Vaghefi
相关产品推荐
相关产品推荐

