强适应性的PHP邮件发送类(采用邮件专递方式,无需smtp服务器)

    技术2022-05-20  34

        本类参考了网上关于PHP的MIME MAIL和SMTP发送协议的文章,本类可以在*NUX或WIN平台下并且无需SMTP服务器,直接通过邮件专递方式送到邮件接收方的邮件服务器中。

        需要注意的是在发送大尺寸邮件时,建议在服务器允许MAIL()发送的情况下,尽量开启'usemail'=>true,因为用PHP的SOCKE方式发送效率相对于MAIL()函数来说要低;另外要说明的是由于采用邮件专递的方式邮件没有本地暂存发送,为了可靠性和避免长时间等待的过时问题,所以在没有启用PHP的MAIL函数时,本类没有添加支持用通过分号分隔的多帐号同时发送的功能。

        本类在nease.net的Linux+php5虚拟主机空间(该空间不能使用PHP自带的MAIL函数发邮件,写此类当时就是为了在这个空间下发送邮件)及win2003+IIS6+php4.3上测试成功。

    简单范例:

    require("mailer.class.php");$mailer=new mailer();$mailer->mConfig['mailform']="xxx@21cn.com";$isended=$mailer->mail("nobody@example.com","the subject","hello","From: webmaster@example.com");if($isended){    echo "true";}else{    echo "false";}

    类文件: mailer.class.php

    <?php /** * Project:     Dowebs.Lib: the PHP compiling template engine * File:        mailer.lib.php * * This library is opensource software; * @link http://www.dowebs.net/ * @copyright 2004-2005 dowebs.net studio. * @author Xie Hengduo xiejuchen@21cn.com * @package System * @version 1.0.0.0 */ class mailer    var $mConfig=array(         'dns'    =>"202.96.104.16",                //设置解域MX记录的域名服务器         'mailform'    =>"yourname@yourdomain.com",//发送邮件的帐号         'charset'    =>"utf-8",                    //HTML附件编码         'usemail'    =>false                        //是否使用PHP中的MAIL函数     );     var $dns_repl_domain="";     var $arrMX    =array();     var $error    ="";     var $aattach    =array();     var $xheaders    =array();     var $ctencoding    = "7bit";     var $priorities = array( '1 (Highest)', '2 (High)', '3 (Normal)', '4 (Low)', '5 (Lowest)' );     var $content_type='';          function mailer()     {              }          //兼容的mail函数     function mail($to,$subject,$message,$additional_headers='')     {         if($this->mConfig['usemail'])         {             return mail($to,$subject,$message,$additional_headers);         }         else         {             if($this->queryMailStmp($to))             {                 $this->error="2 收件人邮箱地址非法";                 return false;             }             //连接服务器             $is_sockopen=false;             $hostname="";             foreach($this->arrMX as $value)             {                 if($fp = fsockopen ($value, 25, $errno, $errstr, 60))                 {                     $hostname=$value;                     $is_sockopen=true;                     break;                 }             }             if (!$is_sockopen){$this->error="3 联接服务器失败";return false;}             //HELO             fputs($fp,"HELO {$hostname}/r/n");             $lastmessage = fgets($fp,1024);             if(substr($lastmessage,0,3) != 220 ){$this->error="4 错误信息$lastmessage";return false;}             //FROM:             fputs( $fp,"MAIL FROM:<{$this->mConfig['mailform']}>"."/r/n");             $lastmessage = fgets ($fp,1024);             if (substr($lastmessage,0,3) != 250){$this->error="5 错误信息$lastmessage";return false;}             //TO:             fputs( $fp,"RCPT TO:<$to>"."/r/n");             $lastmessage = fgets ($fp,1024);             if (substr($lastmessage,0,3) != 250){$this->error="6 错误信息$lastmessage";return false;}             while(true){                 $lastmessage = fgets($fp,512);                 if((substr($lastmessage,3,1) != "-")||(empty($lastmessage)))break;             }             //DATA             fputs($fp,"DATA/r/n");             $lastmessage = fgets ($fp,1024);             if (substr($lastmessage,0,3) != 354){$this->error="7 错误信息$lastmessage";return false;}             $message="/n".$message;             if($additional_headers!='')             {                 $message = $additional_headers."/r/n".$message;             }             //处理To头             $head="To: $to/r/n";             $message = $head.$message;             //处理Subject头             $head="Subject: $subject/r/n";             $message = $head.$message;             //加上结束串             $message .= "/r/n./r/n";             //发送信息             fputs($fp, $message);             fputs($fp,"QUIT/r/n");             fclose($fp);             return true;         }     }     //邮址初步校验     function is_valid_email ($email = "")     {         return preg_match('/^[./w-]+@([/w-]+/.)+[a-zA-Z]{2,6}$/',$email);     }     function queryMailStmp($mailaddr)     {         if($this->is_valid_email($mailaddr))         {             $this->mxlookup(substr(strstr($mailaddr,'@'),1));         }         else         {             return false;         }     }     //取得MX记录     function mxlookup($domain)     {         if(function_exists('getmxrr'))         {             getmxrr($domain,$this->arrMX);         }         else         {             ##########################             $dot_pos = 0; $temp = "";             $QNAME="";             while($dot_pos=strpos($domain,"."))             {                 $temp   = substr($domain,0,$dot_pos);                 $domain = substr($domain,$dot_pos+1);                 $QNAME .= chr(strlen($temp)).$temp;             }             $QNAME .= chr(strlen($domain)).$domain.chr(0);             ###########################             $dns_packet = chr(0).chr(1).chr(1).chr(0).chr(0).chr(1).chr(0).chr(0).chr(0).chr(0).chr(0).chr(0).$QNAME.chr(0).chr(15).chr(0).chr(1);             $dns_socket = fsockopen("udp://{$this->mConfig['dns']}", 53);             fwrite($dns_socket,$dns_packet,strlen($dns_packet));             $this->dns_reply  = fread($dns_socket,1);             $bytes = stream_get_meta_data($dns_socket);             $this->dns_reply .= fread($dns_socket,$bytes['unread_bytes']);             fclose($dns_socket);             $this->cIx=6;             $this->Total_Accounts="";             for($i=0;$i<2;$i++){                 $this->Total_Accounts.=ord(substr($this->dns_reply,$this->cIx,1));                 $this->cIx++;             }             $this->cIx+=4;             $this->parse_data($this->dns_repl_domain);             $this->cIx+=7;             for($ic=1;$ic<=$this->Total_Accounts;$ic++) {                 $QTYPE = ord($this->gdi($this->cIx));                 if($QTYPE!==15){                     print("<font color='red' size='4' face='verdana'><B>[No MX Records returned]</b></font>");                     die();                 }                 $this->cIx+=9;                 $mxPref = ord($this->gdi($this->cIx));                 $this->parse_data($curmx);                 $this->arrMX[] =$curmx;                 $this->cIx+=3;             }         }     }     function gdi(&$cIx,$bytes=1) {         $this->cIx++;         return(substr($this->dns_reply, $this->cIx-1, $bytes));     }     function parse_data(&$retval) {         $arName = array();         $byte = ord($this->gdi($this->cIx));         while($byte!==0) {             if($byte==192) { //compressed                    $tmpIx = $this->cIx;                 $this->cIx = ord($this->gdi($cIx));                 $tmpName = $retval;                 $this->parse_data($tmpName);                 $retval = $retval.".".$tmpName;                 $this->cIx = $tmpIx+1;                 return;             }             $retval="";             $bCount = $byte;             for($b=0;$b<$bCount;$b++) {                 $retval .= $this->gdi($this->cIx);             }             $arName[]=$retval;             $byte = ord($this->gdi($this->cIx));         }         $retval=join(".",$arName);     }          ############################################     # MIME MAIL CODE     ############################################     function From( $from="")     {         if($from=='')         {             $this->xheaders['From']=$this->mConfig['mailform'];         }         else         {             $this->xheaders['From'] = $from;         }     }     function mimemail($to,$subject,$message)     {         $this->boundary= "--" . md5( uniqid("myboundary") );         if( $this->mConfig['charset'] != "us-ascii" )         {             $this->ctencoding = "8bit";         }         $headers = "";         if( $this->mConfig['charset'] != "") {             //global $contenttype;             $this->xheaders["Mime-Version"] = "1.0";             $this->xheaders["Content-Type"] = "{$this->content_type}; charset={$this->mConfig['charset']}";             $this->xheaders["Content-Transfer-Encoding"] = $this->ctencoding;         }         $this->xheaders["X-Mailer"] = "Dowebs.net Mailer";         if( count( $this->aattach ) > 0 )         {             $this->xheaders["Content-Type"] = "multipart/mixed;/n boundary=/"{$this->boundary}/"";             $fullBody="This is a multi-part message in MIME format./n--{$this->boundary}/n";             $fullBody.= "Content-Type: text/html; charset={$this->mConfig['charset']}/nContent-Transfer-Encoding:{$this->ctencoding}/n/n".message."/n";             $sep= chr(13) . chr(10);             $ata= array();             $k=0;             for( $i=0; $i < count( $this->aattach); $i++ ) {                 $filename = $this->aattach[$i];                 $basename = basename($filename);                 $ctype = $this->actype[$i];        // content-type                 $disposition = $this->adispo[$i];                 if(!file_exists( $filename)){$this->error="1 Class Mail, method attach : file {$filename} can't be found";return false;}                 $subhdr= "--{$this->boundary}/nContent-Type: {$ctype};/n name=/"{$basename}/";/nContent-Transfer-Encoding: base64/nContent-Disposition: {$disposition};/n  filename=/"{$basename}/"/n";                 $ata[$k++] = $subhdr;                 $linesz= filesize( $filename)+1;                 $fp= fopen( $filename, 'r' );                 $ata[$k++] = chunk_split(base64_encode(fread( $fp, $linesz)));                 fclose($fp);             }             $fullBody .= implode($sep, $ata);         }         else         {             $fullBody = $message;         }         reset($this->xheaders);         while( list( $hdr,$value ) = each( $this->xheaders)) {             $headers .= "$hdr: $value/n";         }                  return $this->mail($to,$subject,$fullBody,$headers);     }     function Attach($filename,$filetype = "",$disposition = "inline")     {             if( $filetype == "" )             {                 $filetype = "application/x-unknown-content-type";             }             $this->aattach[] = $filename;             $this->actype[] = $filetype;             $this->adispo[] = $disposition;     }     function Content_type($contenttype)     {         $this->content_type=$contenttype;     }          function Priority($priority)     {         if(!intval($priority))return false;         if(!isset($this->priorities[$priority-1]))return false;         $this->xheaders["X-Priority"] = $this->priorities[$priority-1];         return true;     } } ?>


    最新回复(0)