1 | <?php |
||||||
2 | /** |
||||||
3 | * 邮件 |
||||||
4 | * |
||||||
5 | * @author mybsdc <[email protected]> |
||||||
6 | * @date 2019/5/12 |
||||||
7 | * @time 16:38 |
||||||
8 | */ |
||||||
9 | |||||||
10 | namespace Luolongfei\Lib; |
||||||
11 | |||||||
12 | use Luolongfei\App\Exceptions\LlfException; |
||||||
13 | use PHPMailer\PHPMailer\PHPMailer; |
||||||
14 | use PHPMailer\PHPMailer\Exception as MailException; |
||||||
15 | |||||||
16 | class Mail |
||||||
17 | { |
||||||
18 | /** |
||||||
19 | * @var PHPMailer |
||||||
20 | */ |
||||||
21 | protected static $mail; |
||||||
22 | |||||||
23 | /** |
||||||
24 | * @return PHPMailer |
||||||
25 | * @throws MailException |
||||||
26 | * @throws \Exception |
||||||
27 | */ |
||||||
28 | public static function mail() |
||||||
29 | { |
||||||
30 | if (!self::$mail instanceof PHPMailer) { |
||||||
31 | self::$mail = new PHPMailer(true); |
||||||
32 | |||||||
33 | // 邮件服务配置 |
||||||
34 | $username = config('mail.username'); |
||||||
35 | $password = config('mail.password'); |
||||||
36 | if (stripos($username, '@gmail.com') !== false) { |
||||||
37 | $host = 'smtp.gmail.com'; |
||||||
38 | $secure = 'tls'; |
||||||
39 | $port = 587; |
||||||
40 | } else if (stripos($username, '@qq.com') !== false) { |
||||||
41 | $host = 'smtp.qq.com'; |
||||||
42 | $secure = 'tls'; |
||||||
43 | $port = 587; |
||||||
44 | } else if (stripos($username, '@163.com') !== false) { |
||||||
45 | $host = 'smtp.163.com'; |
||||||
46 | $secure = 'ssl'; |
||||||
47 | $port = 465; |
||||||
48 | } else if (stripos($username, '@vip.163.com') !== false) { |
||||||
49 | $host = 'smtp.vip.163.com'; |
||||||
50 | $secure = 'ssl'; |
||||||
51 | $port = 465; |
||||||
52 | } else if (stripos($username, '@outlook.com') !== false) { |
||||||
53 | $host = 'smtp.office365.com'; |
||||||
54 | $secure = 'starttls'; |
||||||
55 | $port = 587; |
||||||
56 | } else { |
||||||
57 | throw new \Exception('不受支持的邮箱。目前仅支持谷歌邮箱、QQ邮箱以及163邮箱,推荐使用谷歌邮箱。'); |
||||||
58 | } |
||||||
59 | |||||||
60 | self::$mail->SMTPDebug = config('debug') ? 2 : 0; // Debug 0:关闭 1:客户端信息 2:客户端和服务端信息 |
||||||
61 | self::$mail->isSMTP(); // 告诉PHPMailer使用SMTP |
||||||
62 | self::$mail->Host = $host; // SMTP服务器 |
||||||
63 | self::$mail->SMTPAuth = true; // 启用SMTP身份验证 |
||||||
64 | self::$mail->Username = $username; // 账号 |
||||||
65 | self::$mail->Password = $password; // 密码或授权码 |
||||||
66 | self::$mail->SMTPSecure = $secure; // 将加密系统设置为使用 - ssl(不建议使用)或tls |
||||||
67 | self::$mail->Port = $port; // 设置SMTP端口号 - tsl使用587端口,ssl使用465端口 |
||||||
68 | self::$mail->CharSet = 'UTF-8'; // 防止中文邮件乱码 |
||||||
69 | self::$mail->setLanguage('zh_cn', VENDOR_PATH . '/phpmailer/phpmailer/language/'); // 设置语言 |
||||||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||||
70 | self::$mail->setFrom($username, 'im robot'); // 发件人 |
||||||
71 | } |
||||||
72 | |||||||
73 | return self::$mail; |
||||||
74 | } |
||||||
75 | |||||||
76 | /** |
||||||
77 | * 发送邮件 |
||||||
78 | * |
||||||
79 | * @param string $subject 标题 |
||||||
80 | * @param string | array $content 正文 |
||||||
81 | * @param string $to 收件人,选传 |
||||||
82 | * @param string $template 模板,选传 |
||||||
83 | * |
||||||
84 | * @return bool |
||||||
85 | * @throws \Exception |
||||||
86 | */ |
||||||
87 | public static function send($subject, $content, $to = '', $template = '') |
||||||
88 | { |
||||||
89 | if (config('mail.enable') === false) { |
||||||
90 | system_log('由于没有启用邮件功能,故本次不通过邮件送信。'); |
||||||
91 | |||||||
92 | return false; |
||||||
93 | } |
||||||
94 | |||||||
95 | $to = $to ?: config('mail.to'); |
||||||
96 | if (!$to) { |
||||||
97 | throw new LlfException(env('ON_GITHUB_ACTIONS') ? 34520011 : 34520012); |
||||||
98 | } |
||||||
99 | |||||||
100 | self::mail()->addAddress($to, config('mail.toName', '主人')); // 添加收件人,参数2选填 |
||||||
0 ignored issues
–
show
It seems like
$to can also be of type array ; however, parameter $address of PHPMailer\PHPMailer\PHPMailer::addAddress() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() It seems like
config('mail.toName', '主人') can also be of type array ; however, parameter $name of PHPMailer\PHPMailer\PHPMailer::addAddress() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
101 | self::mail()->addReplyTo(config('mail.replyTo', '[email protected]'), config('mail.replyToName', '作者')); // 备用回复地址,收到的回复的邮件将被发到此地址 |
||||||
0 ignored issues
–
show
It seems like
config('mail.replyToName', '作者') can also be of type array ; however, parameter $name of PHPMailer\PHPMailer\PHPMailer::addReplyTo() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() It seems like
config('mail.replyTo', '[email protected]') can also be of type array ; however, parameter $address of PHPMailer\PHPMailer\PHPMailer::addReplyTo() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
102 | |||||||
103 | /** |
||||||
104 | * 抄送和密送都是添加收件人,抄送方式下,被抄送者知道除被密送者外的所有的收件人,密送方式下, |
||||||
105 | * 被密送者知道所有的被抄送者,但不知道其它的被密送者。 |
||||||
106 | * 抄送好比@,密送好比私信。 |
||||||
107 | */ |
||||||
108 | // self::mail()->addCC('[email protected]'); // 抄送 |
||||||
109 | // self::mail()->addBCC('[email protected]'); // 密送 |
||||||
110 | |||||||
111 | // 添加附件,参数2选填 |
||||||
112 | // self::mail()->addAttachment('README.md', '说明.txt'); |
||||||
113 | |||||||
114 | // 内容 |
||||||
115 | self::mail()->Subject = $subject; // 标题 |
||||||
116 | |||||||
117 | /** |
||||||
118 | * 正文 |
||||||
119 | * 使用html文件内容作为正文,其中的图片将被base64编码,另确保html样式为内联形式,且某些样式可能需要!important方能正常显示, |
||||||
120 | * msgHTML方法的第二个参数指定html内容中图片的路径,在转换时会拼接html中图片的相对路径得到完整的路径,最右侧无需“/”,PHPMailer |
||||||
121 | * 源码里有加。css中的背景图片不会被转换,这是PHPMailer已知问题,建议外链。 |
||||||
122 | * 此处也可替换为: |
||||||
123 | * self::mail()->isHTML(true); // 设为html格式 |
||||||
124 | * self::mail()->Body = '正文'; // 支持html |
||||||
125 | * self::mail()->AltBody = 'This is an HTML-only message. To view it, activate HTML in your email application.'; // 纯文本消息正文。不支持html预览的邮件客户端将显示此预览消息,其它情况将显示正常的body |
||||||
126 | */ |
||||||
127 | $template = file_get_contents(RESOURCES_PATH . '/mail/' . ($template ?: 'default') . '.html'); |
||||||
0 ignored issues
–
show
|
|||||||
128 | if (is_array($content)) { |
||||||
129 | array_unshift($content, $template); |
||||||
130 | $message = call_user_func_array('sprintf', $content); |
||||||
131 | } else if (is_string($content)) { |
||||||
132 | $message = $content; |
||||||
133 | } else { |
||||||
134 | throw new MailException('邮件内容格式错误,仅支持传入数组或字符串。'); |
||||||
135 | } |
||||||
136 | |||||||
137 | self::mail()->msgHTML($message, APP_PATH . '/mail'); |
||||||
0 ignored issues
–
show
|
|||||||
138 | |||||||
139 | if (!self::mail()->send()) throw new MailException(self::mail()->ErrorInfo); |
||||||
140 | |||||||
141 | return true; |
||||||
142 | } |
||||||
143 | } |
||||||
144 |