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 相关文章推荐
PHP分页显示制作详细讲解
Oct 09 PHP
用PHP实现多级树型菜单
Oct 09 PHP
PHP 文件扩展名 获取函数
Jun 03 PHP
php中获取主机名、协议及IP地址的方法
Nov 18 PHP
功能强大的PHP图片处理类(水印、透明度、旋转)
Oct 21 PHP
编写PHP程序检查字符串中的中文字符个数的实例分享
Mar 17 PHP
ECSHOP完美解决Deprecated: preg_replace()报错的问题
May 17 PHP
PHP简单判断iPhone、iPad、Android及PC设备的方法
Oct 11 PHP
php 从一个数组中随机的取出若干个不同的数实例
Dec 31 PHP
php str_getcsv把字符串解析为数组的实现方法
Apr 05 PHP
PHP实现对xml的增删改查操作案例分析
May 19 PHP
php nginx 实时输出的简单实现方法
Jan 21 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
根德YB400的电路分析
2021/03/02 无线电
PHP也可以?成Shell Script
2006/10/09 PHP
站长助手-网站web在线管理程序 v1.0 下载
2007/05/12 PHP
php页面跳转代码 输入网址跳转到你定义的页面
2013/03/28 PHP
PHP+jQuery 注册模块的改进(一):验证码存入SESSION
2014/10/14 PHP
YII Framework框架教程之国际化实现方法
2016/03/14 PHP
PHP 二维array转换json的实例讲解
2018/08/21 PHP
gearman管理工具GearmanManager的安装与php使用方法示例
2020/02/27 PHP
javascript call和apply方法
2008/11/24 Javascript
获取HTML DOM节点元素的方法的总结
2009/08/21 Javascript
jQuery源码分析-04 选择器-Sizzle-工作原理分析
2011/11/14 Javascript
一款jquery特效编写的大度宽屏焦点图切换特效的实例代码
2013/08/05 Javascript
易操作的jQuery表单提示插件
2015/12/01 Javascript
深入学习AngularJS中数据的双向绑定机制
2016/03/04 Javascript
跨域资源共享 CORS 详解
2016/04/26 Javascript
jQuery实现鼠标经过购物车出现下拉框代码(推荐)
2016/07/21 Javascript
常用Javascript函数与原型功能收藏(必看篇)
2016/10/09 Javascript
jQ处理xml文件和xml字符串的方法(详解)
2016/11/22 Javascript
js实现刷新页面后回到记录时滚动条的位置【两种方案可选】
2016/12/12 Javascript
JS实现iframe自适应高度的方法示例
2017/01/07 Javascript
Jil,高效的json序列化和反序列化库
2017/02/15 Javascript
Vue.js在数组中插入重复数据的实现代码
2017/11/17 Javascript
JavaScript门道之标准库
2018/05/26 Javascript
详解Python核心对象类型字符串
2018/02/11 Python
基于Python Numpy的数组array和矩阵matrix详解
2018/04/04 Python
Python利用Xpath选择器爬取京东网商品信息
2020/06/01 Python
英国领先的瓷砖专家:Walls and Floors
2018/04/27 全球购物
历史学专业大学生找工作的自我评价
2013/10/16 职场文书
高中生期末评语
2014/01/28 职场文书
婚纱摄影师求职信
2014/03/07 职场文书
2014学习全国两会精神心得体会2000字
2014/03/11 职场文书
服务质量承诺书
2014/03/27 职场文书
教育系统干部作风整顿心得体会
2014/09/09 职场文书
党员评议个人总结
2014/10/20 职场文书
三孔导游词
2015/02/05 职场文书
学校后勤工作总结2015
2015/05/15 职场文书