1. 程式人生 > >php通過socket程式設計,以SMTP將郵件傳送到指定的QQ郵箱裡面。

php通過socket程式設計,以SMTP將郵件傳送到指定的QQ郵箱裡面。

在剛開始先配置好php.ini檔案:

(1)我是在window 7 下面進行配置的。

(2)將擴充套件extension=php_openssl.dll,extension=php_sockets.dll開啟

(3)設定allow_url_fopen = On,SMTP = localhost,smtp_port = 25,

          當然sendmail_from,sendmail_path可以不用設定。但在Unix下sendmail_path需要設定

接下來用qq郵箱測試時需要設定:

(1)開啟qq郵箱設定。

(2)然後在賬戶中將pop3/smtp勾選,儲存設定。當然這裡注意自己的郵箱和測試郵箱都要開啟。

這裡簡單介紹一下HTTP狀態含義一邊測試使用,這是我測試瀏覽器顯示的內容:

     220 smtp.qq.com Esmtp QQ Mail Server
   250-smtp.qq.com
   250-PIPELINING
   250-SIZE 52428800
   250-STARTTLS
   250-AUTH LOGIN PLAIN
   250-AUTH=LOGIN SMTP使用者驗證
   250-MAILCOMPRESS
   250 8BITMIME
   334 VXNlcm5hbWU6 輸入使用BASE64編碼的使用者名稱
   334 UGFzc3dvcmQ6 輸入使用BASE64編碼的密碼
   235 Authentication successful 驗證通過


   250 Ok 接受者郵件地址

250 Ok 告訴伺服器我要開始傳送郵件資料了
   354 End data with.
     250 Ok: queued as
    郵件傳送成功

下面便是傳送郵件的一個SMTP類,經過本人修改,沒問題了,class.mail.php:

<?php
define('SMTP_STATUS_NOT_CONNECTED', 1, TRUE);
define('SMTP_STATUS_CONNECTED', 2, TRUE);
/**
* @desc   SMTP 郵件伺服器
* @param  伺服器引數和郵件資訊
*/
class p8_smtp
{
    var $connection;
    var $recipients;
    var $headers;
    var $timeout;
    var $errors;
    var $status;
    var $body;
    var $from;
    var $host;
    var $port;
    var $helo;
    var $auth;
    var $user;
    var $pass;
    
    /**
     *  引數為一個數組
     *  host        SMTP 伺服器的主機       預設:localhost
     *  port        SMTP 伺服器的埠       預設:25
     *  helo        傳送HELO命令的名稱      預設:localhost
     *  user        SMTP 伺服器的使用者名稱     預設:空值
     *  pass        SMTP 伺服器的登陸密碼   預設:空值
     *  timeout     連線超時的時間          預設:5
     *  @return  bool
     */
    
    function p8_smtp($params = array())
    {
        if(!defined('CRLF')) define('CRLF', "\r\n", TRUE);
        
        $this->timeout  = 5;
        $this->status   = SMTP_STATUS_NOT_CONNECTED;
        $this->host     = 'localhost';
        $this->port     = 25;
        $this->auth     = FALSE;
        $this->user     = '';
        $this->pass     = '';
        $this->errors   = array();
        foreach($params as $key => $value)
        {
            $this->$key = $value;
        }
        
        $this->helo     = $this->host;
        //  如果沒有設定使用者名稱則不驗證         
        $this->auth = ('' == $this->user) ? FALSE : TRUE;
    }
    function connect($params = array())
    {
        if(!isset($this->status))
        {
            $obj = new p8_smtp($params);
            
            if($obj->connect())
            {
                $obj->status = SMTP_STATUS_CONNECTED;
            }
            return $obj;
        }
        else
        {    
            $this->connection = fsockopen($this->host, $this->port, $errno, $errstr, $this->timeout);
            socket_set_timeout($this->connection, 0, 250000);
            $greeting = $this->get_data();
            
            if(is_resource($this->connection))
            {
                $this->status = 2;
                return $this->auth ? $this->ehlo() : $this->helo();
            }
            else
            {                           
                $this->errors[] = 'Failed to connect to server: '.$errstr;
                return FALSE;
            }
        }
    }
    
