PHP 專案中發送郵件是基本需求,但選擇哪種方式常讓開發者猶豫。本文系統整理四種主流方案:內建 mail()、qmail/sendmail 管道、PHPMailer 類別、PEAR Net_SMTP,並提供實戰程式碼與優缺點分析,助你依專案情境選型。
最簡單,直接呼叫系統 MTA(如 sendmail、postfix)。
<?php
$to = 'user@example.com';
$subject = '測試郵件';
$message = '<h1>HTML 內容</h1>';
$headers = "From: system@example.com\r\nContent-Type: text/html; charset=UTF-8\r\n";
mail($to, $subject, $message, $headers);
?>
透過 popen() 開啟管道直接餵資料給 MTA,適合本地已配置好 qmail/sendmail 的環境。
<?php
function send_check_mail($email, $subject, $uid, $buffer) {
$command = "/var/qmail/bin/qmail-inject $email";
$handle = popen($command, "w");
if (!$handle) return false;
$from = "webmaster@example.com";
fwrite($handle, "From: $from\n");
fwrite($handle, "Return-Path: $from\n");
fwrite($handle, "To: $uid\n");
fwrite($handle, "Subject: $subject\n");
fwrite($handle, "Mime-Version: 1.0\n");
fwrite($handle, "Content-Type: text/html; charset=\"gb2312\"\n\n");
fwrite($handle, $buffer . "\n");
pclose($handle);
return true;
}
// sendmail 管道寫法
$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\r\n");
fputs($pp, "Body content\r\n");
pclose($pp);
?>
功能最完整的純 PHP 郵件庫,支援 SMTP 驗證、SSL/TLS、附件、HTML/純文字替代、多語言、異步發送等。
<?php
require 'vendor/autoload.php'; // Composer 安裝: composer require phpmailer/phpmailer
use PHPMailer\PHPMailer\PHPMailer;
$mail = new PHPMailer(true);
try {
$mail->isSMTP();
$mail->Host = 'smtp.example.com';
$mail->SMTPAuth = true;
$mail->Username = 'user@example.com';
$mail->Password = 'secret';
$mail->SMTPSecure = 'tls';
$mail->Port = 587;
$mail->setFrom('from@example.com', 'Mailer');
$mail->addAddress('to@example.com', 'User');
$mail->Subject = 'PHPMailer 測試';
$mail->isHTML(true);
$mail->Body = '<h1>HTML 內容</h1>';
$mail->AltBody = '純文字備份';
$mail->send();
echo '寄送成功';
} catch (Exception $e) {
echo "寄送失敗: {$mail->ErrorInfo}";
}
?>
進階:繼承自訂預設值
<?php
// MyMailer.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 = 'user@example.com';
$this->Password = 'secret';
$this->SMTPSecure = 'tls';
$this->Port = 587;
$this->From = 'default@example.com';
$this->FromName = 'System';
$this->CharSet = 'UTF-8';
}
}
// 使用
$mail = new MyMailer();
$mail->addAddress('to@example.com');
$mail->Subject = '訂單通知';
$mail->Body = '您的訂單已成立';
$mail->send();
?>
需安裝 pear install Net_SMTP,手動處理 SMTP 協議流程,適合不想引入完整 PHPMailer 的輕量場景。
<?php
require_once 'Net/SMTP.php';
$smtp = new Net_SMTP('smtp.example.com', 587);
$smtp->connect();
$smtp->auth('user@example.com', 'secret', 'PLAIN'); // 或 LOGIN/CRAM-MD5
$smtp->mailFrom('from@example.com');
$smtp->rcptTo('to@example.com');
$date = date('r');
$headers = "Date: $date\r\nFrom: from@example.com\r\nTo: to@example.com\r\nSubject: Test\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n";
$body = '<h1>Hello</h1>';
$smtp->data($headers . $body);
$smtp->disconnect();
?>
| 方案 | 適用場景 | 維護性 | 功能完整度 |
|---|---|---|---|
| mail() | 簡單通知、內部測試、無附件 | ★★★★★ | ★☆☆☆☆ |
| qmail/sendmail 管道 | 本地 MTA 已就緒、高吞吐、無 SMTP 驗證需求 | ★★☆☆☆ | ★★☆☆☆ |
| PHPMailer | 正式專案、需附件/HTML/驗證/SSL、長期維護 | ★★★★☆ | ★★★★★ |
| PEAR Net_SMTP | 極輕量需求、教學、嵌入式環境 | ★★★☆☆ | ★★☆☆☆ |
結論:現代 PHP 專案首選 PHPMailer(Composer 安裝),兼顧功能與維護性;僅發簡單通知且環境受控時,mail() 或管道可作為備選。