PHP 内置的 mail() 函数将邮件交给本地的 sendmail 程序,不进行 SMTP 认证,不协商 TLS,也没有结构化的错误报告。PHPMailer 为 PHP 应用提供 SMTP 客户端、MIME 格式化和附件支持。
如何安装 PHPMailer?
使用 Composer:
composer require phpmailer/phpmailer
然后加载自动加载器并导入所需的类:
<?php
require "vendor/autoload.php";
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
如何配置 SMTP 并发送邮件?
创建一个 PHPMailer 实例,通过 isSMTP() 将其切换到 SMTP 模式,然后设置连接和邮件字段。将调用包裹在 try/catch 中,以便发送失败时报告错误而非静默吞掉:
<?php
$mail = new PHPMailer(true); // true enables exceptions
try {
// Server settings
$mail->isSMTP();
$mail->Host = "smtp.example.com";
$mail->SMTPAuth = true;
$mail->Username = getenv("SMTP_USER");
$mail->Password = getenv("SMTP_PASS");
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port = 587;
// Recipients
$mail->setFrom("you@yourdomain.com", "Your App");
$mail->addAddress("recipient@example.org", "Recipient Name");
// Content
$mail->isHTML(true);
$mail->Subject = "Your receipt";
$mail->Body = "<p>Thanks for your order.</p>";
$mail->AltBody = "Thanks for your order. This is the plain-text version.";
$mail->send();
echo "Message sent.";
} catch (Exception $e) {
echo "Send failed: {$mail->ErrorInfo}";
}
SMTPSecure 要与服务器端口匹配:587 端口上的 ENCRYPTION_STARTTLS 将明文连接升级为 TLS,465 端口上的 ENCRYPTION_SMTPS 则在连接时立即协商 TLS。设置 isHTML(true) 后,Body 被视为 HTML,AltBody 则作为纯文本部分,供无法渲染 HTML 的客户端显示。同时包含这两部分还能提高送达能力。向构造函数传入 true 后,失败时会抛出 Exception,而不是返回 false。
如何添加附件?
在 send() 之前调用 addAttachment 并传入文件路径:
<?php
$mail->addAttachment("./invoices/invoice-1042.pdf", "invoice.pdf");
第二个参数用于重命名收件人看到的文件名。可以多次调用以添加多个附件。
使用 Bird 发送
如果想在 PHP 中通过 HTTPS 发送邮件而无需管理 SMTP 连接,请安装 Bird PHP SDK(composer require messagebird/sdk)并调用 $bird->email->send():
<?php
use MessageBird\Bird;
$bird = new Bird(apiKey: getenv("BIRD_API_KEY"));
$message = $bird->email->send(
from: "onboarding@messagebird.dev",
to: ["delivered@messagebird.dev"],
subject: "Hello from PHP",
html: "<p>It works.</p>",
);
echo $message->getId(), " ", $message->getStatus(), "\n";
在配置自定义域名之前,可以使用 onboarding@messagebird.dev 发件人和 delivered@messagebird.dev 沙盒收件人验证你的 API 密钥和载荷。