php使用smtp发送支持附件的邮件示例


Posted in PHP onApril 13, 2014

轻量级PHP邮件发送,需要有smtp服务器,代码经过多次实战使用,现在把代码分享给大家

<?php
/*
邮件发送smtp服务
联结smtp服务器,进行邮件发送,版权所有,不能复制
@author:jackbrown;
@qq: 610269963 
@time:2011-8-20;
@version:1.0.3;
*/
class smtp{ /*邮件用户名*/
 public $mailUser = MAIL_USER;
 /*邮件密码*/
 public $mailPwd = MAIL_PWD;
 /*邮件服务器地址*/
 public $server = MAIL_SMTP_HOST;
 /*邮件端口*/
 public $port = MAIL_SMTP_PORT;
 public $timeout = MAIL_TIMEOUT;
 /*邮件编码*/
 public $charset = MAIL_CHARSET;
 /*邮件发送者email,用于显示给接收者*/
 public $senderMail = MAIL_SENDER;
 /*发用者名称*/
 public $senderName = MAIL_SENDER_NAME;
 /*是否使用ssl安全操作*/
 public $useSSL = IN_SSL;
 /*是否显示错误信息*/
 public $showError = MAIL_SHOW_ERR;
 public $needLogin = MAIL_NEED_LOGIN;
 /*附件数组*/
 public $attachMent = array();
 public $failed = false;
 private static $smtpCon;
 private $stop ="\r\n";
 private $status = 0;
 
