最近做项目要发邮件,什么注册确认、密码重置、订单通知,一堆功能都离不开邮件。PHP 自带的 mail() 函数?说实话,用过的都知道有多坑——配置麻烦、兼容性差、容易被当垃圾邮件。最后还是老老实实用 PHPMailer,踩了一些坑,今天把经验整理一下。
为什么是 PHPMailer
PHPMailer 是 PHP 里最老牌的邮件发送库,功能齐全:
- 支持 SMTP 认证,TLS/SSL 加密
- HTML 邮件、附件、嵌入式图片都能搞定
- 抄送、密送、回复地址这些不在话下
环境要求:PHP 5.5 ~ 8.3,需要开启 mbstring 和 openssl 扩展。
安装
推荐用 Composer,省心:
1
| composer require phpmailer/phpmailer
|
不想用 Composer 也行,去 GitHub 下载源码,手动引入文件。但都 2026 年了,还是 Composer 吧。
邮箱服务器配置
发邮件得有 SMTP 服务器,常用的 163 和 QQ 邮箱配置如下:
| 邮箱 |
SMTP 服务器 |
SSL 端口 |
| 163 |
smtp.163.com |
465 或 994 |
| QQ |
smtp.qq.com |
465 或 587 |
重要提醒:163、QQ 这些邮箱默认关闭 SMTP 服务,得去邮箱设置里手动开启,然后生成一个「授权码」。后面代码里的密码填的是授权码,不是你的登录密码!
基础用法
直接上代码,能跑的才是好教程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| <?php use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\Exception;
require 'vendor/autoload.php';
$mail = new PHPMailer(true);
try { $mail->CharSet = "UTF-8"; $mail->isSMTP(); $mail->Host = 'smtp.163.com'; $mail->SMTPAuth = true; $mail->Username = 'your@163.com'; $mail->Password = '授权码'; $mail->SMTPSecure = 'ssl'; $mail->Port = 465;
$mail->setFrom('your@163.com', '发件人名字'); $mail->addAddress('receiver@example.com', '收件人名字');
$mail->isHTML(true); $mail->Subject = '邮件标题'; $mail->Body = '<h1>这是 HTML 邮件内容</h1>';
$mail->send(); echo '发送成功'; } catch (Exception $e) { echo "发送失败: {$mail->ErrorInfo}"; }
|
发送附件
加附件一行代码的事:
1 2
| $mail->addAttachment('/path/to/file.zip'); $mail->addAttachment('/path/to/image.jpg', '图片.jpg');
|
注意路径要写对,相对路径、绝对路径都行,但要确保文件存在。
嵌入图片到邮件正文
想在邮件正文里显示图片,有两种方式:一种是用 <img src="cid:图片id"> 配合 addEmbeddedImage,另一种是直接 base64 编码嵌入。推荐前者:
1 2
| $mail->Body = '<h1>你好</h1><img src="cid:logo">'; $mail->addEmbeddedImage('images/logo.png', 'logo');
|
常见坑和解决方案
1. SMTP connect failed
最常见的错误。原因可能是:
- SMTP 服务没开启(去邮箱设置里开)
- 端口被防火墙拦截(换个端口试试:25、465、587)
- 服务器地址写错了
2. 认证失败
大概率是密码填错了。163、QQ 邮箱要用授权码,不是登录密码。授权码在邮箱设置里生成。
3. 中文乱码
编码问题,加上这句:
1
| $mail->CharSet = "UTF-8";
|
4. SSL 连接失败
检查 PHP 有没有开启 openssl 扩展,php.ini 里把 extension=openssl 前面的分号去掉,重启服务。
5. 邮件进了垃圾箱
原因很多:发件人和 SMTP 认证邮箱不一致、邮件内容太像广告、域名没有配置 SPF 记录。生产环境建议用专业邮件服务,比如 SendGrid、Mailgun,比自己搭 SMTP 靠谱。
调试技巧
开发阶段遇到问题,打开调试模式:
调试完记得关掉,生产环境开调试会暴露敏感信息。
一个完整的例子
把上面的拼起来:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| <?php use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\Exception;
require 'vendor/autoload.php';
$mail = new PHPMailer(true);
try { $mail->CharSet = "UTF-8"; $mail->SMTPDebug = 0; $mail->isSMTP(); $mail->Host = 'smtp.163.com'; $mail->SMTPAuth = true; $mail->Username = 'your@163.com'; $mail->Password = 'your-authorization-code'; $mail->SMTPSecure = 'ssl'; $mail->Port = 465;
$mail->setFrom('your@163.com', 'l1n6yun'); $mail->addAddress('receiver@example.com'); $mail->addReplyTo('your@163.com', 'Reply');
$mail->addAttachment('files/report.pdf');
$mail->isHTML(true); $mail->Subject = '测试邮件'; $mail->Body = '<h2>邮件发送成功!</h2><p>这是一封测试邮件。</p>'; $mail->AltBody = '邮件发送成功!这是一封测试邮件。';
$mail->send(); echo '邮件发送成功'; } catch (Exception $e) { echo "邮件发送失败: {$mail->ErrorInfo}"; }
|
PHPMailer 用起来其实不难,主要是 SMTP 配置容易踩坑。记住几个要点:授权码、端口、编码、调试模式,基本就能搞定大部分场景了。
有问题欢迎评论区交流~