Skip to content

邮件发送解决方案

本文介绍 PHP 中发送邮件的几种方案,从基础的 mail() 到专业的 PHPMailer。

基础 mail() 函数

php
// 最简单的方式(需要服务器配置好 sendmail)
$to = 'recipient@example.com';
$subject = '测试邮件';
$message = '这是一封测试邮件';
$headers = 'From: sender@example.com';

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

// 发送 HTML 邮件
$headers = "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/html; charset=UTF-8\r\n";
$headers .= "From: sender@example.com\r\n";

$html = '<h1>标题</h1><p>内容</p>';
mail($to, $subject, $html, $headers);

使用 PHPMailer(推荐)

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

require 'vendor/autoload.php';

$mail = new PHPMailer(true);

try {
    // 服务器配置
    $mail->isSMTP();
    $mail->Host = 'smtp.qq.com';           // SMTP 服务器
    $mail->SMTPAuth = true;
    $mail->Username = 'your_email@qq.com';  // 发件人邮箱
    $mail->Password = 'your_auth_code';     // 授权码(不是密码)
    $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
    $mail->Port = 465;

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

    // 抄送和密送
    $mail->addCC('cc@example.com');
    $mail->addBCC('bcc@example.com');

    // 附件
    $mail->addAttachment('/path/to/file.pdf', '文档.pdf');

    // 内容
    $mail->isHTML(true);
    $mail->Subject = '邮件主题';
    $mail->Body = '<h1>HTML 内容</h1><p>这是一封测试邮件</p>';
    $mail->AltBody = '纯文本内容(HTML 不支持时显示)';

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

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

使用 Symfony Mailer

php
use Symfony\Component\Mailer\Transport;
use Symfony\Component\Mailer\Mailer;
use Symfony\Component\Mime\Email;

$transport = Transport::fromDsn('smtp://user:pass@smtp.example.com:587');
$mailer = new Mailer($transport);

$email = (new Email())
    ->from('hello@example.com')
    ->to('you@example.com')
    ->subject('测试邮件')
    ->text('这是纯文本内容')
    ->html('<p>这是 HTML 内容</p>');

$mailer->send($email);

邮件模板封装

php
class MailService {
    private $mailer;

    public function __construct($config) {
        $this->mailer = new PHPMailer(true);
        $this->mailer->isSMTP();
        $this->mailer->Host = $config['host'];
        $this->mailer->Username = $config['username'];
        $this->mailer->Password = $config['password'];
        $this->mailer->Port = $config['port'];
        $this->mailer->CharSet = 'UTF-8';
    }

    public function send($to, $subject, $template, $data = []) {
        $body = $this->renderTemplate($template, $data);

        $this->mailer->clearAddresses();
        $this->mailer->addAddress($to);
        $this->mailer->Subject = $subject;
        $this->mailer->Body = $body;
        $this->mailer->isHTML(true);

        return $this->mailer->send();
    }

    private function renderTemplate($template, $data) {
        extract($data);
        ob_start();
        include "templates/{$template}.php";
        return ob_get_clean();
    }
}

// 使用示例
$mail = new MailService($config);
$mail->send(
    'user@example.com',
    '欢迎注册',
    'welcome',
    ['username' => '张三', 'code' => '123456']
);

异步发送邮件

php
// 将邮件任务存入队列,后台处理
class MailQueue {
    public function push($mailData) {
        // 存入 Redis 或数据库队列
        Redis::lpush('mail_queue', json_encode($mailData));
    }
}

// 消费队列(CLI 脚本)
while (true) {
    $data = Redis::brpop('mail_queue', 0);
    $mail = json_decode($data[1], true);

    try {
        $service = new MailService($config);
        $service->send($mail['to'], $mail['subject'], $mail['body']);
    } catch (Exception $e) {
        // 失败重试或记录日志
        error_log("邮件发送失败: " . $e->getMessage());
    }
}

注意事项

  1. 发送频率限制:各大邮箱服务商都有频率限制
  2. SPF/DKIM 配置:防止邮件进入垃圾箱
  3. 异步处理:邮件发送慢,不要阻塞用户请求
  4. 错误处理:做好重试和日志记录
  5. 测试环境:使用 MailHog 等工具本地测试

Binstork