Skip to content

17.1 发送邮件

为什么需要发送邮件

在 Web 应用程序中,发送邮件是一项常见的功能,它可以用于:

  • 用户注册验证:发送验证邮件,确认用户邮箱的有效性
  • 密码重置:发送密码重置链接,帮助用户找回密码
  • 订单通知:发送订单确认、发货通知等
  • 系统通知:发送系统相关的通知和提醒
  • 营销邮件:发送促销信息、 newsletters 等

PHP 发送邮件的方法

1. 使用 mail() 函数

PHP 内置的 mail() 函数是最基本的发送邮件的方法:

php
// 发送邮件
$to = 'recipient@example.com';
$subject = '邮件主题';
$message = '邮件内容';
$headers = 'From: sender@example.com' . "\r\n" .
    'Reply-To: sender@example.com' . "\r\n" .
    'X-Mailer: PHP/' . phpversion();

if (mail($to, $subject, $message, $headers)) {
    echo '邮件发送成功';
} else {
    echo '邮件发送失败';
}

2. 使用 PHPMailer 库

PHPMailer 是一个功能强大的邮件发送库,支持 SMTP、HTML 邮件、附件等功能:

安装

bash
composer require phpmailer/phpmailer

使用

php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require 'vendor/autoload.php';

$mail = new PHPMailer(true);

try {
    // 服务器设置
    $mail->SMTPDebug = 2; // 启用详细调试输出
    $mail->isSMTP(); // 使用 SMTP
    $mail->Host = 'smtp.example.com'; // SMTP 服务器
    $mail->SMTPAuth = true; // 启用 SMTP 认证
    $mail->Username = 'user@example.com'; // SMTP 用户名
    $mail->Password = 'password'; // SMTP 密码
    $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // 启用 TLS 加密
    $mail->Port = 587; // TCP 端口

    // 收件人
    $mail->setFrom('from@example.com', '发件人名称');
    $mail->addAddress('recipient@example.com', '收件人名称'); // 添加收件人
    $mail->addReplyTo('reply@example.com', '回复地址');

    // 附件
    $mail->addAttachment('/var/tmp/file.tar.gz'); // 添加附件

    // 内容
    $mail->isHTML(true); // 设置邮件格式为 HTML
    $mail->Subject = '邮件主题';
    $mail->Body    = '<b>HTML 邮件内容</b>';
    $mail->AltBody = '纯文本邮件内容';

    $mail->send();
    echo '邮件发送成功';
} catch (Exception $e) {
    echo "邮件发送失败: {$mail->ErrorInfo}";
}

3. 使用 Swift Mailer 库

Swift Mailer 是另一个流行的邮件发送库,功能丰富,易于使用:

安装

bash
composer require swiftmailer/swiftmailer

使用

php
require 'vendor/autoload.php';

// 创建邮件传输
$transport = (new Swift_SmtpTransport('smtp.example.com', 587, 'tls'))
    ->setUsername('user@example.com')
    ->setPassword('password');

// 创建邮件发送器
$mailer = new Swift_Mailer($transport);

// 创建消息
$message = (new Swift_Message('邮件主题'))
    ->setFrom(['sender@example.com' => '发件人名称'])
    ->setTo(['recipient@example.com' => '收件人名称'])
    ->setBody('<b>HTML 邮件内容</b>', 'text/html')
    ->addPart('纯文本邮件内容', 'text/plain');

// 发送邮件
$result = $mailer->send($message);
echo "发送了 {$result} 封邮件";

邮件发送最佳实践

1. 使用 SMTP 服务器

使用 SMTP 服务器发送邮件比使用 mail() 函数更可靠,因为:

  • SMTP 服务器提供更好的错误处理
  • SMTP 服务器可以验证发件人身份
  • SMTP 服务器可以提高邮件的送达率

2. 配置 SPF 和 DKIM

配置 SPF (Sender Policy Framework) 和 DKIM (DomainKeys Identified Mail) 可以提高邮件的可信度,减少被标记为垃圾邮件的可能性:

  • SPF:指定哪些服务器可以代表你的域名发送邮件
  • DKIM:使用加密签名验证邮件的真实性

3. 使用队列发送邮件

对于大量邮件发送,应该使用队列系统,避免阻塞应用程序:

php
// 将邮件添加到队列
$queue->push(new SendEmailJob($to, $subject, $message));

// 后台处理队列
// php artisan queue:work (Laravel)

4. 测试邮件发送

