php基于socket实现SMTP发送邮件的方法


Posted in PHP onMarch 05, 2015

本文实例讲述了php基于socket实现SMTP发送邮件的方法。分享给大家供大家参考。具体分析如下:

php采用socket通过SMTP发送邮件。
用的是php的php-sockets扩展,可以发送纯文本和html格式的邮件。代码如下:

<?php

/**

* 邮件发送类

* 支持发送纯文本邮件和HTML格式的邮件

* @example

* $config = array(

*       "from" => "*****",

*       "to" => "***",

*       "subject" => "test",

*       "body" => "<b>test</b>",

*       "username" => "***",

*       "password" => "****",

*       "isHTML" => true

*   );

*

* $mail = new MySendMail();

*

* $mail->setServer("smtp.126.com");

*

* $mail->setMailInfo($config);

* if(!$mail->sendMail()) {

*   echo $mail->error();

*   return 1;

* }

*/

class MySendMail {

    /**

    * @var 邮件传输代理用户名

    * @access private

    */

    private $_userName;

    /**

    * @var 邮件传输代理密码

    * @access private

    */

    private $_password;

    /**

    * @var 邮件传输代理服务器地址

    * @access protected

    */

    protected $_sendServer;

    /**

    * @var 邮件传输代理服务器端口

    * @access protected

    */

    protected $_port=25;

    /**

    * @var 发件人

    * @access protected

    */

    protected $_from;

    /**

    * @var 收件人

    * @access protected

    */

    protected $_to;

    /**

    * @var 主题

    * @access protected

    */

    protected $_subject;

    /**

    * @var 邮件正文

    * @access protected

    */

    protected $_body;

    /**

    * @var 是否是HTML格式的邮件

    * @access protected

    */

    protected $_isHTML=false;

    /**

    * @var socket资源

    * @access protected

    */

    protected $_socket;

    /**

    * @var 错误信息

    * @access protected

    */

    protected $_errorMessage;

    public function __construct($from="", $to="", $subject="", $body="", $server="", $username="", $password="",$isHTML="", $port="") {

        if(!empty($from)){

            $this->_from = $from;

        }

        if(!empty($to)){

            $this->_to = $to;

        }

        if(!empty($subject)){

            $this->_subject = $subject;

        }

        if(!empty($body)){

            $this->_body = $body;

        }

        if(!empty($isHTML)){

            $this->_isHTML = $isHTML;

        }

        if(!empty($server)){

            $this->_sendServer = $server;

        }

        if(!empty($port)){

            $this->_port = $port;

        }

        if(!empty($username)){

            $this->_userName = $username;

        }

        if(!empty($password)){

            $this->_password = $password;

        }

    }

    /**

    * 设置邮件传输代理

    * @param string $server 代理服务器的ip或者域名

    * @param int $port 代理服务器的端口,smtp默认25号端口

    * @param int $localPort 本地端口

    * @return boolean

    */

    public function setServer($server, $port=25) {

        if(!isset($server) || empty($server) || !is_string($server)) {

            $this->_errorMessage = "first one is an invalid parameter";

            return false;

        }

        if(!is_numeric($port)){

            $this->_errorMessage = "first two is an invalid parameter";

            return false;

        }

        $this->_sendServer = $server;

        $this->_port = $port;

        return true;

    }

    /**

    * 设置邮件

    * @access public

    * @param array $config 邮件配置信息

    * 包含邮件发送人、接收人、主题、内容、邮件传输代理的验证信息

    * @return boolean

    */

    public function setMailInfo($config) {

        if(!is_array($config) || count($config) < 6){

            $this->_errorMessage = "parameters are required";

            return false;

        }

        $this->_from = $config['from'];

        $this->_to = $config['to'];

        $this->_subject = $config['subject'];

        $this->_body = $config['body'];

        $this->_userName = $config['username'];

        $this->_password = $config['password'];

        if(isset($config['isHTML'])){

            $this->_isHTML = $config['isHTML'];

        }

        return true;

    }

