1. 程式人生 > 其它 >thinkphp6實現郵箱註冊功能的細節和程式碼

thinkphp6實現郵箱註冊功能的細節和程式碼

封裝傳送郵件功能

使用的是PHPMailer包

//郵件傳送
if (!function_exists('sendmail')) {
    function sendmail($address, $title, $body)
    {
        $mail = new \PHPMailer\PHPMailer\PHPMailer(true);
        try {
            $mail->SMTPDebug = 0;
            $mail->isSMTP();
            $mail->CharSet = "UTF-8";                     //utf-8;
            $mail->Encoding = "base64";
            $mail->Host = env('mail.host');
            $mail->SMTPAuth = true;
            $mail->Username = env('mail.username');
            $mail->Password = env('mail.password');
            $mail->SMTPSecure = env('mail.encryption');
            $mail->Port = env('mail.port');

            //Recipients
            $mail->setFrom(env('mail.from_address'), env('mail.from_name'));
            //接收人
            $mail->addAddress($address);
            //回覆的時候回覆給哪個郵箱 建議和發件人一致
            $mail->addReplyTo(env('mail.from_address'), 'info');
            //Content
            $mail->isHTML(true);
            //防止中文亂碼
            $mail->Subject = "=?UTF-8?B?" . base64_encode($title) . "?=";
            $mail->Body = $body;
            $mail->AltBody = '您的郵箱客戶端不支援顯示HTML內容';

            $mail->send();
            return true;

        } catch (Exception $e) {
            return $e;
        }
    }

}

2.使用

sendmail('[email protected]', '系統通知', '<h1>你好啊</h1>');

3.使用think-queue訊息佇列傳送郵件


//前面的註冊邏輯省略...


//快取key(此處可以替換為redis等nosql快取產品)
//引數說明 
//引數1:快取標誌register_email_code_+使用者註冊入庫時返回的主鍵id作為快取key
//引數2:uuid當作快取值進行快取
//引數3:快取過期時間(這裡我從我的配置檔案中讀取,你可以直接設定值,單位:秒),24 * 60 * 60
cache("register_email_code_" . $user->id, $uuid, config('my.email_register.expire'));


            //非同步傳送郵箱
            //把需要的資料傳遞過去
            Queue::push(RegEmailActiveJob::class, [
                'user_id' => $user->id,
                //暱稱
                'nickname' => $user->profile->nickname,
                //uuid
                'uuid' => $uuid,
                //發給誰
                'email' => $user->email
            ]);

生成RegEmailActiveJob非同步任務

<?php


namespace app\job;



use think\queue\Job;

class RegEmailActiveJob
{
    public function fire(Job $job, $data)
    {

        $user_id = $data['user_id'];
        $nickname = $data['nickname'];
        $uuid = $data['uuid'];
        $email = $data['email'];

        $link = env('app.host') . '/validate/email?user_id=' . $user_id . '&code=' . $uuid;

        //smarty替換變數後返回html內容
        $html = app('smarty')->fetch('index/email/regEmailActive.tpl', compact('nickname', 'link'));

        //傳送郵件
        sendmail($email, config('my.email_register.title'), $html);

        if ($job->attempts() > 3) {
            //通過這個方法可以檢查這個任務已經重試了幾次了
//            Log::info("超過三次");

        }


        //如果任務執行成功後 記得刪除任務,不然這個任務會重複執行,直到達到最大重試次數後失敗後,執行failed方法
        $job->delete();

        // 也可以重新發布這個任務
        //$job->release(0); //$delay為延遲時間

    }

    public function failed($data)
    {

        // ...任務達到最大重試次數後,失敗了

    }


}

uuid生成方法

//生成uuid
if (!function_exists('uuid')) {
    function uuid($prefix = '')
    {
        $chars = md5(uniqid(mt_rand(), true));
        $uuid = substr($chars, 0, 8);
        $uuid .= substr($chars, 8, 4);
        $uuid .= substr($chars, 12, 4);
        $uuid .= substr($chars, 16, 4);
        $uuid .= substr($chars, 20, 12);
        return $prefix . $uuid;
    }
}

傳送成功後用戶點選連線的處理

驗證成功後你可以直接登入,你也可以跳轉回登入頁,讓使用者登入

    //郵箱註冊連結回撥
    public function email(Request $request)
    {

        //接收引數
        $user_id = $request->get('user_id');
        $code = $request->get('code');


        if ($user_id === null || $code === null) {

            return $this->smarty->display('index/error/error.tpl', [
                'msg' => '啟用地址非法',
                'code' => 500
            ]);

        }

        //判斷快取中取出來的是否和傳遞過來的是否相等
        if (cache('register_email_code_' . $user_id) != $code) {
            return $this->smarty->display('index/error/error.tpl', [
                'msg' => '啟用地址已失效',
                'code' => 500
            ]);
        }


        //上面那一步過不來就等於是非法了,到這一步其實就已經可以直接更新狀態了
        $user = User::with(['profile'])->find($user_id);

        $user->status = 1;

        $user->save();

        //讓快取失效
        cache('register_email_code_' . $user_id, null);

        //直接登入
        session('index_user', $user);
        return redirect((string)url('/'))->with('success', '登入成功');
    }