 public function __construct(){
  if(self::$smtpCon){
   return;
  }
  if($this->mailUser==''){
   $this->error('请配置好邮件登录用户名!');
   return false; 
  }
  if($this->mailPwd==''){  
   $this->error('请配置好邮件登录密码!');
   return false; 
  }
  if($this->server==''){   
   $this->error('请配置好邮服务器地址!');
   return false; 
  }
  if(!is_numeric($this->port)){   
   $this->error('请配置好邮服务器端口!');
   return false; 
  }
  /*ssl使用**/
  $server = $this->server;
  if($this->useSSL == true){
   $server = "ssl://".$this->server; 
  }
  self::$smtpCon = @fsockopen($server, $this->port, $errno, $errstr,10);;
  
  if(!self::$smtpCon){
   $this->error($errno.$errstr); 
   return false;
  }
  
  socket_set_timeout(self::$smtpCon,0,250000);
  /*开始邮件指令*/
  $this->getStatus();
  $resp = true;
  $resp = $resp && $this->helo();
  if($this->needLogin == '1'){
   $resp = $resp && $this->login();
  }
  if(!$resp){
   $this->failed = true;
  }
 }
 /*
 发送邮件
 @param string $to 接收邮件地址
 @param string $msg 邮件主要内容
 @title string $title 邮件标题
 */
 public function sendMail($to,$msg,$title=''){
  if($msg=='' ){
   return false;
  }
  if(is_array($to)){
   if($to!=null){
    foreach($to as $k=>$e){
     if(!preg_match('/^[a-z0-9A-Z_-]+@+([a-z0-9A-Z_-]+\.)+[a-z0-9A-Z]{2,3}$/',$e)){
      unset($to[$k]);
     }
    }
   }else{
    return false;
   }
   if($to == null){
    return false;
   }
  }else{
   if(!preg_match('/^[a-z0-9A-Z_-]+@+([a-z0-9A-Z_-]+\.)+[a-z0-9A-Z]{2,3}$/',$to)){
    return false;
   }
  }
   
  if(!self::$smtpCon){
   return false;
  }
  $this->sendSmtpMsg('MAIL FROM:<'.$this->senderMail.'>');
  if(!is_array($to)){      
   $this->sendSmtpMsg('RCPT TO:<'.$to.'>');
  }else{
   foreach($to as $k=>$email){    
    $this->sendSmtpMsg('RCPT TO:<'.$email.'>'); 
   }
  }
  $this->sendSmtpMsg("DATA");
 
  if($this->status !='354'){
   $this->error('请求发送邮件失败!');
   $this->failed = true;
   return false; 
  }
  $msg  = base64_encode($msg);
  $msg = str_replace($this->stop . '.', $this->stop . '..', $msg);
  $msg    = substr($msg, 0, 1) == '.' ? '.' . $msg : $msg;
  if($this->attachMent!=null){
   $headers = $this->mimeHeader($msg,$to,$title);
   $this->sendSmtpMsg($headers,false); 
  }else{
   $headers = $this->mailHeader($to,$title);
   $this->sendSmtpMsg($headers,false); 
   $this->sendSmtpMsg('',false);
   $this->sendSmtpMsg($msg,false);
  }
  $this->sendSmtpMsg('.');//发送结束标识符
  if($this->status != '250'){
   $this->failed = true;
   $this->error($this->readSmtpMsg());
   return false; 
  }
  return true;
 }
 /*
 关闭邮件连接
 */
 public function close(){
  $this->sendSmtpMsg('Quite');
  @socket_close(self::$smtpCon);
 }
 /*
 添加普通邮件头信息
 */
 protected function mailHeader($to,$title){
  $headers = array();
  $headers[] = 'Date: '.$this->gmtime('D j M Y H:i:s').' '.date('O');
  if(!is_array($to)){
   $headers[] = 'To: "'.'=?'.$this->charset.'?B?'.base64_encode($this->getMailUser($to)).'?="<'.$to.'>';
  }else{
   foreach($to as $k=>$e){
    $headers[] = 'To: "'.'=?'.$this->charset.'?B?'.base64_encode($this->getMailUser($e)).'?="<'.$e.'>';
   }
  }
  $headers[] = 'From: "=?'.$this->charset.'?B?'.base64_encode($this->senderName).'?="<'.$this->senderMail.'>';
  $headers[] = 'Subject: =?'.$this->charset.'?B?'.base64_encode($title).'?=';
  $headers[] = 'Content-type: text/html; charset='.$this->charset.'; format=flowed'; 
  $headers[] = 'Content-Transfer-Encoding: base64'; 
     $headers = str_replace($this->stop . '.', $this->stop . '..', trim(implode($this->stop, $headers)));
  return $headers;
 }
 /*
 带付件的头部信息
 */
 protected function mimeHeader($msg,$to,$title){
  if($this->attachMent!=null){
   $headers = array();
   $boundary = '----='.uniqid();
   $headers[] = 'Date: '.$this->gmtime('D j M Y H:i:s').' '.date('O');  
   if(!is_array($to)){
    $headers[] = 'To: "'.'=?'.$this->charset.'?B?'.base64_encode($this->getMailUser($to)).'?="<'.$to.'>';
   }else{
    foreach($to as $k=>$e){
     $headers[] = 'To: "'.'=?'.$this->charset.'?B?'.base64_encode($this->getMailUser($e)).'?="<'.$e.'>';
    }
   }
   $headers[] = 'From: "=?'.$this->charset.'?B?'.base64_encode($this->senderName).'?="<'.$this->senderMail.'>';
   $headers[] = 'Subject: =?'.$this->charset.'?B?'.base64_encode($title).'?=';
   $headers[] =  'Mime-Version: 1.0';
   $headers[] = 'Content-Type: multipart/mixed;boundary="'.$boundary.'"'.$this->stop;
   $headers[]='--'.$boundary;
   $headers[]='Content-Type: text/html;charset="'.$this->charset.'"';
   $headers[]='Content-Transfer-Encoding: base64'.$this->stop;
   $headers[] = '';
   $headers[]= $msg.$this->stop;   
   foreach($this->attachMent as $k=>$filename){
    $f = @fopen($filename, 'r');
    $mimetype = $this->getMimeType(realpath($filename));
    $mimetype = $mimetype == '' ? 'application/octet-stream' : $mimetype;
    $attachment = @fread($f, filesize($filename));
    $attachment = base64_encode($attachment);
    $attachment = chunk_split($attachment);
    $headers[] = "--" . $boundary;
    $headers[] = "Content-type: ".$mimetype.";name=\"=?".$this->charset."?B?". base64_encode(basename($filename)).'?="' ;
    $headers[] = "Content-disposition: attachment; name=\"=?".$this->charset."?B?". base64_encode(basename($filename)).'?="';
    $headers[] = 'Content-Transfer-Encoding: base64'.$this->stop;
    $headers[] = $attachment.$this->stop;
    
   }
   $headers[] = "--" . $boundary . "--";
   $headers = str_replace($this->stop . '.', $this->stop . '..', trim(implode($this->stop, $headers)));
   return $headers;
  }  
 }
 /*
 获取返回状态
 */
 protected function getStatus(){
  $this->status = substr($this->readSmtpMsg(),0,3);
 }
 