    /**

    * 发送邮件

    * @access public

    * @return boolean

    */

    public function sendMail() {

        $command = $this->getCommand();

        $this->socket();

        foreach ($command as $value) {

            if($this->sendCommand($value[0], $value[1])) {

                continue;

            }

            else{

                return false;

            }

        }

        $this->close(); //其实这里也没必要关闭,smtp命令:QUIT发出之后,服务器就关闭了连接,本地的socket资源会自动释放

        echo 'Mail OK!';

        return true;

    }

    /**

    * 返回错误信息

    * @return string

    */

    public function error(){

        if(!isset($this->_errorMessage)) {

            $this->_errorMessage = "";

        }

        return $this->_errorMessage;

    }

    /**

    * 返回mail命令

    * @access protected

    * @return array

    */

    protected function getCommand() {

        if($this->_isHTML) {

            $mail = "MIME-Version:1.0\r\n";

            $mail .= "Content-type:text/html;charset=utf-8\r\n";

            $mail .= "FROM:test<" . $this->_from . ">\r\n";

            $mail .= "TO:<" . $this->_to . ">\r\n";

            $mail .= "Subject:" . $this->_subject ."\r\n\r\n";

            $mail .= $this->_body . "\r\n.\r\n";

        }

        else{

            $mail = "FROM:test<" . $this->_from . ">\r\n";

            $mail .= "TO:<" . $this->_to . ">\r\n";

            $mail .= "Subject:" . $this->_subject ."\r\n\r\n";

            $mail .= $this->_body . "\r\n.\r\n";

        }

        $command = array(

                array("HELO sendmail\r\n", 250),

                array("AUTH LOGIN\r\n", 334),

                array(base64_encode($this->_userName) . "\r\n", 334),

                array(base64_encode($this->_password) . "\r\n", 235),

                array("MAIL FROM:<" . $this->_from . ">\r\n", 250),

                array("RCPT TO:<" . $this->_to . ">\r\n", 250),

                array("DATA\r\n", 354),

                array($mail, 250),

                array("QUIT\r\n", 221)

        );

        return $command;

    }

    /**

    * @access protected

    * @param string $command 发送到服务器的smtp命令

    * @param int $code 期望服务器返回的响应吗

    * @param boolean

    */

