email.php 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. <?php
  2. /**
  3. * 邮件类
  4. *
  5. * 邮件操作类,目前只支持smtp服务的邮件发送
  6. *
  7. *
  8. * @package
  9. */
  10. defined('InShopNC') or exit('Access Invalid!');
  11. final class Email{
  12. /**
  13. * 邮件服务器
  14. */
  15. private $email_server;
  16. /**
  17. * 端口
  18. */
  19. private $email_port = 25;
  20. /**
  21. * 账号
  22. */
  23. private $email_user;
  24. /**
  25. * 密码
  26. */
  27. private $email_password;
  28. /**
  29. * 发送邮箱
  30. */
  31. private $email_from;
  32. /**
  33. * 间隔符
  34. */
  35. private $email_delimiter = "\n";
  36. /**
  37. * 站点名称
  38. */
  39. private $site_name;
  40. public function get($key){
  41. if (!empty($this->$key)){
  42. return $this->$key;
  43. }else {
  44. return false;
  45. }
  46. }
  47. public function set($key, $value){
  48. if (!isset($this->$key)){
  49. $this->$key = $value;
  50. return true;
  51. }else {
  52. return false;
  53. }
  54. }
  55. /**
  56. * 发送邮件
  57. *
  58. * @param string $email_to 发送对象邮箱地址
  59. * @param string $subject 邮件标题
  60. * @param string $message 邮件内容
  61. * @param string $from 页头来源内容
  62. * @return bool 布尔形式的返回结果
  63. */
  64. public function send($email_to, $subject, $message, $from = ''){
  65. if(empty($email_to)) return false;
  66. $message = base64_encode($this->html($subject, $message));
  67. $email_to = $this->to($email_to);
  68. $header = $this->header($from);
  69. /**
  70. * 发送
  71. */
  72. if(!$fp = @fsockopen($this->email_server, $this->email_port, $errno, $errstr, 30)) {
  73. $this->resultLog($this->email_server.':'.$this->email_port." CONNECT - Unable to connect to the SMTP server");
  74. return false;
  75. }
  76. stream_set_blocking($fp, true);
  77. $lastmessage = fgets($fp, 512);
  78. if(substr($lastmessage, 0, 3) != '220') {
  79. $this->resultLog($this->email_server.':'.$this->email_port.$lastmessage);
  80. return false;
  81. }
  82. fputs($fp, 'EHLO'." shopnc\r\n");
  83. $lastmessage = fgets($fp, 512);
  84. if(substr($lastmessage, 0, 3) != 220 && substr($lastmessage, 0, 3) != 250) {
  85. $this->resultLog($this->email_server.':'.$this->email_port." HELO/EHLO - $lastmessage");
  86. return false;
  87. }elseif(substr($lastmessage, 0, 3) == 220){
  88. $lastmessage = fgets($fp, 512);
  89. if(substr($lastmessage, 0, 3) != 250) {
  90. $this->resultLog($this->email_server.':'.$this->email_port." HELO/EHLO - $lastmessage");
  91. return false;
  92. }
  93. }
  94. while(1) {
  95. if(substr($lastmessage, 3, 1) != '-' || empty($lastmessage)) {
  96. break;
  97. }
  98. $lastmessage = fgets($fp, 512);
  99. }
  100. fputs($fp, "AUTH LOGIN\r\n");
  101. $lastmessage = fgets($fp, 512);
  102. if(substr($lastmessage, 0, 3) != 334) {
  103. $this->resultLog($this->email_server.':'.$this->email_port." AUTH LOGIN - $lastmessage");
  104. return false;
  105. }
  106. fputs($fp, base64_encode($this->email_user)."\r\n");
  107. $lastmessage = fgets($fp, 512);
  108. if(substr($lastmessage, 0, 3) != 334) {
  109. $this->resultLog($this->email_server.':'.$this->email_port." USERNAME - $lastmessage");
  110. return false;
  111. }
  112. fputs($fp, base64_encode($this->email_password)."\r\n");
  113. $lastmessage = fgets($fp, 512);
  114. if(substr($lastmessage, 0, 3) != 235) {
  115. $this->resultLog($this->email_server.':'.$this->email_port." PASSWORD - $lastmessage");
  116. return false;
  117. }
  118. fputs($fp, "MAIL FROM: <".preg_replace("/.*\<(.+?)\>.*/", "\\1", $this->email_from).">\r\n");
  119. $lastmessage = fgets($fp, 512);
  120. if(substr($lastmessage, 0, 3) != 250) {
  121. fputs($fp, "MAIL FROM: <".preg_replace("/.*\<(.+?)\>.*/", "\\1", $this->email_from).">\r\n");
  122. $lastmessage = fgets($fp, 512);
  123. if(substr($lastmessage, 0, 3) != 250) {
  124. $this->resultLog($this->email_server.':'.$this->email_port." MAIL FROM - $lastmessage");
  125. return false;
  126. }
  127. }
  128. fputs($fp, "RCPT TO: <".preg_replace("/.*\<(.+?)\>.*/", "\\1", $email_to).">\r\n");
  129. $lastmessage = fgets($fp, 512);
  130. if(substr($lastmessage, 0, 3) != 250) {
  131. fputs($fp, "RCPT TO: <".preg_replace("/.*\<(.+?)\>.*/", "\\1", $email_to).">\r\n");
  132. $lastmessage = fgets($fp, 512);
  133. $this->resultLog($this->email_server.':'.$this->email_port." RCPT TO - $lastmessage");
  134. return false;
  135. }
  136. fputs($fp, "DATA\r\n");
  137. $lastmessage = fgets($fp, 512);
  138. if(substr($lastmessage, 0, 3) != 354) {
  139. $this->resultLog($this->email_server.':'.$this->email_port." DATA - $lastmessage");
  140. return false;
  141. }
  142. fputs($fp, "Date: ".gmdate('r')."\r\n");
  143. fputs($fp, "To: ".$email_to."\r\n");
  144. fputs($fp, "Subject: ".$subject."\r\n");
  145. fputs($fp, $header."\r\n");
  146. fputs($fp, "\r\n\r\n");
  147. fputs($fp, "$message\r\n.\r\n");
  148. $lastmessage = fgets($fp, 512);
  149. if(substr($lastmessage, 0, 3) != 250) {
  150. $this->resultLog($this->email_server.':'.$this->email_port." END - $lastmessage");
  151. }
  152. fputs($fp, "QUIT\r\n");
  153. return true;
  154. }
  155. public function send_sys_email($email_to, $subject, $message){
  156. $this->set('email_server',C('email_host'));
  157. $this->set('email_port',C('email_port'));
  158. $this->set('email_user',C('email_id'));
  159. $this->set('email_password',C('email_pass'));
  160. $this->set('email_from',C('email_addr'));
  161. $this->set('site_name',C('site_name'));
  162. $result = $this->send($email_to, $subject, $message);
  163. return $result;
  164. }
  165. /**
  166. * 内容:邮件主体
  167. *
  168. * @param string $subject 邮件标题
  169. * @param string $message 邮件内容
  170. * @return string 字符串形式的返回结果
  171. */
  172. private function html($subject, $message){
  173. $message = preg_replace("/href\=\"(?!http\:\/\/)(.+?)\"/i", 'href="'.SHOP_SITE_URL.'\\1"', $message);
  174. $tmp .= "<html><head>";
  175. $tmp .= '<meta http-equiv="Content-Type" content="text/html; charset='.CHARSET.'">';
  176. $tmp .= "<title>". $subject ."</title>";
  177. $tmp .= "</head><body>".$message."</body></html>";
  178. $message = $tmp;
  179. unset($tmp);
  180. return $message;
  181. }
  182. /**
  183. * 发送对象邮件地址
  184. *
  185. * @param string $email_to 发送地址
  186. * @return string 字符串形式的返回结果
  187. */
  188. private function to($email_to){
  189. $email_to = preg_match('/^(.+?) \<(.+?)\>$/',$email_to, $mats) ? ($this->email_user ? '=?'.CHARSET.'?B?'.base64_encode($mats[1])."?= <$mats[2]>" : $mats[2]) : $email_to;
  190. return $email_to;
  191. }
  192. /**
  193. * 内容:邮件标题
  194. *
  195. * @param string $subject 邮件标题
  196. * @return string 字符串形式的返回结果
  197. */
  198. private function subject($subject){
  199. $subject = '=?'.CHARSET.'?B?'.base64_encode(preg_replace("/[\r|\n]/", '', '['.$this->site_name.'] '.$subject)).'?=';
  200. return $subject;
  201. }
  202. /**
  203. * 内容:邮件主体内容
  204. *
  205. * @param string $message 邮件主体内容
  206. * @return string 字符串形式的返回结果
  207. */
  208. private function message($message){
  209. $message = chunk_split(base64_encode(str_replace("\n", "\r\n", str_replace("\r", "\n", str_replace("\r\n", "\n", str_replace("\n\r", "\r", $message))))));
  210. return $message;
  211. }
  212. /**
  213. * 内容:邮件页头
  214. *
  215. * @param string $from 邮件页头来源
  216. * @return array $rs_row 返回数组形式的查询结果
  217. */
  218. private function header($from=''){
  219. if ($from == ''){
  220. $from = '=?'.CHARSET.'?B?'.base64_encode($this->site_name)."?= <".$this->email_from.">" ;
  221. }else {
  222. $from = preg_match('/^(.+?) \<(.+?)\>$/',$from, $mats) ? '=?'.CHARSET.'?B?'.base64_encode($mats[1])."?= <$mats[2]>" : $from;
  223. }
  224. $header = "From: $from{$this->email_delimiter}";
  225. $header .= "X-Priority: 3{$this->email_delimiter}";
  226. $header .= "X-Mailer: 33hao {$this->email_delimiter}";
  227. $header .= "MIME-Version: 1.0{$this->email_delimiter}";
  228. $header .= "Content-type: text/html; ";
  229. $header .= "charset=".CHARSET."{$this->email_delimiter}";
  230. $header .= "Content-Transfer-Encoding: base64{$this->email_delimiter}";
  231. $header .= 'Message-ID: <'.gmdate('YmdHs').'.'.substr(md5($message.microtime()), 0, 6).rand(100000, 999999).'@'.$_SERVER['HTTP_HOST'].">{$this->email_delimiter}";
  232. return $header;
  233. }
  234. /**
  235. * 错误信息记录
  236. *
  237. * @param string $msg 错误信息
  238. * @return bool 布尔形式的返回结果
  239. */
  240. private function resultLog($msg){
  241. if (DeBug === true){
  242. $fp = fopen('txt.txt','a+');
  243. fwrite($fp,$msg);
  244. fclose($fp);
  245. return true;
  246. }else {
  247. return true;
  248. }
  249. }
  250. }