0

0

发一个可以同时兼容新浪云和百度云的邮件发送类

php中文网

php中文网

发布时间:2016-06-07 11:44:05

|

1231人浏览过

|

来源于php中文网

原创

目前只能发送文字信息,大家可以进行改进,欢迎将改进代码分享出来
感谢redspear 帮助改进,将新的代码放出了 class Email{
    public $config = array(
        'host'   => null,
        'port'   => 25,
        'user'   => null,
        'pass'   => null,
        'from'   => null,
        'debug'  => false,
        'isHtml' => false,
        'param'  => array('socket_create', 'fsockopen'),
        'method' => null,
    );

    public function __set($key, $value){
        $this->config[$key] = $value;
    }

    public function __get($key){
        return $this->config[$key];
    }
    
    public function __construct($config = array()){
        if(is_array($config)) $this->config = array_merge($this->config, $config);

        if(is_null($this->host)) $this->host = C('EMAIL_SMTP');
        if(is_null($this->port)) $this->port = C('EMAIL_PORT');
        if(is_null($this->user)) $this->user = C('EMAIL_USER');
        if(is_null($this->pass)) $this->pass = C('EMAIL_PWD');
        if(is_null($this->from)) $this->from = C('EMAIL_FROM');

        foreach($this->param as $index=>$method){
            if(function_exists($method)){
                $this->method = $index;
                $this->record("检测函数 {$method} 通过");
                break;
            }
        }

        $this->host = gethostbyname($this->host);
        $this->user = base64_encode($this->user);
        $this->pass = base64_encode($this->pass);

        if(is_null($this->method)) $this->record('当前环境不支持发送邮件', true);
    }

    //发送方法
    public function send($to='', $subject='', $body=''){
        if(is_null($this->method)){
            $this->result = false;
            return false;
        }

        if(!$to || !$subject || !$body){
            $this->record('收信人信息不全', true);
            $this->result = false;
            return false;
        }

        $this->to      = $to;      //收信人
        $this->subject = $subject; //邮件主题
        $this->body    = $body;    //邮件内容

        $method = $this->param[$this->method];
        if(!method_exists($this, $method)){
            $this->record("调用方法 {$method} 不存在", true);
            $this->result = false;
            return false;
        }

        $this->$method();
    }

    private function socket_create(){
        $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        if($this->socket){
            $this->record('创建SOCKET:' . socket_strerror(socket_last_error()));
        }else{
            $this->record('初始化失败,请检查您的网络连接和参数', true);
            $this->result = false;
            return false;
        }
        $conn = socket_connect($this->socket, $this->host, $this->port);
        if($conn){
            $this->record('创建SOCKET连接:' . socket_strerror(socket_last_error()));
        }else{
            $this->record('初始化失败,请检查您的网络连接和参数', true);
            $this->result = false;
            return false;
        }
        $this->record("服务器应答:".socket_read($this->socket, 1024)."");

        $this->handle();
    }

    private function socket_create_call($params){
        socket_write($this->socket, $params[0], strlen($params[0]));
        $this->record("客户机命令:{$params[0]}");
        $msg = socket_read($this->socket, 1024);
        $this->record("服务器应答:{$msg}");

        if(isset($params[1]) && strpos($msg, $params[1]) === false){
            $this->record($params[2], true);
            $this->result = false;
        }
    }

    // fsockopen函数发送
    private function fsockopen(){
        $this->socket = fsockopen($this->host, $this->port, $errno, $errstr, 60);
        if($this->socket){
            $this->record("创建SOCKET连接:".$this->host.':'.$this->port);
        }else{
            $this->record('初始化失败,请检查您的网络连接和参数'.$errstr, true);
            $this->result = false;
            return false;
        }
        stream_set_blocking($this->socket, true);
        $this->handle();
    }

    private function fsockopen_call($params){
        fputs($this->socket, $params[0]);
        $this->record("客户机命令:{$params[0]}");
        $msg = fgets($this->socket, 512);
        $this->record("服务器应答:{$msg}");

        if(isset($params[1]) && strpos($msg, $params[1]) === false){
            $this->record($params[2], true);
            $this->result = false;
        }
    }

    private function handle(){
        $all = array();
        array_push($all, "From:{$this->from}\r\n");
        array_push($all, "To:{$this->to}\r\n");
        array_push($all, "Subject:=?utf-8?B?" . base64_encode($this->subject) . "?=\r\n");
        $this->isHtml ? array_push($all, "Content-Type: text/html;\r\n") : array_push($all, "Content-Type: text/plain;\r\n");  //邮件类型 html或文本
        array_push($all, "charset: utf-8\r\n");
        //告诉浏览器信件内容进过了base64编码,最后必须要发一组\r\n产生一个空行,表示头部信息发送完毕
        array_push($all, "Content-Transfer-Encoding: base64\r\n\r\n");
        array_push($all, base64_encode($this->body));

        $all = implode('', $all);

        $method = $this->param[$this->method];
        $call   = $method . '_call';

        if(!method_exists($this, $call)){
            $this->record("调用方法 {$call} 不存在", true);
            $this->result = false;
            return false;
        }

        $items = array(
            array("EHLO wangdong\r\n"),
            array("AUTH LOGIN\r\n"),
            array("{$this->user}\r\n"),
            array("{$this->pass}\r\n", '235', 'smtp 认证失败'),
            array("MAIL FROM:from}>\r\n", '250', '邮件发送失败'),
            array("RCPT TO:to}>\r\n", '250', '邮件发送失败'),
            array("DATA\r\n", '354', '邮件发送失败'),
            array("{$all}\r\n.\r\n", '250', '邮件发送失败'),
            array("QUIT\r\n"),
        );

        //以下是和服务器会话
        foreach($items as $index=>$params){
            $this->$call($params);
            if($this->result === false) return false;

            if($index == 0){
                // fsockopen需要单独处理
                while ($method == 'fsockopen') {
                    $msg = fgets($this->socket, 512);
                    $this->record("服务器应答:{$msg}");
                    if ((substr($msg, 3, 1) != '-') || empty($msg)) break;
                }
            }
        }

        if($this->result !== false) $this->result = true;
    }

    //调试记录
    private function record($msg, $save = false){
        if($save) $this->error = $msg;
        if($this->debug) printf("

%s

多面-AI面试
多面-AI面试

猎聘推出的AI面试平台

下载
\n", $msg);
    }

    //关闭socket
    public function __destruct(){
        $method = $this->param[$this->method];
        switch ($method){
            case 'socket_create':
                socket_close($this->socket);
                break;
            case 'fsockopen':
                fclose($this->socket);
                break;
        }
    }
}

AD:真正免费,域名+虚机+企业邮箱=0元

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
虚拟号码教程汇总
虚拟号码教程汇总

本专题整合了虚拟号码接收验证码相关教程,阅读下面的文章了解更多详细操作。

29

2025.12.25

错误代码dns_probe_possible
错误代码dns_probe_possible

本专题整合了电脑无法打开网页显示错误代码dns_probe_possible解决方法,阅读专题下面的文章了解更多处理方案。

20

2025.12.25

网页undefined啥意思
网页undefined啥意思

本专题整合了undefined相关内容,阅读下面的文章了解更多详细内容。后续继续更新。

37

2025.12.25

word转换成ppt教程大全
word转换成ppt教程大全

本专题整合了word转换成ppt教程,阅读专题下面的文章了解更多详细操作。

6

2025.12.25

msvcp140.dll丢失相关教程
msvcp140.dll丢失相关教程

本专题整合了msvcp140.dll丢失相关解决方法,阅读专题下面的文章了解更多详细操作。

2

2025.12.25

笔记本电脑卡反应很慢处理方法汇总
笔记本电脑卡反应很慢处理方法汇总

本专题整合了笔记本电脑卡反应慢解决方法,阅读专题下面的文章了解更多详细内容。

6

2025.12.25

微信调黑色模式教程
微信调黑色模式教程

本专题整合了微信调黑色模式教程,阅读下面的文章了解更多详细内容。

5

2025.12.25

ps入门教程
ps入门教程

本专题整合了ps相关教程,阅读下面的文章了解更多详细内容。

4

2025.12.25

苹果官网入口直接访问
苹果官网入口直接访问

苹果官网直接访问入口是https://www.apple.com/cn/,该页面具备0.8秒首屏渲染、HTTP/3与Brotli加速、WebP+AVIF双格式图片、免登录浏览全参数等特性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

218

2025.12.24

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Git 教程
Git 教程

共21课时 | 2.2万人学习

Kotlin 教程
Kotlin 教程

共23课时 | 2万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号