首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 發送郵件四大方案完整指南:mail()、qmail 管道、PHPMailer、PEAR Net_SMTP

     編輯:PHP 綜合知識

PHP 專案中發送郵件是基本需求,但選擇哪種方式常讓開發者猶豫。本文系統整理四種主流方案:內建 mail()、qmail/sendmail 管道、PHPMailer 類別、PEAR Net_SMTP,並提供實戰程式碼與優缺點分析,助你依專案情境選型。

方案一:內建 mail() 函式

最簡單,直接呼叫系統 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);
?>
  • ✅ 零依賴、部署簡單
  • ❌ 無 SMTP 驗證、難以處理附件、進垃圾箱機率高、錯誤處理弱

方案二:qmail / sendmail 管道(底層管道寫入)

透過 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 mail() 限制
  • ❌ 強依賴本地 MTA、需手動組裝 MIME、維護性差

方案三:PHPMailer(推薦主流專案)

功能最完整的純 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();
?>
  • ✅ 功能豐富、社群活躍、相容性高、支援 Composer
  • ❌ 體積較大(含多語言檔),極簡專案可能過重

方案四:PEAR Net_SMTP(輕量 SMTP 客戶端)

需安裝 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();
?>
  • ✅ 極輕量、無額外依賴、學習 SMTP 協議好教材
  • ❌ 需手動組裝 MIME、無附件支援、錯誤處理需自行實作、PEAR 維護狀態較舊

選型建議總覽

方案適用場景維護性功能完整度
mail()簡單通知、內部測試、無附件★★★★★★☆☆☆☆
qmail/sendmail 管道本地 MTA 已就緒、高吞吐、無 SMTP 驗證需求★★☆☆☆★★☆☆☆
PHPMailer正式專案、需附件/HTML/驗證/SSL、長期維護★★★★☆★★★★★
PEAR Net_SMTP極輕量需求、教學、嵌入式環境★★★☆☆★★☆☆☆

結論:現代 PHP 專案首選 PHPMailer(Composer 安裝),兼顧功能與維護性;僅發簡單通知且環境受控時,mail() 或管道可作為備選。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved