Email.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. <?php
  2. namespace app\common\library;
  3. use think\Config;
  4. use Tx\Mailer;
  5. use Tx\Mailer\Exceptions\CodeException;
  6. use Tx\Mailer\Exceptions\SendException;
  7. class Email
  8. {
  9. /**
  10. * 单例对象
  11. */
  12. protected static $instance;
  13. /**
  14. * phpmailer对象
  15. */
  16. protected $mail = [];
  17. /**
  18. * 错误内容
  19. */
  20. protected $error = '';
  21. /**
  22. * 默认配置
  23. */
  24. public $options = [
  25. 'charset' => 'utf-8', //编码格式
  26. 'debug' => false, //调式模式
  27. 'mail_type' => 0, //状态
  28. ];
  29. /**
  30. * 初始化
  31. * @access public
  32. * @param array $options 参数
  33. * @return Email
  34. */
  35. public static function instance($options = [])
  36. {
  37. if (is_null(self::$instance)) {
  38. self::$instance = new static($options);
  39. }
  40. return self::$instance;
  41. }
  42. /**
  43. * 构造函数
  44. * @param array $options
  45. */
  46. public function __construct($options = [])
  47. {
  48. if ($config = Config::get('site')) {
  49. $this->options = array_merge($this->options, $config);
  50. }
  51. $this->options = array_merge($this->options, $options);
  52. $secureArr = [0 => '', 1 => 'tls', 2 => 'ssl'];
  53. $secure = isset($secureArr[$this->options['mail_verify_type']]) ? $secureArr[$this->options['mail_verify_type']] : '';
  54. $this->mail = new Mailer();
  55. $this->mail->setServer($this->options['mail_smtp_host'], $this->options['mail_smtp_port'], $secure);
  56. $this->mail->setAuth($this->options['mail_from'], $this->options['mail_smtp_pass']);
  57. //设置发件人
  58. $this->from($this->options['mail_from'], $this->options['mail_smtp_user']);
  59. }
  60. /**
  61. * 设置邮件主题
  62. * @param string $subject 邮件主题
  63. * @return $this
  64. */
  65. public function subject($subject)
  66. {
  67. $this->mail->setSubject($subject);
  68. return $this;
  69. }
  70. /**
  71. * 设置发件人
  72. * @param string $email 发件人邮箱
  73. * @param string $name 发件人名称
  74. * @return $this
  75. */
  76. public function from($email, $name = '')
  77. {
  78. $this->mail->setFrom($name, $email);
  79. return $this;
  80. }
  81. /**
  82. * 设置收件人
  83. * @param mixed $email 收件人,多个收件人以,进行分隔
  84. * @return $this
  85. */
  86. public function to($email)
  87. {
  88. $emailArr = $this->buildAddress($email);
  89. foreach ($emailArr as $address => $name) {
  90. $this->mail->addTo($name, $address);
  91. }
  92. return $this;
  93. }
  94. /**
  95. * 设置抄送
  96. * @param mixed $email 收件人,多个收件人以,进行分隔
  97. * @param string $name 收件人名称
  98. * @return Email
  99. */
  100. public function cc($email, $name = '')
  101. {
  102. $emailArr = $this->buildAddress($email);
  103. if (count($emailArr) == 1 && $name) {
  104. $emailArr[key($emailArr)] = $name;
  105. }
  106. foreach ($emailArr as $address => $name) {
  107. $this->mail->addCC($address, $name);
  108. }
  109. return $this;
  110. }
  111. /**
  112. * 设置密送
  113. * @param mixed $email 收件人,多个收件人以,进行分隔
  114. * @param string $name 收件人名称
  115. * @return Email
  116. */
  117. public function bcc($email, $name = '')
  118. {
  119. $emailArr = $this->buildAddress($email);
  120. if (count($emailArr) == 1 && $name) {
  121. $emailArr[key($emailArr)] = $name;
  122. }
  123. foreach ($emailArr as $address => $name) {
  124. $this->mail->addBCC($name, $address);
  125. }
  126. return $this;
  127. }
  128. /**
  129. * 设置邮件正文
  130. * @param string $body 邮件下方
  131. * @param boolean $ishtml 是否HTML格式
  132. * @return $this
  133. */
  134. public function message($body, $ishtml = true)
  135. {
  136. $this->mail->setBody($body);
  137. return $this;
  138. }
  139. /**
  140. * 添加附件
  141. * @param string $path 附件路径
  142. * @param string $name 附件名称
  143. * @return Email
  144. */
  145. public function attachment($path, $name = '')
  146. {
  147. $this->mail->addAttachment($name, $path);
  148. return $this;
  149. }
  150. /**
  151. * 构建Email地址
  152. * @param mixed $emails Email数据
  153. * @return array
  154. */
  155. protected function buildAddress($emails)
  156. {
  157. if (!is_array($emails)) {
  158. $emails = array_flip(explode(',', str_replace(";", ",", $emails)));
  159. foreach ($emails as $key => $value) {
  160. $emails[$key] = strstr($key, '@', true);
  161. }
  162. }
  163. return $emails;
  164. }
  165. /**
  166. * 获取最后产生的错误
  167. * @return string
  168. */
  169. public function getError()
  170. {
  171. return $this->error;
  172. }
  173. /**
  174. * 设置错误
  175. * @param string $error 信息信息
  176. */
  177. protected function setError($error)
  178. {
  179. $this->error = $error;
  180. }
  181. /**
  182. * 发送邮件
  183. * @return boolean
  184. */
  185. public function send()
  186. {
  187. $result = false;
  188. if (in_array($this->options['mail_type'], [1, 2])) {
  189. try {
  190. $result = $this->mail->send();
  191. } catch (SendException $e) {
  192. $this->setError($e->getCode() . $e->getMessage());
  193. } catch (CodeException $e) {
  194. preg_match_all("/Expected: (\d+)\, Got: (\d+)( \| (.*))?\$/i", $e->getMessage(), $matches);
  195. $code = isset($matches[2][3]) ? $matches[2][3] : 0;
  196. $message = isset($matches[2][0]) ? $matches[4][0] : $e->getMessage();
  197. $this->setError($message);
  198. } catch (\Exception $e) {
  199. $this->setError($e->getMessage());
  200. }
  201. $this->setError($result ? '' : $this->getError());
  202. } else {
  203. //邮件功能已关闭
  204. $this->setError(__('Mail already closed'));
  205. }
  206. return $result;
  207. }
  208. }