整合ThinkPHP功能系列之PHPMailer发送SMTP邮件可带附件

2018-06-06 14:19:18 浏览数 (1)

最近公司赶项目,只能抽出来时间去写点别的东西,然后也在给十年之约项目写签约博客申请审核系统,憋大招啊 ?

博客没有发过关于十年之约的文章,但是我也是已经加入了十年之约,同时也加入了十年之约的项目组,过段时间等系统上线了再发关于十年之约这个项目的介绍等其他东西,这篇文章还是讲使用PHPMailer发送SMTP邮件,因为十年之约项目审核以后会给通过的博客发送邮件以及会带上一个公约附件

PHPMailer是一个封装好的PHP邮件发送类,支持发送HTML内容的电子邮件,以及可以添加附件发送,并不像PHP本身mail()函数需要服务器环境支持,还是十分好用的,在一些需要邮箱注册的地方也很方便

下载PHPMailer

下载PHPMailer包,然后放在TP框架的Vendor目录下,路径是/ThinkPHP/Library/Vendor/

下载地址:OSC,Github

压缩包中很多东西是没有用的,作为不研究直接使用来说,只要保留以下文件即可

  • class.phpmailer.php
  • class.smtp.php
  • class.pop3.php

你也可以都留着,都留着也才一百来KB

项目集成

PHPMailer属于第三方类库,并且命名规范不符合TP的要求,所以应当使用第三方类库Vendor方式打开

代码语言:javascript复制
function sendMail($to, $subject, $content){
    Vendor('phpmailer.class#phpmailer');
    $mail = new PHPMailer(); //实例化
    // 装配邮件服务器
    if (C('MAIL_SMTP')) {
        $mail->IsSMTP();  //启动SMTP
    }
    $mail->Host = C('MAIL_HOST'); //SMTP服务器地址
    $mail->SMTPAuth = C('MAIL_SMTPAUTH'); //启用SMTP认证
    $mail->Username = C('MAIL_USERNAME');//邮箱名称
    $mail->Password = C('MAIL_PASSWORD');//邮箱密码
    $mail->SMTPSecure = C('MAIL_SECURE');//发件人地址
    $mail->CharSet = C('MAIL_CHARSET');//邮件头部信息
    $mail->From = C('MAIL_USERNAME');//SMTP服务器登陆用户名
    $mail->AddAddress($to);
    $mail->FromName = '沈唁志'; //发件人是谁
//  $mail->AddAttachment('./Public/test.png','沈唁志.png'); 
// 添加附件,并指定名称
    $mail->IsHTML(C('MAIL_ISHTML'));//是否是HTML字样
    $mail->Subject = $subject;// 邮件标题信息
    $mail->Body = $content;//邮件内容
    // 发送邮件
    if (!$mail->Send()) {
        return FALSE;
    } else {
        return TRUE;
    }
}

在使用的Vendor引入的时候用Vendor(‘phpmailer.class#phpmailer’);为什么使用#呢?

phpmailer代表文件夹 . 后面的代表文件名 class.phpmailer,将 . 换成 # 可以避免在解析的时候解析出错,因为从根本原理上讲 vendor 也是通过import实现的(具体可参照TP官方文档)

为了方便在全局使用,所以将sendMail()定义成了全局数组,定义在Application/Common/Common/functions.php中之后在任何地方都可以无条件调用

使用TP的C方法来获取配置信息,当然不要忘了在config.php加入一下配置

代码语言:javascript复制
// 配置邮件发送服务器
'MAIL_SMTP'                     =>TRUE,
'MAIL_HOST'                     =>'smtp.exmail.qq.com',//邮件发送SMTP服务器
'MAIL_SMTPAUTH'                 =>TRUE,
'MAIL_USERNAME'                 =>'52o@qq52o.cn',//SMTP服务器登陆用户名
'MAIL_PASSWORD'                 =>'XXXXXXXXXXXXXXXXX',//SMTP服务器登陆密码
'MAIL_SECURE'                   =>'tls',
'MAIL_CHARSET'                  =>'utf-8',
'MAIL_ISHTML'                   =>TRUE,

补全邮件发送服务器,以及用户名密码就可以进行邮件发送了

代码语言:javascript复制
/**
 * 发送邮件demo
 */
public function sendMail()
{
    $to = '52o@qq52o.cn';
    $subject = '邮件标题';
    $content = '邮件内容';
    if(sendMail($to,$subject,$content)){
        $this->success('发送成功');
    }else{
        $this->error('发送失败');
    }
}

具体的内容根据你的需求来吧,就比如十年之约的附件,发送附件部分我注释掉了,需要的可以打开,有问题评论留言或者联系我QQ等都可以

Github:项目地址,如果项目对你有所帮助,请给一个 star ?


2018年5月18日15:25 补充一下

有点坑了,今天把十年之约的审核系统转移线上,然后发邮件出了点问题,发送邮件直接404

有点气,感觉不是伪静态的事情,找了半天才发现问题所在,一部分还是哪个vendor的事情

我把Debug给关掉了,不然应该会提示Class ‘PHPMailer’ not found

仔细看了一下我之前引用的Vendor('phpmailer.class#phpmailer');

这行代码将PHPMailer引入的,既然提示找不到PHPMailer类,说明没有被正确引入

粗略看了一下vendor()方 法的源码,这才发现其实vendor()方法也就是对import()方法进行了一次参数组装,然后还是交给了import()方法处理

查看import()方法的源码又发现,在import()方法中,对于上面传入参数的解析其实就是将’.’替换成’/’,将’#’替换成了’.’,baseurl则由vendor()方法自动补充上了,指向Vendor目录

所以上面vendor()方法中的参数最终被解析成了如下目录:

代码语言:javascript复制
Library/Vendor/phpmailer/class.phpmailer.php

而PHPMailer的入口文件的实际目录地址为:

代码语言:javascript复制
Library/Vendor/PHPMailer/class.phpmailer.php

内容都一样的,不过用的是Linux的服务器,所以对大小写是严格区分的,这样当然不能成功导入这个类,而解决办法就是将vendor()引入改为:

代码语言:javascript复制
vendor('PHPMailer.class#phpmailer');

修改引入以后按理说是没有问题了,然后点发送邮件,浏览器加载的圈圈动了 ? 然后跳转error发送失败

带了报错Language string failed to load:tls

服务器25端口是肯定不能用的,tls使用的也是25端口,将funciton.php中的tls改成ssl,然后再加上一个端口465就没问题了

具体代码看Github吧…

0 人点赞