亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > PHP > 正文

PHP實現支持SSL連接的SMTP郵件發送類

2024-05-04 23:31:54
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了PHP實現支持SSL連接的SMTP郵件發送類,實例分析了php實現smtp郵件發送類的原理與技巧,以及支持SSL連接的方法,需要的朋友可以參考下
 

本文實例講述了PHP實現支持SSL連接的SMTP郵件發送類。分享給大家供大家參考。具體如下:

該實例代碼測試過了gmail和QQ郵箱的SMTP。具體代碼如下:

復制代碼代碼如下:
<?php
/**
* 郵件發送類
* 支持發送純文本郵件和HTML格式的郵件,可以多收件人,多抄送,多秘密抄送,帶附件(單個或多個附件),支持到服務器的ssl連接
* 需要的php擴展:sockets、Fileinfo和openssl。
* 編碼格式是UTF-8,傳輸編碼格式是base64
* @example
* $mail = new MySendMail();
* $mail->setServer("smtp@126.com", "XXXXX@126.com", "XXXXX"); //設置smtp服務器,普通連接方式
* $mail->setServer("smtp.gmail.com", "XXXXX@gmail.com", "XXXXX", 465, true); //設置smtp服務器,到服務器的SSL連接
* $mail->setFrom("XXXXX"); //設置發件人
* $mail->setReceiver("XXXXX"); //設置收件人,多個收件人,調用多次
* $mail->setCc("XXXX"); //設置抄送,多個抄送,調用多次
* $mail->setBcc("XXXXX"); //設置秘密抄送,多個秘密抄送,調用多次
* $mail->addAttachment("XXXX"); //添加附件,多個附件,調用多次
* $mail->setMail("test", "<b>test</b>"); //設置郵件主題、內容
* $mail->sendMail(); //發送
*/
class MySendMail {
    /**
    * @var string 郵件傳輸代理用戶名
    * @access protected
    */
    protected $_userName;
    /**
    * @var string 郵件傳輸代理密碼
    * @access protected
    */
    protected $_password;
    /**
    * @var string 郵件傳輸代理服務器地址
    * @access protected
    */
    protected $_sendServer;
    /**
    * @var int 郵件傳輸代理服務器端口
    * @access protected
    */
    protected $_port;
    /**
    * @var string 發件人
    * @access protected
    */
    protected $_from;
    /**
    * @var array 收件人
    * @access protected
    */
    protected $_to = array();
    /**
    * @var array 抄送
    * @access protected
    */
    protected $_cc = array();
    /**
    * @var array 秘密抄送
    * @access protected
    */
    protected $_bcc = array();
    /**
    * @var string 主題
    * @access protected
    */
    protected $_subject;
    /**
    * @var string 郵件正文
    * @access protected
    */
    protected $_body;
    /**
    * @var array 附件
    * @access protected
    */
    protected $_attachment = array();
    /**
    * @var reource socket資源
    * @access protected
    */
    protected $_socket;
    /**
    * @var reource 是否是安全連接
    * @access protected
    */
    protected $_isSecurity;
    /**
    * @var string 錯誤信息
    * @access protected
    */
    protected $_errorMessage;
    /**
    * 設置郵件傳輸代理,如果是可以匿名發送有郵件的服務器,只需傳遞代理服務器地址就行
    * @access public
    * @param string $server 代理服務器的ip或者域名
    * @param string $username 認證賬號
    * @param string $password 認證密碼
    * @param int $port 代理服務器的端口,smtp默認25號端口
    * @param boolean $isSecurity 到服務器的連接是否為安全連接,默認false
    * @return boolean
    */
    public function setServer($server, $username="", $password="", $port=25, $isSecurity=false) {
        $this->_sendServer = $server;
        $this->_port = $port;
        $this->_isSecurity = $isSecurity;
        $this->_userName = empty($username) ? "" : base64_encode($username);
        $this->_password = empty($password) ? "" : base64_encode($password);
        return true;
    }
    /**
    * 設置發件人
    * @access public
    * @param string $from 發件人地址
    * @return boolean
    */
    public function setFrom($from) {
        $this->_from = $from;
        return true;
    }
    /**
    * 設置收件人,多個收件人,調用多次.
    * @access public
    * @param string $to 收件人地址
    * @return boolean
    */
    public function setReceiver($to) {
        $this->_to[] = $to;
        return true;
    }
    /**
    * 設置抄送,多個抄送,調用多次.
    * @access public
    * @param string $cc 抄送地址
    * @return boolean
    */
    public function setCc($cc) {
        $this->_cc[] = $cc;
        return true;
    }
    /**
    * 設置秘密抄送,多個秘密抄送,調用多次
    * @access public
    * @param string $bcc 秘密抄送地址
    * @return boolean
    */
    public function setBcc($bcc) {
        $this->_bcc[] = $bcc;
        return true;
    }
    /**
    * 設置郵件附件,多個附件,調用多次
    * @access public
    * @param string $file 文件地址
    * @return boolean
    */
    public function addAttachment($file) {
        if(!file_exists($file)) {
            $this->_errorMessage = "file " . $file . " does not exist.";
            return false;
        }
        $this->_attachment[] = $file;
        return true;
    }
    /**
    * 設置郵件信息
    * @access public
    * @param string $body 郵件主題
    * @param string $subject 郵件主體內容,可以是純文本,也可是是HTML文本
    * @return boolean
    */
    public function setMail($subject, $body) {
        $this->_subject = base64_encode($subject);
        $this->_body = base64_encode($body);
        return true;
    }
    /**
    * 發送郵件
    * @access public
    * @return boolean
    */
    public function sendMail() {
        $command = $this->getCommand();
        $this->_isSecurity ? $this->socketSecurity() : $this->socket();
        foreach ($command as $value) {
            $result = $this->_isSecurity ? $this->sendCommandSecurity($value[0], $value[1]) : $this->sendCommand($value[0], $value[1]);
            if($result) {
                continue;
            }
            else{
                return false;
            }
        }
        //其實這里也沒必要關閉,smtp命令:QUIT發出之后,服務器就關閉了連接,本地的socket資源會自動釋放
        $this->_isSecurity ? $this->closeSecutity() : $this->close();
        return true;
    }
    /**
    * 返回錯誤信息
    * @return string
    */
    public function error(){
        if(!isset($this->_errorMessage)) {
            $this->_errorMessage = "";
        }
        return $this->_errorMessage;
    }
    /**
    * 返回mail命令
    * @access protected
    * @return array
    */
    protected function getCommand() {
        $separator = "----=_Part_" . md5($this->_from . time()) . uniqid(); //分隔符
        $command = array(
                array("HELO sendmail/r/n", 250)
            );
        if(!empty($this->_userName)){
            $command[] = array("AUTH LOGIN/r/n", 334);
            $command[] = array($this->_userName . "/r/n", 334);
            $command[] = array($this->_password . "/r/n", 235);
        }
        //設置發件人
        $command[] = array("MAIL FROM: <" . $this->_from . ">/r/n", 250);
        $header = "FROM: <" . $this->_from . ">/r/n";
        //設置收件人
        if(!empty($this->_to)) {
            $count = count($this->_to);
            if($count == 1){
                $command[] = array("RCPT TO: <" . $this->_to[0] . ">/r/n", 250);
                $header .= "TO: <" . $this->_to[0] .">/r/n";
            }
            else{
                for($i=0; $i<$count; $i++){
                    $command[] = array("RCPT TO: <" . $this->_to[$i] . ">/r/n", 250);
                    if($i == 0){
                        $header .= "TO: <" . $this->_to[$i] .">";
                    }
                    elseif($i + 1 == $count){
                        $header .= ",<" . $this->_to[$i] .">/r/n";
                    }
                    else{
                        $header .= ",<" . $this->_to[$i] .">";
                    }
                }
            }
        }
        //設置抄送
        if(!empty($this->_cc)) {
            $count = count($this->_cc);
            if($count == 1){
                $command[] = array("RCPT TO: <" . $this->_cc[0] . ">/r/n", 250);
                $header .= "CC: <" . $this->_cc[0] .">/r/n";
            }
            else{
                for($i=0; $i<$count; $i++){
                    $command[] = array("RCPT TO: <" . $this->_cc[$i] . ">/r/n", 250);
                    if($i == 0){
                    $header .= "CC: <" . $this->_cc[$i] .">";
                    }
                    elseif($i + 1 == $count){
                        $header .= ",<" . $this->_cc[$i] .">/r/n";
                    }
                    else{
                        $header .= ",<" . $this->_cc[$i] .">";
                    }
                }
            }
        }
        //設置秘密抄送
        if(!empty($this->_bcc)) {
            $count = count($this->_bcc);
            if($count == 1) {
                $command[] = array("RCPT TO: <" . $this->_bcc[0] . ">/r/n", 250);
                $header .= "BCC: <" . $this->_bcc[0] .">/r/n";
            }
            else{
                for($i=0; $i<$count; $i++){
                    $command[] = array("RCPT TO: <" . $this->_bcc[$i] . ">/r/n", 250);
                    if($i == 0){
                    $header .= "BCC: <" . $this->_bcc[$i] .">";
                    }
                    elseif($i + 1 == $count){
                        $header .= ",<" . $this->_bcc[$i] .">/r/n";
                    }
                    else{
                        $header .= ",<" . $this->_bcc[$i] .">";
                    }
                }
            }
        }
        //主題
        $header .= "Subject: =?UTF-8?B?" . $this->_subject ."?=/r/n";
        if(isset($this->_attachment)) {
            //含有附件的郵件頭需要聲明成這個
            $header .= "Content-Type: multipart/mixed;/r/n";
        }
        elseif(false){
            //郵件體含有圖片資源的,且包含的圖片在郵件內部時聲明成這個,如果是引用的遠程圖片,就不需要了
            $header .= "Content-Type: multipart/related;/r/n";
        }
        else{
            //html或者純文本的郵件聲明成這個
            $header .= "Content-Type: multipart/alternative;/r/n";
        }
        //郵件頭分隔符
        $header .= "/t" . 'boundary="' . $separator . '"';
        $header .= "/r/nMIME-Version: 1.0/r/n";
        //這里開始是郵件的body部分,body部分分成幾段發送
        $header .= "/r/n--" . $separator . "/r/n";
        $header .= "Content-Type:text/html; charset=utf-8/r/n";
        $header .= "Content-Transfer-Encoding: base64/r/n/r/n";
        $header .= $this->_body . "/r/n";
        $header .= "--" . $separator . "/r/n";
        //加入附件
        if(!empty($this->_attachment)){
            $count = count($this->_attachment);
            for($i=0; $i<$count; $i++){
                $header .= "/r/n--" . $separator . "/r/n";
                $header .= "Content-Type: " . $this->getMIMEType($this->_attachment[$i]) . '; name="=?UTF-8?B?' . base64_encode( basename($this->_attachment[$i]) ) . '?="' . "/r/n";
                $header .= "Content-Transfer-Encoding: base64/r/n";
                $header .= 'Content-Disposition: attachment; filename="=?UTF-8?B?' . base64_encode( basename($this->_attachment[$i]) ) . '?="' . "/r/n";
                $header .= "/r/n";
                $header .= $this->readFile($this->_attachment[$i]);
                $header .= "/r/n--" . $separator . "/r/n";
            }
        }
        //結束郵件數據發送
        $header .= "/r/n./r/n";
 
        $command[] = array("DATA/r/n", 354);
        $command[] = array($header, 250);
        $command[] = array("QUIT/r/n", 221);
        return $command;
    }
    /**
    * 發送命令
    * @access protected
    * @param string $command 發送到服務器的smtp命令
    * @param int $code 期望服務器返回的響應嗎
    * @return boolean
    */
    protected function sendCommand($command, $code) {
        echo 'Send command:' . $command . ',expected code:' . $code . '<br />';
        //發送命令給服務器
        try{
            if(socket_write($this->_socket, $command, strlen($command))){
                //當郵件內容分多次發送時,沒有$code,服務器沒有返回
                if(empty($code))  {
                    return true;
                }
                //讀取服務器返回
                $data = trim(socket_read($this->_socket, 1024));
                echo 'response:' . $data . '<br /><br />';
                if($data) {
                    $pattern = "/^".$code."+?/";
                    if(preg_match($pattern, $data)) {
                        return true;
                    }
                    else{
                        $this->_errorMessage = "Error:" . $data . "|**| command:";
                        return false;
                    }
                }
                else{
                    $this->_errorMessage = "Error:" . socket_strerror(socket_last_error());
                    return false;
                }
            }
            else{
                $this->_errorMessage = "Error:" . socket_strerror(socket_last_error());
                return false;
            }
        }catch(Exception $e) {
            $this->_errorMessage = "Error:" . $e->getMessage();
        }
    }
    /**
    * 安全連接發送命令
    * @access protected
    * @param string $command 發送到服務器的smtp命令
    * @param int $code 期望服務器返回的響應嗎
    * @return boolean
    */
    protected function sendCommandSecurity($command, $code) {
        echo 'Send command:' . $command . ',expected code:' . $code . '<br />';
        try {
            if(fwrite($this->_socket, $command)){
                //當郵件內容分多次發送時,沒有$code,服務器沒有返回
                if(empty($code))  {
                    return true;
                }
                //讀取服務器返回
                $data = trim(fread($this->_socket, 1024));
                echo 'response:' . $data . '<br /><br />';
                if($data) {
                    $pattern = "/^".$code."+?/";
                    if(preg_match($pattern, $data)) {
                        return true;
                    }
                    else{
                        $this->_errorMessage = "Error:" . $data . "|**| command:";
                        return false;
                    }
                }
                else{
                    return false;
                }
            }
            else{
                $this->_errorMessage = "Error: " . $command . " send failed";
                return false;
            }
        }catch(Exception $e) {
            $this->_errorMessage = "Error:" . $e->getMessage();
        }
    } 
    /**
    * 讀取附件文件內容,返回base64編碼后的文件內容
    * @access protected
    * @param string $file 文件
    * @return mixed
    */
    protected function readFile($file) {
        if(file_exists($file)) {
            $file_obj = file_get_contents($file);
            return base64_encode($file_obj);
        }
        else {
            $this->_errorMessage = "file " . $file . " dose not exist";
            return false;
        }
    }
    /**
    * 獲取附件MIME類型
    * @access protected
    * @param string $file 文件
    * @return mixed
    */
    protected function getMIMEType($file) {
        if(file_exists($file)) {
            $mime = mime_content_type($file);
            /*if(! preg_match("/gif|jpg|png|jpeg/", $mime)){
                $mime = "application/octet-stream";
            }*/
            return $mime;
        }
        else {
            return false;
        }
    }
    /**
    * 建立到服務器的網絡連接
    * @access protected
    * @return boolean
    */
    protected function socket() {
        //創建socket資源
        $this->_socket = socket_create(AF_INET, SOCK_STREAM, getprotobyname('tcp'));
        if(!$this->_socket) {
            $this->_errorMessage = socket_strerror(socket_last_error());
            return false;
        }
        socket_set_block($this->_socket);//設置阻塞模式
        //連接服務器
        if(!socket_connect($this->_socket, $this->_sendServer, $this->_port)) {
            $this->_errorMessage = socket_strerror(socket_last_error());
            return false;
        }
        $str = socket_read($this->_socket, 1024);
        if(!preg_match("/220+?/", $str)){
            $this->_errorMessage = $str;
            return false;
        }
        return true;
    }
    /**
    * 建立到服務器的SSL網絡連接
    * @access protected
    * @return boolean
    */
    protected function socketSecurity() {
        $remoteAddr = "tcp://" . $this->_sendServer . ":" . $this->_port;
        $this->_socket = stream_socket_client($remoteAddr, $errno, $errstr, 30);
        if(!$this->_socket){
            $this->_errorMessage = $errstr;
            return false;
        }
        //設置加密連接,默認是ssl,如果需要tls連接,可以查看php手冊stream_socket_enable_crypto函數的解釋
        stream_socket_enable_crypto($this->_socket, true, STREAM_CRYPTO_METHOD_SSLv23_CLIENT);
        stream_set_blocking($this->_socket, 1); //設置阻塞模式
        $str = fread($this->_socket, 1024);
        if(!preg_match("/220+?/", $str)){
            $this->_errorMessage = $str;
            return false;
        }
        return true;
    }
    /**
    * 關閉socket
    * @access protected
    * @return boolean
    */
    protected function close() {
        if(isset($this->_socket) && is_object($this->_socket)) {
            $this->_socket->close();
            return true;
        }
        $this->_errorMessage = "No resource can to be close";
        return false;
    }
    /**
    * 關閉安全socket
    * @access protected
    * @return boolean
    */
    protected function closeSecutity() {
        if(isset($this->_socket) && is_object($this->_socket)) {
            stream_socket_shutdown($this->_socket, STREAM_SHUT_WR);
            return true;
        }
        $this->_errorMessage = "No resource can to be close";
        return false;
    }
}

 

