使用的是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; } } }
sendmail('xxx@xx.xx', '系统通知', '<h1>你好啊</h1>');
//前面的注册逻辑省略... //缓存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', '登录成功'); }