VerifyCode.php 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. <?php
  2. namespace App\Servers\Email;
  3. use Illuminate\Bus\Queueable;
  4. use Illuminate\Mail\Mailable;
  5. use Illuminate\Queue\SerializesModels;
  6. use Swift_Mailer;
  7. use Swift_Message;
  8. use Swift_SmtpTransport;
  9. /**
  10. * 邮件验证码发送
  11. * @author 唐远望
  12. * @version 1.0
  13. * @date 2026-03-30
  14. *
  15. */
  16. class VerifyCode extends Mailable
  17. {
  18. use Queueable, SerializesModels;
  19. /**
  20. * 封装SMTP发送邮件的方法
  21. *
  22. * @param string|array $to 收件人邮箱
  23. * @param string $subject 邮件主题
  24. * @param string $body 邮件内容
  25. * @param string|null $from 发件人邮箱,默认为配置中的from地址
  26. * @return int 发送结果
  27. */
  28. public static function sendSmtpEmail($to, $subject, $body, $from = null)
  29. {
  30. // 创建SMTP传输
  31. $transport = new Swift_SmtpTransport(
  32. config('mail.mailers.smtp.host'),
  33. config('mail.mailers.smtp.port')
  34. );
  35. // 设置认证信息
  36. $transport->setUsername(config('mail.mailers.smtp.username'));
  37. $transport->setPassword(config('mail.mailers.smtp.password'));
  38. // 设置加密方式
  39. if (config('mail.mailers.smtp.encryption')) {
  40. $transport->setEncryption(config('mail.mailers.smtp.encryption'));
  41. }
  42. // 创建邮件器
  43. $mailer = new Swift_Mailer($transport);
  44. // 创建邮件消息
  45. $message = new Swift_Message($subject);
  46. $message->setFrom($from ?: config('mail.from.address'));
  47. $message->setTo($to);
  48. // 自动识别 body 是否为 HTML 内容
  49. if (self::isHtmlContent($body)) {
  50. // HTML 内容
  51. $message->setBody($body, 'text/html');
  52. // 可选:同时添加纯文本版本作为备选
  53. $message->addPart(strip_tags($body), 'text/plain');
  54. } else {
  55. // 纯文本内容
  56. $message->setBody($body);
  57. }
  58. // 发送邮件
  59. return $mailer->send($message);
  60. }
  61. /**
  62. * 判断内容是否为 HTML
  63. *
  64. * @param string $content
  65. * @return bool
  66. */
  67. private static function isHtmlContent($content)
  68. {
  69. // 方法1:检查是否包含 HTML 标签
  70. if (strip_tags($content) != $content) {
  71. return true;
  72. }
  73. // 方法2:检查是否以 <!DOCTYPE html 或 <html 开头(忽略空白字符)
  74. $trimmedContent = trim($content);
  75. if (
  76. strpos($trimmedContent, '<!DOCTYPE html') === 0 ||
  77. strpos($trimmedContent, '<html') === 0
  78. ) {
  79. return true;
  80. }
  81. // 方法3:检查常见的 HTML 标签
  82. $htmlPatterns = [
  83. '/<div[^>]*>/i',
  84. '/<p[^>]*>/i',
  85. '/<span[^>]*>/i',
  86. '/<table[^>]*>/i',
  87. '/<br\s*\/?>/i',
  88. '/<h[1-6][^>]*>/i',
  89. '/<a[^>]*>/i',
  90. '/<img[^>]*>/i',
  91. '/<ul[^>]*>/i',
  92. '/<ol[^>]*>/i',
  93. '/<li[^>]*>/i'
  94. ];
  95. foreach ($htmlPatterns as $pattern) {
  96. if (preg_match($pattern, $content)) {
  97. return true;
  98. }
  99. }
  100. return false;
  101. }
  102. }