    protected function sendCommand($command, $code) {

        echo 'Send command:' . $command . ',expected code:' . $code . '<br />';

        //发送命令给服务器

        try{

            if(socket_write($this->_socket, $command, strlen($command))){

                //读取服务器返回

                $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 private

    * @return boolean

    */

    private function socket() {

        if(!function_exists("socket_create")) {

            $this->_errorMessage = "extension php-sockets must be enabled";

            return false;

        }

        //创建socket资源

        $this->_socket = socket_create(AF_INET, SOCK_STREAM, getprotobyname('tcp'));

        if(!$this->_socket) {

            $this->_errorMessage = socket_strerror(socket_last_error());

            return false;

        }

        //连接服务器

        if(!socket_connect($this->_socket, $this->_sendServer, $this->_port)) {

            $this->_errorMessage = socket_strerror(socket_last_error());

            return false;

        }

        socket_read($this->_socket, 1024);

        return true;

    }

    /**

    * 关闭socket

    * @access private

    * @return boolean

    */

    private 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;

    }

}

/**************************** Test ***********************************/

$config = array(

        "from" => "XXXXX",

        "to" => "XXXXX",

        "subject" => "test",

        "body" => "<b>test</b>",

        "username" => "XXXXX",

        "password" => "******",

        //"isHTML" => true

    );

$mail = new MySendMail();

$mail->setServer("smtp.126.com");

$mail->setMailInfo($config);

if(!$mail->sendMail()) {

    echo $mail->error();

    return 1;

}

希望本文所述对大家的php程序设计有所帮助。

PHP 相关文章推荐
提问的智慧(2)
Oct 09 PHP
dede全站URL静态化改造[070414更正]
Apr 17 PHP
PHP print类函数使用总结
Jun 25 PHP
PHP防CC攻击实现代码
Dec 29 PHP
关于js与php互相传值的介绍
Jun 25 PHP
PHP改进计算字符串相似度的函数similar_text()、levenshtein()
Oct 27 PHP
PHP中static关键字以及与self关键字的区别
Jul 01 PHP
PHP内核学习教程之php opcode内核实现
Jan 27 PHP
浅析PHP中的i++与++i的区别及效率
Jun 15 PHP
PHP类型约束用法示例
Sep 28 PHP
php使用str_replace替换多维数组的实现方法分析
Jun 15 PHP
php反序列化长度变化尾部字符串逃逸(0CTF-2016-piapiapia)
Feb 15 PHP
php计算两个整数的最大公约数常用算法小结
Mar 05 #PHP
PHP 使用memcached简单示例分享
Mar 05 #PHP
Ubuntu中搭建Nginx、PHP环境最简单的方法
Mar 05 #PHP
PHP实现支持SSL连接的SMTP邮件发送类
Mar 05 #PHP
PHP 使用redis简单示例分享
Mar 05 #PHP
memcache一致性hash的php实现方法
Mar 05 #PHP
PHP将session信息存储到数据库的类实例
Mar 04 #PHP
You might like
PHP中file_exists函数不支持中文名的解决方法
2014/07/26 PHP
添加到收藏夹代码(兼容几乎所有的浏览器)
2007/01/09 Javascript
利用ASP发送和接收XML数据的处理方法与代码
2007/11/13 Javascript
jquery 简单的进度条实现代码
2010/03/11 Javascript
jQuery列表拖动排列具体实现
2013/11/04 Javascript
php的文件上传入门教程(实例讲解)
2014/04/10 Javascript
javascript删除一个html元素节点的方法
2014/12/20 Javascript
jQuery中delegate()方法用法实例
2015/01/19 Javascript
jQuery中$this和$(this)的区别介绍(一看就懂)
2015/07/06 Javascript
jQuery遍历json的方法(推荐)
2016/06/12 Javascript
Ajax的概述与实现过程
2016/11/18 Javascript
jQuery Validate设置onkeyup验证的实例代码
2016/12/09 Javascript
JS正则匹配URL网址的方法(可匹配www,http开头的一切网址)
2017/01/06 Javascript
JS实现二叉查找树的建立以及一些遍历方法实现
2017/04/17 Javascript
微信小程序基于高德地图查找位置并显示文字
2019/10/30 Javascript
vue 微信分享回调iOS和安卓回调出现错误的解决
2020/09/07 Javascript
JavaScript实现滑块验证解锁
2021/01/07 Javascript
python使用multiprocessing模块实现带回调函数的异步调用方法
2015/04/18 Python
简单介绍Python中用于求最小值的min()方法
2015/05/15 Python
python如何删除文件中重复的字段
2019/07/16 Python
python函数的万能参数传参详解
2019/07/26 Python
Python脚本如何在bilibili中查找弹幕发送者
2020/06/04 Python
详解Python3 定义一个跨越多行的字符串的多种方法
2020/09/06 Python
html5开发三八女王节表白神器
2018/03/07 HTML / CSS
html5唤醒APP小记
2019/03/27 HTML / CSS
什么是会话Bean
2015/05/14 面试题
学生处主任岗位职责
2013/12/01 职场文书
检查接待方案
2014/02/27 职场文书
三爱活动实施方案
2014/03/19 职场文书
2014党员自我评议表范文
2014/09/20 职场文书
领导班子四风查摆对照检查材料思想汇报
2014/10/05 职场文书
2014年业务工作总结
2014/11/17 职场文书
英语专业毕业论文答辩开场白
2015/05/27 职场文书
年会主持人开场白台词
2015/05/29 职场文书
早恋主题班会
2015/08/14 职场文书
golang的文件创建及读写操作
2022/04/14 Golang