请问如何优化这段代码

public function resetPassword($email,$verifyCode,$newPassword)
{
    $user = User::findByEmail($email)->first();
    if ($user) {
        $codeData = EmailVerifyLog::findByEmail($email)->get()->last();
        if($codeData){
            if ($codeData->verifyCode($verifyCode) && $codeData->notExpired()) {
                $user->updatePassword($newPassword);
                $codeData->updateToExpired();
                return true;
            }
        }
    }
    return false;
}

调用这个函数的是controller,这里需要用到User和EmailVerifyLog两个对象。
这里加了if判断对象是为了防止执行方法会报错。
但是这样每取一个对象就要判断一次,那就可能会有无数个if,我自己想到的方案有:
1、两个对象同时取同时判断,就少了一个if了,但是如果email不存在,可能会多执行一次查询
2、在控制器获取对象并判断,把对象传进来,这个函数就负责执行函数就行了
请问大家有没有其他方案?

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 18
JaguarJack
public function resetPassword($email,$verifyCode,$newPassword)
{
    $user = User::findByEmail($email)->first();

    if (! $user) {
     return false;
   }

   $codeData = EmailVerifyLog::findByEmail($email)->get()->last();

   if (! $codeData) {
      return false;
    }

   if ($codeData->verifyCode($verifyCode) && $codeData->notExpired()) {
          $user->updatePassword($newPassword);
          $codeData->updateToExpired();
          return true;
    }

    return false;
}

尽量提前 return

1年前 评论
24K大白羊 1年前
ModStart 1年前
WindyLater 1年前
寞小陌 1年前
   public function resetPassword($email, $verifyCode, $newPassword)
    {
        // 1 换一种写法
        // $user = User::findByEmail($email)->first();
        $user = User::findByEmail($email)->firstOrFail();
        // 2 千万别 get 在 last, 那样子等于从数据库获取所有可能一千条, 然后在 PHP 从数组的 1000 个取一个
        // $codeData = EmailVerifyLog::findByEmail($email)->get()->last();
        $codeData = EmailVerifyLog::findByEmail($email)->latest()->first();

        if (!$codeData->verifyCode($verifyCode) || !$codeData->notExpired()) {
            return false;
        }

        // update 应该返回成功或者失败,建议上事务
        return $user->updatePassword($newPassword) && $codeData->updateToExpired();
    }
1年前 评论

自定义validator,查询用户是否存在,或者查询邮件里验证码是否和入参一致其他地方应该也能用到

1年前 评论

$user = User::findByEmail($email)->first(); 这个应该可以在验证器里面验证

$codeData = EmailVerifyLog::findByEmail($email)->get()->last(); 放到中间件

1年前 评论

first可以优化为,嫌麻烦可以再封装一下

firstOr(function(){
    throw new Exception();
})

下面那个获取log直接倒序first就好了

$codeData = EmailVerifyLog::findByEmail($email)->orderBy('id')->firstOr(function(){
    throw new Exception();
});
1年前 评论

提前 return 掉

1年前 评论
JaguarJack
public function resetPassword($email,$verifyCode,$newPassword)
{
    $user = User::findByEmail($email)->first();

    if (! $user) {
     return false;
   }

   $codeData = EmailVerifyLog::findByEmail($email)->get()->last();

   if (! $codeData) {
      return false;
    }

   if ($codeData->verifyCode($verifyCode) && $codeData->notExpired()) {
          $user->updatePassword($newPassword);
          $codeData->updateToExpired();
          return true;
    }

    return false;
}

尽量提前 return

1年前 评论
24K大白羊 1年前
ModStart 1年前
WindyLater 1年前
寞小陌 1年前
Mutoulee

文档:快速入门《Laravel 9 中文文档》

$user = User::findByEmail($email)->firstOrFail();
1年前 评论

public function resetPassword($email,$verifyCode,$newPassword)
{
    $user = User::findByEmail($email)->first();
    if (!$user) {
        return false;
    }
    $codeData = EmailVerifyLog::findByEmail($email)->get()->last();
    if(!$codeData){
       return false;
    }
    if ($codeData->verifyCode($verifyCode) && $codeData->notExpired()) {
        $user->updatePassword($newPassword);
        $codeData->updateToExpired();
        return true;
    }
    return false;
}

判断条件不多的话,感觉没必要过分优化
$user = User::findByEmail($email)->first();只是查询存在的话可以换成 $user = User::findByEmail($email)->exists();和doesntExist();

1年前 评论
public function resetPassword($email,$verifyCode,$newPassword)
{
    $user = User::findByEmail($email)->first();
    if ($user && $codeData = EmailVerifyLog::findByEmail($email)->get()->last()) {
      // ..
    }
    return false;
}
1年前 评论
   public function resetPassword($email, $verifyCode, $newPassword)
    {
        // 1 换一种写法
        // $user = User::findByEmail($email)->first();
        $user = User::findByEmail($email)->firstOrFail();
        // 2 千万别 get 在 last, 那样子等于从数据库获取所有可能一千条, 然后在 PHP 从数组的 1000 个取一个
        // $codeData = EmailVerifyLog::findByEmail($email)->get()->last();
        $codeData = EmailVerifyLog::findByEmail($email)->latest()->first();

        if (!$codeData->verifyCode($verifyCode) || !$codeData->notExpired()) {
            return false;
        }

        // update 应该返回成功或者失败,建议上事务
        return $user->updatePassword($newPassword) && $codeData->updateToExpired();
    }
1年前 评论

最有必要优化的就是如下语句

EmailVerifyLog::findByEmail($email)->get()->last();

改为

EmailVerifyLog::findByEmail($email)->latest()->first();
1年前 评论
public function resetPassword($email, $verifyCode, $newPassword)
{
    // 建個 findLastEmail 的 scope
    if($codeData = EmailVerifyLog::findLastEmail($email)) {
        if (
            $codeData->verifyCode($verifyCode)
            && $codeData->notExpired()
            && $user = User::findFirstEmail($email) // 建個 findFirstEmail 的 scope
        ) {
            $user->updatePassword($newPassword);
            $codeData->updateToExpired();
            return true;
        }
    }

    return false;
}

考量的點在於,會先驗證 email,所以 email 相關的會先處理過關 之後才將 user 抓取出來做處理

1年前 评论
public function resetPassword($email, $verifyCode, $newPassword)
{
    $user = User::findByEmail($email)->first();
    if (! $user) {
        return false;
    }

    $codeData = EmailVerifyLog::findByEmail($email)->get()->last();
    if (! $codeData) {
        return false;
    }

    if (!$codeData->verifyCode($verifyCode)) {
        return false;
    }

    if (!$codeData->notExpired()) {
        return false;
    }

    DB::beginTransaction();
    try {
        $user->updatePassword($newPassword);
        $codeData->updateToExpired();
        DB::commit();
    } catch (\Throwable $e) {
        DB::rollBack();
        return false;
    }

   return true;
}
1年前 评论

如果需要返回true false 加个try catch

public function resetPassword($email,$verifyCode,$newPassword)
{
    $user = User::findByEmail($email)->firstOrFail();
    $codeData = EmailVerifyLog::findByEmail($email)->orderByDesc('id')->firstOrFail();
    if ($codeData->verifyCode($verifyCode) && $codeData->notExpired()) {
        $user->updatePassword($newPassword);
        $codeData->updateToExpired();
    }
}
1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!