悠悠楠杉
如何使用PHP发送带附件的邮件?PHPMailer完整实战教程
一、为什么选择PHPMailer?
在Web开发中,邮件发送是注册验证、订单通知等场景的刚需。虽然PHP自带mail()函数,但存在三个致命缺陷:
- 功能简陋(不支持附件)
- 易被标记为垃圾邮件
- 依赖服务器邮件服务
PHPMailer作为开源库解决了这些问题,它具有以下优势:
- 支持SMTP认证
- 可添加多个附件
- 内嵌HTML内容和图片
- 完善的错误处理机制
- 全球95%的PHP邮件系统采用
二、准备工作
1. 环境要求
- PHP 5.5+(推荐7.0+)
- 已安装Composer
- 有效的SMTP服务(如QQ邮箱、阿里云企业邮箱)
2. 安装PHPMailer
在项目目录执行:
bash
composer require phpmailer/phpmailer
三、核心代码实现
php
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'vendor/autoload.php';
$mail = new PHPMailer(true);
try {
// SMTP配置
$mail->isSMTP();
$mail->Host = 'smtp.exmail.qq.com'; // SMTP服务器
$mail->SMTPAuth = true;
$mail->Username = 'your@domain.com';
$mail->Password = 'yourpassword';
$mail->SMTPSecure = 'ssl'; // 加密方式
$mail->Port = 465; // SMTP端口
// 邮件内容
$mail->setFrom('noreply@domain.com', '系统管理员');
$mail->addAddress('recipient@example.com', '李经理'); // 收件人
$mail->addReplyTo('service@domain.com', '客服中心');
// 添加附件
$mail->addAttachment('/var/www/uploads/contract.pdf'); // 路径附件
$mail->addAttachment($_FILES['file']['tmp_name'], '用户上传.jpg'); // 表单上传
// 邮件内容
$mail->isHTML(true);
$mail->Subject = '2023年度报表 - 请查收';
$mail->Body = '<h1>重要文件</h1><p>附件包含:</p><ul>'
.'<li>Q3财务报告</li><li>客户签约合同</li></ul>';
$mail->AltBody = '请使用HTML邮件客户端查看内容';
$mail->send();
echo '邮件已发送';
} catch (Exception $e) {
echo "发送失败: {$mail->ErrorInfo}";
}
四、关键点详解
1. 附件添加技巧
addAttachment()
方法支持两种形式:
- 服务器绝对路径(推荐)
- 上传文件的临时路径(需处理表单上传)
- 大文件建议分卷压缩后发送(超过10MB可能被拒收)
2. SMTP调试技巧
启用调试模式能看到详细交互日志:
php
$mail->SMTPDebug = 2; // 级别1-4
3. 垃圾邮件规避策略
- 设置DKIM和SPF记录
- 避免使用freemail发件箱
- HTML与纯文本内容需一致
- 添加退订链接
五、常见问题排查
连接超时
- 检查防火墙是否开放465/587端口
- 尝试更换SMTPSecure为'tls'
认证失败
- 确认密码是否包含特殊字符
- 企业邮箱可能需要专用授权码
附件丢失
- 确保PHP有文件读取权限
- 检查附件路径是否包含中文
六、高级应用场景
1. 批量发送带附件邮件
php
$users = [
['email'=>'a@test.com', 'name'=>'张三', 'file'=>'a.pdf'],
//...
];
foreach($users as $user){
$mail->clearAddresses(); // 清空上次收件人
$mail->addAddress($user['email'], $user['name']);
$mail->addAttachment('files/'.$user['file']);
// 其他发送逻辑
}
2. 嵌入图片附件
php
$mail->addEmbeddedImage('logo.png', 'logo_cid');
$mail->Body = '<img src="cid:logo_cid"> 公司标识';