在开发环境中,可以使用邮件测试服务,如 Mailtrap:

php
// Mailtrap 配置
$mail->Host = 'smtp.mailtrap.io';
$mail->Username = 'your-mailtrap-username';
$mail->Password = 'your-mailtrap-password';
$mail->Port = 2525;

5. 优化邮件内容

  • 使用 HTML 邮件:HTML 邮件更美观,信息更丰富
  • 添加退订链接:遵循反垃圾邮件法规,添加退订选项
  • 优化邮件标题:使用吸引人的标题,提高打开率
  • 使用模板:使用邮件模板,保持一致的品牌形象

实战演练

场景:用户注册验证邮件

php
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require 'vendor/autoload.php';

// 生成验证令牌
$verification_token = bin2hex(random_bytes(32));

// 保存令牌到数据库
// ...

// 发送验证邮件
$mail = new PHPMailer(true);

try {
    // 服务器设置
    $mail->isSMTP();
    $mail->Host = 'smtp.example.com';
    $mail->SMTPAuth = true;
    $mail->Username = 'user@example.com';
    $mail->Password = 'password';
    $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
    $mail->Port = 587;

    // 收件人
    $mail->setFrom('no-reply@example.com', 'Example Site');
    $mail->addAddress($user_email, $user_name);

    // 内容
    $mail->isHTML(true);
    $mail->Subject = '请验证您的邮箱';
    
    $verification_link = "http://example.com/verify.php?token=$verification_token";
    $mail->Body = "
        <h1>欢迎注册 Example Site</h1>
        <p>请点击以下链接验证您的邮箱:</p>
        <a href='$verification_link'>验证邮箱</a>
        <p>如果您没有注册,请忽略此邮件。</p>
    ";
    $mail->AltBody = "欢迎注册 Example Site\n请访问以下链接验证您的邮箱:\n$verification_link\n如果您没有注册,请忽略此邮件。";

    $mail->send();
    echo '验证邮件已发送,请检查您的邮箱';
} catch (Exception $e) {
    echo "邮件发送失败: {$mail->ErrorInfo}";
}
?>

场景:密码重置邮件

php
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require 'vendor/autoload.php';

// 生成密码重置令牌
$reset_token = bin2hex(random_bytes(32));

// 保存令牌到数据库
// ...

// 发送密码重置邮件
$mail = new PHPMailer(true);

try {
    // 服务器设置
    $mail->isSMTP();
    $mail->Host = 'smtp.example.com';
    $mail->SMTPAuth = true;
    $mail->Username = 'user@example.com';
    $mail->Password = 'password';
    $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
    $mail->Port = 587;

    // 收件人
    $mail->setFrom('no-reply@example.com', 'Example Site');
    $mail->addAddress($user_email, $user_name);

    // 内容
    $mail->isHTML(true);
    $mail->Subject = '密码重置请求';
    
    $reset_link = "http://example.com/reset.php?token=$reset_token";
    $mail->Body = "
        <h1>密码重置请求</h1>
        <p>您请求重置您的密码,请点击以下链接:</p>
        <a href='$reset_link'>重置密码</a>
        <p>如果您没有请求重置密码,请忽略此邮件。</p>
        <p>此链接将在 1 小时后过期。</p>
    ";
    $mail->AltBody = "密码重置请求\n您请求重置您的密码,请访问以下链接:\n$reset_link\n如果您没有请求重置密码,请忽略此邮件。\n此链接将在 1 小时后过期。";

    $mail->send();
    echo '密码重置邮件已发送,请检查您的邮箱';
} catch (Exception $e) {
    echo "邮件发送失败: {$mail->ErrorInfo}";
}
?>

总结

发送邮件是 Web 应用程序中的常见功能,PHP 提供了多种发送邮件的方法,包括内置的 mail() 函数和第三方库(如 PHPMailer、Swift Mailer)。通过使用这些方法,可以实现各种邮件发送功能,如用户注册验证、密码重置、订单通知等。

在开发过程中,应该注意以下几点:

  • 使用 SMTP 服务器提高邮件送达率
  • 配置 SPF 和 DKIM 减少被标记为垃圾邮件的可能性
  • 使用队列系统处理大量邮件发送
  • 优化邮件内容,提高用户体验
  • 测试邮件发送功能,确保其正常工作

通过合理使用邮件发送功能,可以提高应用程序的用户体验和可靠性。

© 2026 编程马·菜鸟教程 版权所有