 /*
 获取邮件服务器返回的信息
 @return string 信息字符串
 */
 protected function readSmtpMsg(){
  if(!is_resource(self::$smtpCon)){
   return false;
  } 
  $return = '';
  $line   = '';
  while (strpos($return, $this->stop)=== false OR $line{3}!== ' ')
  {
   $line    = fgets(self::$smtpCon, 512);
   $return .= $line;
  }
  return trim($return);  
 }
 /*
 给邮件服务器发给指定命令消息
 */
 protected function sendSmtpMsg($cmd,$chStatus=true){
        if (is_resource(self::$smtpCon))
        {
             fwrite(self::$smtpCon, $cmd . $this->stop, strlen($cmd) + 2);
        }
  if($chStatus == true){
   $this->getStatus();
  }
  return true;
 }
 /*
 邮件时间格式
 */
 protected function gmtime(){
  return (time() - date('Z'));
 }
 /*
 获取付件的mime类型
 */
 protected function getMimeType($file){
  $mimes = array(
   'chm'=>'application/octet-stream', 'ppt'=>'application/vnd.ms-powerpoint', 
   'xls'=>'application/vnd.ms-excel', 'doc'=>'application/msword', 'exe'=>'application/octet-stream', 
   'rar'=>'application/octet-stream', 'js'=>"javascrīpt/js", 'css'=>"text/css", 
   'hqx'=>"application/mac-binhex40", 'bin'=>"application/octet-stream", 'oda'=>"application/oda", 'pdf'=>"application/pdf", 
   'ai'=>"application/postsrcipt", 'eps'=>"application/postsrcipt", 'es'=>"application/postsrcipt", 'rtf'=>"application/rtf", 
   'mif'=>"application/x-mif", 'csh'=>"application/x-csh", 'dvi'=>"application/x-dvi", 'hdf'=>"application/x-hdf", 
   'nc'=>"application/x-netcdf", 'cdf'=>"application/x-netcdf", 'latex'=>"application/x-latex", 'ts'=>"application/x-troll-ts", 
   'src'=>"application/x-wais-source", 'zip'=>"application/zip", 'bcpio'=>"application/x-bcpio", 'cpio'=>"application/x-cpio", 
   'gtar'=>"application/x-gtar", 'shar'=>"application/x-shar", 'sv4cpio'=>"application/x-sv4cpio", 'sv4crc'=>"application/x-sv4crc", 
   'tar'=>"application/x-tar",'ustar'=>"application/x-ustar",'man'=>"application/x-troff-man", 'sh'=>"application/x-sh", 
   'tcl'=>"application/x-tcl", 'tex'=>"application/x-tex", 'texi'=>"application/x-texinfo",'texinfo'=>"application/x-texinfo", 
   't'=>"application/x-troff", 'tr'=>"application/x-troff", 'roff'=>"application/x-troff", 
   'shar'=>"application/x-shar", 'me'=>"application/x-troll-me", 'ts'=>"application/x-troll-ts", 
   'gif'=>"image/gif", 'jpeg'=>"image/pjpeg", 'jpg'=>"image/pjpeg", 'jpe'=>"image/pjpeg", 'ras'=>"image/x-cmu-raster", 
   'pbm'=>"image/x-portable-bitmap", 'ppm'=>"image/x-portable-pixmap", 'xbm'=>"image/x-xbitmap", 'xwd'=>"image/x-xwindowdump", 
   'ief'=>"image/ief", 'tif'=>"image/tiff", 'tiff'=>"image/tiff", 'pnm'=>"image/x-portable-anymap", 'pgm'=>"image/x-portable-graymap", 
   'rgb'=>"image/x-rgb", 'xpm'=>"image/x-xpixmap", 'txt'=>"text/plain", 'c'=>"text/plain", 'cc'=>"text/plain", 
   'h'=>"text/plain", 'html'=>"text/html", 'htm'=>"text/html", 'htl'=>"text/html", 'rtx'=>"text/richtext", 'etx'=>"text/x-setext", 
   'tsv'=>"text/tab-separated-values", 'mpeg'=>"video/mpeg", 'mpg'=>"video/mpeg", 'mpe'=>"video/mpeg", 'avi'=>"video/x-msvideo", 
   'qt'=>"video/quicktime", 'mov'=>"video/quicktime", 'moov'=>"video/quicktime", 'movie'=>"video/x-sgi-movie", 'au'=>"audio/basic", 
   'snd'=>"audio/basic", 'wav'=>"audio/x-wav", 'aif'=>"audio/x-aiff", 'aiff'=>"audio/x-aiff", 'aifc'=>"audio/x-aiff", 
   'swf'=>"application/x-shockwave-flash", 'myz'=>"application/myz" 
  );
  $ext = substr(strrchr($file,'.'),1);
  $type = $mimes[$ext];
  
  unset($mimes);
  return $type;
 }
 /*
 邮件helo命令
 */
 private function helo(){
  if($this->status != '220'){
   $this->error('连接服务器失败!'); 
   return false;
  }
  return $this->sendSmtpMsg('HELO '.$this->server);
 }
 
