thinkphp6實現郵箱註冊功能的細節和程式碼
阿新 • • 發佈:2021-11-10
封裝傳送郵件功能
使用的是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', '登入成功');
}