Mail.php 5.7 KB

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