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

本类参考了网上关于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; 
    } 


} 
?> 
 

 

posted @ 2016-06-11 11:39  八路逆袭寡妇村  阅读(230)  评论(0)    收藏  举报
www.zxzidian.com