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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 20:45:23