关注前端开发
关注用户体验

PHP邮件mail()函数解析和SMTP使用方法及乱码问题

前段时间由于一个需求需要使用评论自动发送邮件到网站官方邮箱的功能,期间碰到不少问题特别是乱码问题,经过一番纠结后终于完美解决了。

一、使用PHP内置的mail 函数

语法: mail(to,subject,message,headers,parameters)

  • to 规定邮件的接收者
  • subject 规定邮件的主题。该参数不能包含任何换行字符
  • message 规定要发送的消息
  • headers 规定额外的报头,比如 From, Cc 以及 Bcc
  • parameters 规定 sendmail 程序的额外参数。

碰到的主要问题是乱码问题,刚开始是某些客户端接收邮件时好(比如QQ邮箱,估计带自动那个识别编码)的有些不foxmail、ipad显示乱码,解决方式正确的设置这个mail的headers就行了,下面是我使用的完美的无乱码的例子。

<?php
// 当发送 HTML 电子邮件时,请始终设置 content-type
$headers = "MIME-Version: 1.0" . "\r\n";

$headers .= "Content-type:text/html; charset=utf-8";

mail($to,$subject,$message,$headers);
?>

优点:使用方便就一个简单的函数
缺点:需要php.ini支持该函数,如果某些服务器不支持而又不能改环境那就不行了而且总是不稳定,发的有时能收到有时不能。

二、使用SMTP发送邮件

这里使用一个已经封装好的smtp类email.class.php类被我修改过,增加了编码设置,没加编码设置的话会在某些不能自动识别编码的客户端上出现乱码。

关于这个类的使用:

<?php
require_once ('email.class.php');

$smtpserver = "smtp.exmail.qq.com";
$smtpserverport =25;
$smtpusermail = "lyushine@qq.com";
$smtpuser = "lyushine@qq.com";
$smtppass = "xxxxxx";
$mailtype = "HTML";

$smtp = new smtp($smtpserver,$smtpserverport,true,$smtpuser,$smtppass);
$smtp->debug = false;
$smtp->sendmail($to, $smtpusermail, $subject,$message, $mailtype,"utf-8");
?>

看以上代码大概了解了吧。先引入email.class.php然后实例化smtp类,配置debug模式,发送邮件,需要注意的是设置最后的编码。

刚开始我网上找的没有对编码进行处理导致乱码。

关于 headers 中 subject 的乱码:

不要把任何除了 iso-8859-1 编码之外的文字直接放进 subject,正确的方式是让 subject 里头的文字符合 RFC 2047 的规范,假设你的 subject 处的文字的编码是 GB2312,那么正确的 subject 应该是这样的格式 $headers[‘subject’] = ‘=?GB2312?B?’ . base64_encode(‘标题文字’) . ‘?=';如果是 UTF-8 的话,把上面开头的 GB2312 替换成 UTF-8 即可。推荐在标题处使用 GB2312 编码,因为 MTA 的分化实在是严重,大部分的 MSP 使用的都是自己开发的 MTA,而相信国内的大部分 MTA 无论如何都是可以支持 GB2312 编码的。

在这里我把对subject的处理在了类里面,而外面只要传参设置编码为utf-8或者GB2312就行了。在email.class.php里是这样处理的,这样有效的解决了乱码问题。

优点:可靠性强,稳定
缺点:代码较多,邮箱的账号密码必须使用明文存于本站中,不安全因素增加,需要在自己的邮箱配置开启smtp服务

下面附上 email.class.php

未经允许不得转载:大前端 » PHP邮件mail()函数解析和SMTP使用方法及乱码问题
分享到:更多 ()

评论 6

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  1. #2

    百度云的云消息好像也开始不支持HTML了,不知道是不是WP自身问题

    babytomas5年前 (2013-02-09)回复
  2. #1

    标题的编码还好弄,正文的编码好麻烦,各家邮局的定义各不相同~
    最后我直接拿个phpmailer来使用
    phpmailer使用方法

    独自流浪5年前 (2012-09-03)回复
    • 这两个测试过 foxmail、outlook、网易邮箱、腾讯邮箱、ipad无乱码。

      宇轩5年前 (2012-09-03)回复
      • 大前端也能投稿了?
        你对message里面的中文正文也是这样处理吗?

        独自流浪5年前 (2012-09-03)回复
        • 设置了head信息和把TITLE设置好的话就不用对正文进行处理了的,class里面处理

          if($mailtype=="HTML"){
          $header .= "Content-Type:text/html;Charset=\"".$additional_headers."\"\r\n";

          另外你可以向大前端申请当编辑。
          }

          宇轩5年前 (2012-09-03)
      • 你好,我用了你提供的这个邮件发送类,但是后面提示出错
        Trying to smtp.exmail.qq.com:25
        220 smtp.qq.com Esmtp QQ Mail Server
        Connected to relay host smtp.exmail.qq.com
        > HELO localhost
        250 smtp.qq.com
        > AUTH LOGIN bHl1c2hpbmVAcXEuY29t
        334 UGFzc3dvcmQ6
        > eHh4eHh4
        535 Authentication failed
        Error: Remote host returned “535 Authentication failed”
        Error: Error occurred while sending HELO command.
        Error: Cannot send email to
        Disconnected from remote host
        邮件发送失败

        天字号笨蛋4年前 (2013-10-26)回复

themebetter 国内更好的WordPress主题服务商

立即前往