本文將結合實例,講解如何使用thinkphp5+Mysql完成注冊帳號、發送激活郵件、驗證激活帳號、處理URL鏈接過期的功能。
業務流程
1、用戶提交注冊信息。
2、寫入數據庫,此時帳號狀態未激活。
3、將用戶名密碼或其他標識字符加密構造成激活識別碼(你也可以叫激活碼)。
4、將構造好的激活識別碼組成URL發送到用戶提交的郵箱。
5、用戶登錄郵箱並點擊URL,進行激活。
6、驗證激活識別碼,如果正確則激活帳號。
准備數據表
用戶信息表中字段Email很重要,它可以用來驗證用戶、找回密碼、甚至對網站方來說可以用來收集用戶信息進行Email營銷,以下是用戶信息表cmf_email的表結構:

CREATE TABLE `cmf_email` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`email` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '郵箱',
`email_password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '郵箱注冊碼',
`token` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '賬戶激活碼',
`token_exptime` int(10) NULL DEFAULT NULL COMMENT '激活碼有效期',
`status` tinyint(1) NULL DEFAULT 0 COMMENT '狀態,0=未激活,1=已激活',
`regtime` int(10) NULL DEFAULT NULL COMMENT '注冊時間',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = MyISAM AUTO_INCREMENT = 25 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '//---前台郵箱注冊' ROW_FORMAT = Dynamic;

在框架中下載phpmailer包
1.composer require phpmailer/phpmailer
2.在控制器中引入類
use PHPMailer\PHPMailer\PHPMailer

3步驟

<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: Powerless < wzxaini9@gmail.com>
// +----------------------------------------------------------------------
namespace app\user\controller;
use cmf\controller\HomeBaseController;
use think\Db;
use think\facade\Validate;
use app\user\model\UserModel;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
class RegisterController extends HomeBaseController
{
/**
* 前台用戶注冊
*/
public function index()
{
return $this->fetch('register');
}
//發送qq郵箱
/*
* @param
* $address_email --收件人郵箱
* $active_url ---激活地址
* $token --- 賬戶激活碼
* $email_password --郵箱密碼
* **/
public function setEmail($address_email, $token, $active_url, $email_password)
{
$sendmail = '135xxx7@qq.com'; //發件人郵箱
//$sendmailpswd = "cbllxxxxxxxhdbc"; //客戶端授權密碼,而不是郵箱的登錄密碼!
$sendmailpswd = "olbzxxxxhpqjbfc"; //客戶端授權密碼,而不是郵箱的登錄密碼!
$send_name = '悅桔拉拉商城';// 設置發件人信息,如郵件格式說明中的發件人,
$toemail = $address_email;//定義收件人的郵箱
$to_name = '小號';//設置收件人信息,如郵件格式說明中的收件人
$mail = new PHPMailer();
$mail->isSMTP();// 使用SMTP服務
$mail->CharSet = "utf8";// 編碼格式為utf8,不設置編碼的話,中文會出現亂碼
$mail->Host = "smtp.qq.com";// 發送方的SMTP服務器地址
$mail->SMTPAuth = true;// 是否使用身份驗證
$mail->Username = $sendmail;//// 發送方的
$mail->Password = $sendmailpswd;//客戶端授權密碼,而不是郵箱的登錄密碼!
$mail->SMTPSecure = "ssl";// 使用ssl協議方式
$mail->Port = 465;// qq端口465或587)
// $mail->setFrom($sendmail,$send_name);// 設置發件人信息,如郵件格式說明中的發件人,
$mail->setFrom($sendmail, $send_name);
$mail->addAddress($toemail, $to_name);// 設置收件人信息,如郵件格式說明中的收件人,
$mail->addReplyTo($sendmail, $send_name);// 設置回復人信息,指的是收件人收到郵件后,如果要回復,回復郵件將發送到的郵箱地址
//$mail->addCC("xxx@qq.com");// 設置郵件抄送人,可以只寫地址,上述的設置也可以只寫地址(這個人也能收到郵件)
//$mail->addBCC("xxx@qq.com");// 設置秘密抄送人(這個人也能收到郵件)
//$mail->addAttachment("bug0.jpg");// 添加附件
$mail->Subject = "悅桔拉拉商城,激活郵箱";// 郵件標題
// $mail->Body = "郵件內容是 <b>您的驗證碼是:123456</b>,哈哈哈!";// 郵件正文
$mail->Body = "恭喜您,注冊成功!請點擊鏈接激活您的帳戶:" . "$active_url" . "$token" . "
如果以上鏈接無法點擊,請將它復制到你的瀏覽器地址欄中進入訪問,該鏈接24小時內有效。";// 郵件正文
//$mail->AltBody = "This is the plain text純文本";// 這個是設置純文本方式顯示的正文內容,如果不支持Html方式,就會用到這個,基本無用
$token_exptime = time() + 60 * 60 * 24;//過期時間為24小時后
if (!$mail->send()) {// 發送郵件
$this->error('郵箱注冊失敗!請檢查郵箱號碼是否正確', url('user/register/index'));
} else {
//將郵箱與密碼寫入數據庫
$data = [
'email' => $address_email,
'email_password' => $email_password,
'token' => $token,
'regtime' => time(),
'token_exptime' => $token_exptime,
];
$res = Db::name('email')->insert($data);
if ($res) {
$this->success('恭喜您,注冊成功!<br/>請登錄到您的郵箱及時激活您的帳號,然后進行登錄!', url('user/login/index'));
}
}
}
//前台注冊頁面,用戶點擊提交,跳轉到控制器里面的add方法
public function add()
{
if ($this->request->isPost()) {
$rules = [
'email' => $this->request->param('email'),
'email_password' => cmf_password($this->request->param('email_password'), $authCode = 'yjllshop'),
];
$nowtime = time(); //當前時間
//對於是否已經注冊用戶進行判斷
$res = Db('email')->where('email', $rules['email'])->find();
if ($res) {
if ($nowtime > $res['token_exptime']) {
$this->error('您的激活有效期已過,請登錄您的帳號重新發送激活郵件', url('user/register/index'));
} else {
$this->success('您已經注冊過,請直接登錄!', url('user/login/index'));
}
}
//dump($rules);die;
//激活地址--對應激活方法
$active_url = 'http://www.yjllshop.com/user/register/valRegister?token=';
//調用生產token方法
$token = $this->makeToken($rules['email']);
$this->setEmail($rules['email'], $token, $active_url, $rules['email_password']);
}
}
//制作token
public function makeToken($email)
{
$regtime = time();
$num = rand(0, 100);//一段隨機數字
$md5Num = md5($regtime . $num . $email);
$token = base64_encode(md5($md5Num)); //創建用於激活識別碼
return $token;
}
//郵箱激活方法--並且將郵箱的各個信息存放數據庫
public function valRegister()
{
//$token
$nowtime = time(); //當前時間
if ($this->request->isGet()) {
$token = $this->request->param('token');
//將條件token值與status=0狀態值帶入數據庫查詢,如果能查到,在判斷時間是夠是過期,就進行激活操作,改變激活碼
$res = Db('email')
->where('status', 0)
->where('token', $token)->find();
//dump($res);
/// dump($res['token_exptime']);die;
if ($res) {
if ($nowtime > $res['token_exptime']) {
$this->error('您的激活有效期已過,請登錄您的帳號重新發送激活郵件', url('user/register/index'));
} else {
Db::name('email')->where('token', $token)->setField('status', 1);
$this->success('恭喜您,激活成功!<br/>請進行登錄!', url('user/login/index'));
}
} else {
$this->error('郵箱注冊失敗!請檢查郵箱號碼是否正確', url('user/register/index'));
}
}
//Db::name('email')->insert($user);
}
}
客戶端的授權碼

注冊完成后的數據庫