 /*
 登录
 */
 private function login(){
  if($this->status!='250'){
   $this->error('helo邮件指令失败!');
   return false;
  }
  $this->sendSmtpMsg('AUTH LOGIN');  
  if($this->status!='334'){
   $this->error('AUTH LOGIN 邮件指令失败!');
   return false;
  }
  $this->sendSmtpMsg(base64_encode($this->mailUser));  
  if($this->status!='334'){
   $this->error('邮件登录用户名可能不正确!'.$this->readSmtpMsg());
   return false;
  }
  $this->sendSmtpMsg(base64_encode($this->mailPwd));
  if($this->status !='235'){
   $this->error('邮件登录密码可能不正确!');
   return false;
  }
  return true;
 }
 private function getMailUser($to){
  $temp = explode('@',$to);
  return $temp[0];
 }
 /*
 异常报告
 */
 private function error($exception){ 
  if($this->showError == false){
   file_put_contents('mail_log.txt',$exception,FILE_APPEND);
   return;
  }
  if(class_exists('error') && is_object($GLOBALS['error'])){   
   $GLOBALS['error']->showErrorStr($exception,'javascript:',false);
  }else{
   throw new Exception($exception);
  }
 }
}

// 使用示例 
ini_set('memory_limit','128M');
set_time_limit(120);
define('MAIL_SENDER_NAME','楚贤');
define('MAIL_SMTP_HOST','smtp.ym.163.com');
define('MAIL_USER','admin@myxxxx.com');
define('MAIL_SENDER','admin@myxxxx.com');
define('MAIL_PWD','xxxx');
define('MAIL_SMTP_PORT',25);
define('IN_SSL',false);
define('MAIL_TIMEOUT',10);
define('MAIL_CHARSET','utf-8');
date_default_timezone_set('PRC');
$m = new smtp();
$msg = "有用户登录服务器@".date('Y-m-d H:i:s');
付件
//$m->attachMent = array('hehe.php','common.php');
if($m->sendMail(array('610269963@qq.com'),$msg,'88服务器登录提示')){
 echo '发送成功!';
}
$m->close();
?>
PHP 相关文章推荐
十天学会php(3)
Oct 09 PHP
PHP获取网站域名和地址的代码
Aug 17 PHP
apache+php+mysql安装配置方法小结
Aug 01 PHP
php join函数应用
May 04 PHP
PHP curl_setopt()函数实例代码与参数分析
Jun 02 PHP
PHP安全配置详细说明
Sep 26 PHP
php预定义变量使用帮助(带实例)
Oct 30 PHP
php计算当前程序执行时间示例
Apr 24 PHP
laravel 4安装及入门图文教程
Oct 29 PHP
php文件读取方法实例分析
Jun 20 PHP
php删除数组指定元素实现代码
May 03 PHP
TP5框架安全机制实例分析
Apr 05 PHP
php实现上传图片生成缩略图示例
Apr 13 #PHP
php使用curl和正则表达式抓取网页数据示例
Apr 13 #PHP
PHP header()函数常用方法总结
Apr 11 #PHP
开源php中文分词系统SCWS安装和使用实例
Apr 11 #PHP
PHP获取网页标题的3种实现方法代码实例
Apr 11 #PHP
PHP动态生成javascript文件的2个例子
Apr 11 #PHP
php实现数组筛选奇数和偶数示例
Apr 11 #PHP
You might like
laravel容器延迟加载以及auth扩展详解
2015/03/02 PHP
PHP标准库 (SPL)――Countable用法示例
2020/06/05 PHP
JavaScript面向对象编程
2008/03/02 Javascript
JavaScript实用技巧(一)
2010/08/16 Javascript
javascript表单验证和Window详解
2014/12/11 Javascript
Nodejs学习笔记之Global Objects全局对象
2015/01/13 NodeJs
详解Vue.js——60分钟组件快速入门(上篇)
2016/12/05 Javascript
JS文件/图片从电脑里面拖拽到浏览器上传文件/图片
2017/03/08 Javascript
vue单页应用在页面刷新时保留状态数据的方法
2018/09/21 Javascript
Vue 组件封装 并使用 NPM 发布的教程
2018/09/30 Javascript
vue-cli随机生成port源码的方法
2019/09/02 Javascript
解决layui表格的表头不滚动的问题
2019/09/04 Javascript
[01:03:56]Mineski vs TNC 2018国际邀请赛淘汰赛BO1 8.21
2018/08/22 DOTA
python使用rsa加密算法模块模拟新浪微博登录
2014/01/22 Python
python检测服务器是否正常
2014/02/16 Python
wxPython框架类和面板类的使用实例
2014/09/28 Python
Python去除列表中重复元素的方法
2015/03/20 Python
在Python中关于中文编码问题的处理建议
2015/04/08 Python
Python2.7简单连接与操作MySQL的方法
2016/04/27 Python
JavaScript实现一维数组转化为二维数组
2018/04/17 Python
python3+PyQt5实现自定义窗口部件Counters
2018/04/20 Python
Python 找到列表中满足某些条件的元素方法
2018/06/26 Python
对python生成业务报表的实例详解
2019/02/03 Python
Python socket非阻塞模块应用示例
2019/09/12 Python
Numpy中对向量、矩阵的使用详解
2019/10/29 Python
Python values()与itervalues()的用法详解
2019/11/27 Python
Python flask路由间传递变量实例详解
2020/06/03 Python
植物选择:Botanic Choice
2017/02/15 全球购物
加拿大在线眼镜零售商:SmartBuyGlasses加拿大
2019/05/25 全球购物
马来西亚奢侈品牌购物商城:Valiram 247
2020/09/29 全球购物
建筑施工员岗位职责
2013/11/26 职场文书
2014年最新学习全国两会精神心得
2014/03/17 职场文书
卫校毕业生自我鉴定
2014/09/28 职场文书
2015年综治维稳工作总结
2015/04/07 职场文书
如何给HttpServletRequest增加消息头
2021/06/30 Java/Android
详解Oracle数据库中自带的所有表结构(sql代码)
2021/11/20 Oracle