希望本文所述對大家的php程序設計有所幫助。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产欧美韩国高清| 亚洲第一免费网站| 欧美国产激情18| 国产精品第七影院| 欧美一级大胆视频| 国产精品扒开腿做爽爽爽的视频| 久久精品国产96久久久香蕉| 成人黄色午夜影院| 国产97在线亚洲| 亚洲精品中文字幕av| 欧美精品在线网站| 在线播放日韩专区| 色老头一区二区三区| 久久久久国产精品免费网站| 亚洲最大在线视频| 成人在线一区二区| 国产精品久久久久7777婷婷| 日本精品久久久久影院| 秋霞av国产精品一区| 久久伊人精品一区二区三区| 亚洲高清一区二| 成人激情视频在线播放| 国产成人精品久久二区二区91| 欧美性xxxxx极品娇小| 久久久久久久999精品视频| 亚洲精品久久久久久久久久久久久| 国产午夜精品理论片a级探花| 亚洲丁香久久久| 中文字幕日韩精品在线观看| 51久久精品夜色国产麻豆| 欧洲成人免费视频| 亚洲视频国产视频| 欧美一区二区大胆人体摄影专业网站| 国产成人高潮免费观看精品| 亚洲偷熟乱区亚洲香蕉av| 精品久久久久久中文字幕大豆网| 久久理论片午夜琪琪电影网| 亚洲天堂视频在线观看| 久久九九国产精品怡红院| 亚洲国内高清视频| 日本高清视频一区| 黄色成人av在线| 91探花福利精品国产自产在线| 亚洲天堂视频在线观看| 国产极品精品在线观看| 久久视频这里只有精品| 久久久伊人欧美| 国产精品无码专区在线观看| 日韩欧美亚洲综合| 精品国产区一区二区三区在线观看| 激情久久av一区av二区av三区| 亚洲精品电影在线观看| 91系列在线观看| 亚洲精品电影网在线观看| 久久影院模特热| 欧美日韩美女在线观看| 成人在线视频网| 久久久久久69| 欧美激情va永久在线播放| 亚洲毛片在线免费观看| 亚洲精品欧美日韩专区| 国产精品亚洲美女av网站| 欧美日韩国产综合新一区| 亚洲天堂精品在线| 欧美日韩在线第一页| 欲色天天网综合久久| 亚洲高清av在线| 久久精品人人爽| 久久中文字幕一区| 日韩一区二区三区在线播放| 国产亚洲欧美日韩美女| 国产亚洲视频中文字幕视频| 欧美电影在线播放| 亚洲欧美在线看| 欧美电影在线观看完整版| 亚洲午夜国产成人av电影男同| 92福利视频午夜1000合集在线观看| 91精品国产自产在线观看永久| 在线观看国产精品淫| 岛国av在线不卡| 国产精品久久久久一区二区| 亚洲一区二区三区xxx视频| 欧美最猛性xxxx| 在线视频国产日韩| 久久久av亚洲男天堂| 91久久国产精品| 国产欧美精品xxxx另类| 国产精品男女猛烈高潮激情| 91国内揄拍国内精品对白| 国产成人精品av| 午夜精品久久久久久久99热浪潮| 成人黄色免费网站在线观看| 日韩在线视频观看正片免费网站| 亚洲视频电影图片偷拍一区| 亚洲人午夜色婷婷| 亚洲精品久久久一区二区三区| 欧美日韩国产999| 国产精品第3页| 亚洲999一在线观看www| 午夜精品美女自拍福到在线| 亚洲日本中文字幕| 狠狠综合久久av一区二区小说| 日韩视频免费在线观看| 国产亚洲欧美日韩美女| 午夜精品久久久久久99热软件| 色综合导航网站| 黄色一区二区在线观看| 一区二区亚洲欧洲国产日韩| 国产精品一区二区三区毛片淫片| 91精品在线播放| 日本a级片电影一区二区| 亚洲精品中文字| 亚洲精品国产综合久久| 精品一区二区三区三区| 日韩精品在线观看网站| 这里只有视频精品| 精品女同一区二区三区在线播放| 国产成人精品av在线| 日av在线播放中文不卡| 欧美中文字幕第一页| 欧美日韩黄色大片| 欧美中文在线观看国产| 亚洲老司机av| 最近中文字幕2019免费| 国产又爽又黄的激情精品视频| 日韩一区二区精品视频| 欧美丰满少妇xxxxx| 日韩av观看网址| 久久精品中文字幕免费mv| 欧美日韩国产二区| 中文字幕免费精品一区| 亚洲日本中文字幕免费在线不卡| 久久国产精品首页| 欧美做受高潮1| 亚洲另类图片色| 亚洲国产女人aaa毛片在线| 亚洲午夜未满十八勿入免费观看全集| 国产精品视频导航| 日韩精品视频免费在线观看| 夜夜嗨av一区二区三区四区| 国产成人精品久久亚洲高清不卡| 成人激情视频在线播放| 亚洲日韩欧美视频| 久久久女女女女999久久| 成人午夜在线视频一区| 国产精品国模在线| 日韩成人激情在线| 9.1国产丝袜在线观看| 国产精品人成电影在线观看| 午夜精品久久久久久久白皮肤| 国产精品免费看久久久香蕉| 欧美丝袜一区二区三区| 欧洲亚洲免费在线| 欧美日韩福利在线观看| 在线播放日韩精品| 狠狠综合久久av一区二区小说| 91在线网站视频| 亚洲国产另类久久精品| 久久久久久久国产| 久久免费精品视频| 国产精品久久中文| 日韩高清不卡av| 久久精品久久精品亚洲人| 2019中文字幕在线|