IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

让phpmailer支持中文名称的附件和邮件标题中文乱码

Codyy技术团队 2009-10-14 13:30:44 累计浏览 3,577 次
本机暂存

    phpmailer设置使用utf-8编码发送邮件以后,已经能够正常的发送中文邮件了,当然你调用时传进去的中文参数必须也是utf-8编码才行,但是我发现,即使这样,发送中文文件名的附件的时候,附件名称不能正确的显示。

    比如我们要发送的附件是“测试.txt”,如果在添加附件的时候强制使用指定文件名的方式:

    $mail->AddAttachment($attach, $attach);

    那么发送过去的附件文件名将会是乱码,如果不指定:

    $mail->AddAttachment($attach, $attach);

    那么发送过去的文件名中的中文干脆没了,成了“.txt”。

    究其原因,打开class.phpmailer.php,在大概第1007行左右,函数AddAttachment中,有一句

    $filename = basename($path);

    原因就在这里,现在我们使用的php

    5.1.2,包括他以前的很多版本,basename函数和dirname函数都是不支持中文文件名的,所以一解析就把中文给过滤掉了。而如果强行指定文

    件名为什么还乱码呢,这是因为phpmailer虽然会自动根据你设定的编码方式给主题、正文进行utf-8编码化,但是却不会给附件的文件名编码。现

    在,只需要修改上面这一句,就能够同时解决这两方面的问题了。修改结果如下:

    //$filename = basename($path);

    if (false === strpos($path, ‘/’))

    $filename = $this->EncodeHeader($path);

    else

    $filename = $this->EncodeHeader(substr($path, strrpos($path, ‘/’) + 1));

    不使用basename函数了,改用自己的方法来得到文件名,并且借用了主题Subject的编码函数EncodeHeader来生成utf-8编码形式的附件名称,搞定。

    解决中文标题乱码:

    下面是一个基于 PHPMailer 的发送函数,旧代码了:

    function smtp_main_send( $to, $subject, $message, $from, $fromName )

    {

    $mail = new PHPMailer();

    $mail->CharSet = “UTF-8″; // 设置编码

    $mail->IsSMTP(); // 设置使用SMTP服务发送

    $mail->Host = “smtp.mail.com”;

    $mail->Username = “user”;

    $mail->Password = “pass”;

    $mail->SMTPAuth = true;

    $mail->From = $from;

    $mail->FromName = $fromName;

    if ( is_array( $to ) ) {

    foreach ( $to as $address ) {

    $mail->AddAddress( $address );

    }

    } else {

    $mail->AddAddress( $to );

    }

    $mail->Subject = $subject;

    $mail->Body = $message;

    $mail->AltBody = $message;

    $mail->IsHTML( true );

    return $mail->Send();

    }

    直接这样发送邮件,英文没有问题,但在发送中文的时候标题会有乱码。需要对 class.phpmailer.php 做一些修改:

    修改1,1137 行:

    function EncodeHeader ($str, $position = ‘text’) {

    将函数增加一个参数:

    function EncodeHeader ($str, $position = ‘text’, $pl = 0) {

    if ( $pl ) return “=?” . $this->CharSet . “?B?” . base64_encode($str) . “?=”;

    修改2,796 行:

    $result .= $this->HeaderLine(”Subject”, $this->EncodeHeader(trim($this->Subject)));

    将调用改为:

    $result .= $this->HeaderLine(”Subject”, $this->EncodeHeader(trim($this->Subject),’text’, 1));

同分类推荐文章

  1. 等了十年的 Go 链式管道,终于来了:seq 让你像写 Scala 一样写 Go (2026-06-25 18:38:18)
  2. Go 实验特性详解 (2026-06-21 10:05:27)
  3. amd64 微架构级别对 Go 程序性能提升多少? (2026-06-21 09:38:49)

查看更多 后端 文章 →

建议继续学习

  1. 使用gettext来支持PHP的多语言 (累计阅读 39,270)
  2. WordPress插件开发 -- 在插件使用数据库存储数据 (累计阅读 29,164)
  3. Paypal接口详细代码(PHP版,非API接口) (累计阅读 19,408)
  4. 我的PHP,Python和Ruby之路 (累计阅读 13,147)
  5. include(“./file.php”)和include(“file.php”)区别 (累计阅读 12,789)
  6. 15个最好的免费开源电子商务平台 (累计阅读 12,541)
  7. Redis消息队列的若干实现方式 (累计阅读 12,088)
  8. 到底什么是MVC? (累计阅读 11,865)
  9. 整理了一份招PHP高级工程师的面试题 (累计阅读 11,708)
  10. Rolling cURL: PHP并发最佳实践 (累计阅读 11,488)