PHP 發送郵件不僅限於 mail(),根據項目架構、性能要求、安全性需求,可選擇管道模式、PHPMailer、PEAR Net_SMTP 等多種方案。本文系統梳理四種主流方式的原理、代碼示例與選型建議。
<?php
$to = 'user@example.com';
$subject = '測試郵件';
$message = '這是純文本內容';
$headers = "From: sender@example.com\r\nContent-Type: text/plain; charset=UTF-8\r\n";
mail($to, $subject, $message, $headers);
?>
php.ini SMTP 參數、無異步隊列。通過 popen() 打開管道,直接向 sendmail 或 qmail-inject 寫入郵件數據流。
<?php
function send_check_mail($email, $subject, $from, $body) {
$cmd = "/var/qmail/bin/qmail-inject $email";
$handle = popen($cmd, 'w');
if (!$handle) return false;
fwrite($handle, "From: $from\n");
fwrite($handle, "Return-Path: $from\n");
fwrite($handle, "To: $email\n");
fwrite($handle, "Subject: $subject\n");
fwrite($handle, "Mime-Version: 1.0\n");
fwrite($handle, "Content-Type: text/html; charset=\"UTF-8\"\n\n");
fwrite($handle, $body . "\n");
pclose($handle);
return true;
}
// 使用
send_check_mail('user@example.com', '測試', 'system@site.com', 'HTML 內容
');
?>
<?php
$pp = popen("/usr/sbin/sendmail -t", 'w');
fputs($pp, "To: to@example.com\r\n");
fputs($pp, "From: from@example.com\r\n");
fputs($pp, "Subject: Test\r\n");
fputs($pp, "Content-Type: text/html; charset=UTF-8\r\n\r\n");
fputs($pp, "HTML 體\r\n");
pclose($pp);
?>
mail() 封裝,直接與 MTA 交互,性能略好,支持完整 MIME 結構。PHPMailer 是標準庫級組件,支持 SMTP 認證、TLS/SSL、多附件、HTML/文本替代體、嵌入圖片、多收件人、郵件隊列等。
<?php
require 'vendor/autoload.php';
use PHPMailer\PHPMailer\PHPMailer;
$mail = new PHPMailer(true);
try {
// SMTP 配置
$mail->isSMTP();
$mail->Host = 'smtp.example.com';
$mail->SMTPAuth = true;
$mail->Username = 'user@example.com';
$mail->Password = 'password';
$mail->SMTPSecure = 'tls'; // 或 'ssl'
$mail->Port = 587;
// 發件/收件
$mail->setFrom('from@example.com', '系統通知');
$mail->addAddress('to@example.com', '用戶');
$mail->addReplyTo('reply@example.com');
// 內容
$mail->isHTML(true);
$mail->Subject = 'PHPMailer 測試';
$mail->Body = 'HTML 正文
支持中文
';
$mail->AltBody = '純文本備選';
// 附件
$mail->addAttachment('/path/to/file.pdf', 'report.pdf');
$mail->addAttachment('/path/to/image.jpg');
$mail->send();
echo '發送成功';
} catch (Exception $e) {
echo "發送失敗: {$mail->ErrorInfo}";
}
?>
<?php
// mail.inc.php
require 'vendor/autoload.php';
use PHPMailer\PHPMailer\PHPMailer;
class MyMailer extends PHPMailer {
public function __construct() {
parent::__construct(true);
$this->isSMTP();
$this->Host = 'smtp.example.com';
$this->SMTPAuth = true;
$this->Username = 'system@example.com';
$this->Password = 'secret';
$this->SMTPSecure = 'tls';
$this->Port = 587;
$this->setFrom('system@example.com', '系統');
$this->CharSet = 'UTF-8';
}
}
// 業務代碼
require 'mail.inc.php';
$mail = new MyMailer();
$mail->addAddress('user@example.com');
$mail->Subject = '訂單通知';
$mail->Body = '您的訂單已發貨';
$mail->addAttachment('/tmp/order.pdf');
$mail->send();
?>
直接操作 SMTP 命令流程(HELO、MAIL FROM、RCPT TO、DATA),適合極簡依賴、需精細控制協議細節的場景。
<?php
require_once 'Net/SMTP.php';
$smtp = new Net_SMTP('smtp.example.com', 587);
$smtp->connect();
$smtp->helo('example.com');
$smtp->auth('user@example.com', 'password', 'LOGIN'); // 需支持 AUTH
$smtp->mailFrom('from@example.com');
$smtp->rcptTo('to@example.com');
$date = date('r');
$headers = "Date: $date\r\n";
$headers .= "From: from@example.com\r\n";
$headers .= "To: to@example.com\r\n";
$headers .= "Subject: Test\r\n";
$headers .= "Content-Type: text/html; charset=UTF-8\r\n\r\n";
$body = "Hello
";
$smtp->data($headers . $body);
$smtp->disconnect();
?>
| 維度 | mail() | 管道 | PHPMailer | Net_SMTP |
|---|---|---|---|---|
| 依賴 | 無 | 本地 MTA | Composer 包 | PEAR 包 |
| SMTP 認證 | 不支持 | 不支持 | 完美支持 | 手動實現 |
| TLS/SSL | 不支持 | 不支持 | 支持 | 手動實現 |
| 附件/HTML | 手動構造 | 手動構造 | 原生支持 | 手動構造 |
| 異步/隊列 | 無 | 無 | 需自行實現 | 無 |
| 送達率 | 低 | 中 | 高(配合 SPF/DKIM) | 中 |
| 推薦場景 | 測試/極簡 | 高併發本地投遞 | 生產環境首選 | 學習/極簡依賴 |
選對工具,郵件發送不再是痛點。PHPMailer 以豐富功能、活躍社區、良好文檔成為 PHP 郵件發送的事實標準。