Thinkphp8创建QQ邮箱通知器
准备项目
- Thinkphp8 需要php8上
- 需要QQ邮箱中生成的Key
- 需要安装驱动 phpmailer
申请QQ邮箱的key
QQ邮箱
点击设置到最低的账号与安全,点击安全设置后生成授权码,记住这个KEY,后面需要

准备Tp8的驱动以及配置文件
1
| composer require phpmailer/phpmailer
|
创建 config\email.php,需要
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <?php return [ 'Host' => 'smtp.qq.com', 'Username' => '', 'Password' => 'key(授权码)', 'Port' => 465, 'From_address' => '2022471677@qq.com', 'From_name' => '28.7Blog', 'Encryption' => 'ssl' ];
|
创建控制器
这里用一个简单的测试页面发送邮箱
1
| vim /etc/app/FeedBackController.php
|
代码如下(我的仅供参考,还是有很多需要更改的地方,首先这并不是最简单做法,我将数据保存到数据库了(这是我网站中代码的一部分),当然也不是最佳做法,我为了方便把模板放到php方法中了,不推荐!!!但是能用( ̄︶ ̄)↗
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
| <?php namespace app\controller;
use think\facade\{Db, Request, Config, Cookie, Log}; use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\Exception;
class FeedBackController { private $mailer; private $receiverEmail = "2022471677@qq.com";
public function __construct() { $this->mailer = new PHPMailer(true); }
/** * 处理用户反馈(API接口) */ public function feedback(): array { try { if (Request()->method() === 'OPTIONS') { return ['code' => 200, 'message' => 'OK']; } // 记录请求参数类型和值 $emailParam = Request()->param("email");//接收一个邮箱作为目的地, 这里目的地仍然是我 $suggestionParam = Request()->param("suggestion");
//准备需要发送的数据 $data = [ 'email' => $emailParam, 'suggestion' => $suggestionParam ]; // 验证需要的字段 if (empty($data['email']) || empty($data['suggestion'])) { return [ 'code' => 400, 'message' => '邮箱和建议内容不能为空', 'data' => null ]; }
// 验证邮箱格式 if (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)) { return [ 'code' => 400, 'message' => '邮箱格式不正确', 'data' => null ]; }
// 保存到数据库 $feedbackId = $this->saveToDatabase($data['email'], $data['suggestion']);
// 发送邮件通知 $this->sendEmailNotification($data['email'], $data['suggestion']);
return [ 'code' => 200, 'message' => '反馈提交成功,感谢您的建议!', 'data' => ['id' => $feedbackId] ];
} catch (\Exception $e) { return [ 'code' => 500, 'message' => '服务器内部错误:' . $e->getMessage(), 'data' => null ]; } }
/** * 保存反馈到数据库 */ private function saveToDatabase(string $email, string $suggestion): int { $userLocation = $this->getUserLocation(); $data = [ 'email' => $email, 'suggestion' => $suggestion, 'user_location' => $userLocation, 'ip_address' => Request::ip(), 'user_agent' => Request::server('HTTP_USER_AGENT', ''), 'created_at' => date('Y-m-d H:i:s') ];
// 检查数据库插入数据类型 foreach ($data as $key => $value) { if (is_array($value)) { throw new \RuntimeException("数据库字段{$key}不能是数组类型"); } }
return Db::name('user_feedback')->strict(false)->insertGetId($data); }
/** * 获取用户地理位置信息 */ private function getUserLocation(): string { //这是我预先GET到的地址 $location = Cookie::get("location_city") ?? "null"; // 确保返回字符串类型 if (is_array($location)) { return 'invalid_location'; } return (string)$location; }
/** * 发送邮件通知 */ private function sendEmailNotification(string $email, string $suggestion): void { try { $this->configureMailer();
// 检查收件人邮箱类型 if (is_array($this->receiverEmail)) { throw new \RuntimeException('收件人邮箱是数组类型: ' . var_export($this->receiverEmail, true)); } $this->mailer->addAddress($this->receiverEmail); $this->mailer->Subject = '用户反馈通知 - ' . date('Y-m-d H:i:s'); $htmlContent = $this->generateEmailContent($email, $suggestion); $this->mailer->isHTML(true); $this->mailer->Body = $htmlContent; $this->mailer->AltBody = strip_tags($htmlContent);
$this->mailer->send();
} catch (\Exception $e) { } }
/** * 生成邮件内容 */ private function generateEmailContent(string $email, string $suggestion): string { $userLocation = $this->getUserLocation(); $ipAddress = Request::ip(); return " <!DOCTYPE html> <html> <head> <meta charset=\"UTF-8\"> <title>用户反馈通知</title> <style> body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; } .container { max-width: 600px; margin: 0 auto; padding: 20px; } .header { background: #007bff; color: white; padding: 15px; text-align: center; } .content { background: #f9f9f9; padding: 20px; border: 1px solid #ddd; } .info { margin-bottom: 15px; } .label { font-weight: bold; color: #007bff; } .suggestion { background: white; padding: 15px; border-left: 4px solid #007bff; } </style> </head> <body> <div class=\"container\"> <div class=\"header\"> <h2>📧 用户反馈通知</h2> </div> <div class=\"content\"> <div class=\"info\"> <span class=\"label\">邮箱:</span> {$email} </div> <div class=\"info\"> <span class=\"label\">时间:</span> " . date('Y-m-d H:i:s') . " </div> <div class=\"info\"> <span class=\"label\">地理位置:</span> {$userLocation} </div> <div class=\"info\"> <span class=\"label\">IP地址:</span> {$ipAddress} </div> <div class=\"info\"> <span class=\"label\">建议内容:</span> </div> <div class=\"suggestion\"> " . nl2br(htmlspecialchars($suggestion)) . " </div> </div> </div> </body> </html> "; }
/** * 邮件服务配置校验 */ private function configureMailer(): void { $config = Config::get('email');
if (empty($config)) { throw new \RuntimeException('邮件配置未找到'); }
// 确保配置是数组 if (!is_array($config)) { throw new \RuntimeException('邮件配置格式错误,期望数组,实际是' . gettype($config)); }
// 检查必要的邮件配置项并验证类型 $requiredKeys = [ 'Host' => 'string', 'Username' => 'string', 'Password' => 'string', 'Encryption' => 'string', 'Port' => 'integer' ]; foreach ($requiredKeys as $key => $expectedType) { // 检查配置项是否存在 if (!isset($config[$key])) { throw new \RuntimeException("邮件配置缺少必要项: {$key}"); }
// 检查端口号的特殊情况 if ($key === 'Port') { // 允许端口号是字符串形式的数字,如"587" if (!is_int($config[$key]) && (!is_string($config[$key]) || !ctype_digit($config[$key]))) { throw new \RuntimeException("邮件配置项{$key}类型错误,期望整数,实际是" . gettype($config[$key])); } // 转换为整数 $config[$key] = (int)$config[$key]; } else { // 检查其他配置项的类型 if (gettype($config[$key]) !== $expectedType) { throw new \RuntimeException("邮件配置项{$key}类型错误,期望{$expectedType},实际是" . gettype($config[$key])); } } } // 设置发件人信息 $fromAddress = $config['From_address'] ?? $config['Username']; $fromName = $config['From_name'] ?? '28.7Blog';
// 验证发件人邮箱格式 if (!filter_var($fromAddress, FILTER_VALIDATE_EMAIL)) { throw new \RuntimeException("发件人邮箱格式不正确: {$fromAddress}"); }
try { $this->mailer->isSMTP(); $this->mailer->Host = $config['Host']; $this->mailer->SMTPAuth = true; $this->mailer->Username = $config['Username']; $this->mailer->Password = $config['Password']; $this->mailer->SMTPSecure = $config['Encryption']; $this->mailer->Port = $config['Port']; $this->mailer->setFrom($fromAddress, $fromName); $this->mailer->CharSet = 'UTF-8'; $this->mailer->SMTPDebug = 0; } catch (\Exception $e) { throw new \RuntimeException('邮件服务初始化失败: ' . $e->getMessage()); $this->mailer->SMTPDebug = 0; } catch (\Exception $e) { throw new \RuntimeException('邮件服务初始化失败: ' . $e->getMessage()); } } }
|
所以在刚才的代码中,最重要的配置,首先我们需要配置发送者以及接收,以及信息本身
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| private function sendEmailNotification(string $email, string $suggestion): void { try { $this->configureMailer();
// 检查收件人邮箱类型 if (is_array($this->receiverEmail)) { throw new \RuntimeException('收件人邮箱是数组类型: ' . var_export($this->receiverEmail, true)); } $this->mailer->addAddress($this->receiverEmail);//接收地址 $this->mailer->Subject = '用户反馈通知 - ' . date('Y-m-d H:i:s'); $htmlContent = $this->generateEmailContent($email, $suggestion); $this->mailer->isHTML(true);//Html格式 $this->mailer->Body = $htmlContent;//指向邮件内容(HTML格式的) $this->mailer->AltBody = strip_tags($htmlContent);//(清洗后的邮件内容)
$this->mailer->send();//发送数据
} catch (\Exception $e) { //当然这个错误可以是降级之类的 } }
|
如果上述代码正确的化,我会从前端接收用户的邮箱以及suggestion,将这些内容通过html格式化发送个我本人并记录到数据库

如果有什么不太明白的可以留言给我 https://www.kong.college/api/world/hot/news