强适应性的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
;
    }


}
?>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值