    /**
     * 引數為陣列
     * recipients      接收人的陣列
     * from            發件人的地址,也將作為回覆地址
     * headers         頭部資訊的陣列
     * body            郵件的主體
     */
    
    function send($params = array())
    {
        foreach($params as $key => $value)
        {
            $this->set($key, $value);
        }     
        if($this->is_connected())
        {
            //  伺服器是否需要驗證 
            if($this->auth)
            {
                if(!$this->auth())  return FALSE;
            }
            $this->mail($this->from);
            if(is_array($this->recipients))
            {
                foreach($this->recipients as $value)
                {
                    $this->rcpt($value);
                }               
            }
            else
            {
                $this->rcpt($this->recipients);
            }          
            if(!$this->data()) return FALSE;
            $headers = str_replace(CRLF.'.', CRLF.'..', trim(implode(CRLF, $this->headers)));
            $body    = str_replace(CRLF.'.', CRLF.'..', $this->body);
            $body    = $body[0] == '.' ? '.'.$body : $body;
            $this->send_data($headers);
            $this->send_data('');
            $this->send_data($body);
            $this->send_data('.');
            return (substr(trim($this->get_data()), 0, 3) === '250');
        }
        else
        {
            $this->errors[] = 'Not connected!';
            return FALSE;
        }
    }
    
    function helo()
    {
        if(is_resource($this->connection)
                AND $this->send_data('HELO '.$this->helo)
                AND substr(trim($error = $this->get_data()), 0, 3) === '250' )
        {
            return TRUE;
        }
        else
        {
            $this->errors[] = 'HELO command failed, output: ' . trim(substr(trim($error),3));
            return FALSE;
        }
    }
    
    
    function ehlo()
    {
        if(is_resource($this->connection)
                AND $this->send_data('EHLO '.$this->helo)
                AND substr(trim($error = $this->get_data()), 0, 3) === '250' )
        {
            return TRUE;
        }
        else
        {
            $this->errors[] = 'EHLO command failed, output: ' . trim(substr(trim($error),3));
            return FALSE;
        }
    }
    
    function auth()
    {   
        if(is_resource($this->connection)
                AND $this->send_data('AUTH LOGIN')
                AND substr(trim($error = $this->get_data()),0,3) === '334'
                AND $this->send_data(base64_encode($this->user))            // Send username
                AND substr(trim($error = $this->get_data()),0,3) === '334'
                AND $this->send_data(base64_encode($this->pass))            // Send password
                AND substr(trim($error = $this->get_data()),0,3) === '235' )
        {
            return TRUE;
        }
        else
        {    
            $this->errors[] = 'AUTH command failed: ' . trim(substr(trim($error),3));
            return FALSE;
        }
    }
    
    function mail($from)
    {
        if($this->is_connected()
            AND $this->send_data('MAIL FROM:<'.$from.'>')
            AND substr(trim($this->get_data()), 0, 2) === '250' )
        {
            return TRUE;
        }
        else
        {
            return FALSE;
        }
    }
    function rcpt($to)
    {
        if($this->is_connected()
            AND $this->send_data('RCPT TO:<'.$to.'>')
            AND substr(trim($error = $this->get_data()), 0, 2) === '25' )
        {
            return TRUE;
        }
        else
        {
            $this->errors[] = trim(substr(trim($error), 3));
            return FALSE;
        }
    }
    function data()
    {      
        if($this->is_connected()
            AND $this->send_data('DATA')
            AND substr(trim($error = $this->get_data()), 0, 3) === '354' )
        { 
            return TRUE;
        }
        else
        {
            $this->errors[] = trim(substr(trim($error), 3));
            return FALSE;
        }
    }
    function is_connected()
    {             
        return (is_resource($this->connection) AND ($this->status === SMTP_STATUS_CONNECTED));
    }
    function send_data($data)
    {
        if(is_resource($this->connection))
        {        
            return fwrite($this->connection, $data.CRLF, strlen($data)+2);
        }
        else
        {
            return FALSE;
        }
    }
    function &get_data()
    {
        $return = '';
        $line   = '';
        if(is_resource($this->connection))
        {
            while(strpos($return, CRLF) === FALSE OR substr($line,3,1) !== ' ')
            {
                $line    = fgets($this->connection, 512);
                echo $line."<br/>";
                $return .= $line;
            }
            return $return;
        }
        else
        {
            return FALSE;
        }
    }
    function set($var, $value)
    {
        $this->$var = $value;
        return TRUE;
    }
} // End of class



class smtp
{
	var $debug;
	var $host;
	var $port;
	var $auth;
	var $user;
	var $pass;

	function smtp($host = "", $port = 25,$auth = false,$user,$pass){
		$this->host=$host;
		$this->port=$port;
		$this->auth=$auth;
		$this->user=$user;
		$this->pass=$pass;
	}

	function sendmail($to,$from, $subject, $content, $T=0){
		//$name, $email, $subject, $content, $type=0
		$type=1;
		$name=array($from);
		$email=array($to);
		$_CFG['smtp_host']= $this->host;
		$_CFG['smtp_port']= $this->port;
		$_CFG['smtp_user']= $this->user;
		$_CFG['smtp_pass']= $this->pass;
		$_CFG['name']= $from;
		$_CFG['smtp_mail']= $from;

		$subject = "=?UTF-8?B?".base64_encode($subject)."==?=";
		$content = base64_encode($content);
		$headers[] = "To:=?gbk?B?".base64_encode($name[0])."?= <$email[0]>";
		$headers[] = "From:=?gbk?B?".base64_encode($_CFG['name'])."?= <$_CFG[smtp_mail]>";
		$headers[] = "MIME-Version: Blueidea v1.0";
		$headers[] = "X-Mailer: 9gongyu Mailer v1.0";
		$headers[] = "Subject:$subject";
		$headers[] = ($type == 0) ? "Content-Type: text/plain; charset=gbk; format=flowed" : "Content-Type: text/html; charset=utf-8; format=flowed";
		$headers[] = "Content-Transfer-Encoding: base64";
		$headers[] = "Content-Disposition: inline";
		//    SMTP 伺服器資訊
		$params['host'] = $_CFG['smtp_host'];
		$params['port'] = $_CFG['smtp_port'];
		$params['user'] = $_CFG['smtp_user'];
		$params['pass'] = $_CFG['smtp_pass'];
		if (empty($params['host']) || empty($params['port']))
		{
			// 如果沒有設定主機和埠直接返回 false
			return false;
		}
		else
		{
			//  傳送郵件
			$send_params['recipients']    = $email;
			$send_params['headers']        = $headers;
			$send_params['from']        = $_CFG['smtp_mail'];
			$send_params['body']        = $content;

		    /*  用於測試資訊
			echo "<pre>";
			print_r($params);
			print_r($send_params);
			echo "</pre>";
			exit;
		    */
			$smtp = new p8_smtp($params);
			if($smtp->connect() AND $smtp->send($send_params))
			{
				return TRUE;
			}
			else 
			{
				return FALSE;
			} 
		}
	}
}

?>


下面便是測試部分sendmail.php:

<?php
/**
* @desc   SMTP 郵件伺服器
* @param  伺服器引數和郵件資訊
*/
header("Content-type:text/html;charset=utf-8");
require_once("class.mail.php");
/**
*伺服器資訊
*/
$MailServer = 'smtp.qq.com';      //SMTP 伺服器
$MailPort   = '25';					 //SMTP伺服器埠號 預設25
$MailId     = '請填寫自己QQ郵箱';  //伺服器郵箱帳號
$MailPw     = '自己QQ郵箱密碼';			     //伺服器郵箱密碼

/**
*客戶端資訊
*/
$Title      = 'TESTMAIL成功';        //郵件標題
$Content    = '測試郵件內容';        //郵件內容
$email      = '要傳送到的QQ郵箱';	 //接收者郵箱
$smtp = new smtp($MailServer,$MailPort,true,$MailId,$MailPw);
$smtp->debug = false;
if($smtp->sendmail($email,$MailId, $Title, $Content, "HTML")){
	 echo '郵件傳送成功';            //返回結果
} else {
	 echo '郵件傳送失敗';            //$succeed = 0;
}
?>