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

PHP 發送郵件的四種主流方式詳解

     編輯:PHP 相關知識

PHP 發送郵件不僅限於 mail(),根據項目架構、性能要求、安全性需求,可選擇管道模式、PHPMailer、PEAR Net_SMTP 等多種方案。本文系統梳理四種主流方式的原理、代碼示例與選型建議。

方式一:內置 mail() 函數(最簡單,受限最多)

<?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);
?>
  • 原理: 調用系統 MTA(如 Sendmail、Postfix)投遞。
  • 優點: 零依賴、代碼極少。
  • 缺點: 無 SMTP 認證、易進垃圾箱、不支持附件/HTML 複雜結構、Windows 下需配置 php.ini SMTP 參數、無異步隊列。
  • 適用: 簡單通知、內部測試、低併發無附件場景。

方式二:管道模式(直接調用 MTA 程序,性能較好)

通過 popen() 打開管道,直接向 sendmail 或 qmail-inject 寫入郵件數據流。

示例:調用 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 內容

'); ?>

示例:調用 sendmail -t(自動解析頭部收件人)

<?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 結構。
  • 缺點: 依賴本地 MTA 穩定性、需管理進程句柄、跨平台差異大(Windows 無 sendmail)、無 SMTP 認證加密。
  • 適用: 高併發、本地 MTA 可靠、Linux 環境、需自定義 MIME 結構。

方式三:PHPMailer(最流行、功能最全、推薦生產環境)

PHPMailer 是標準庫級組件,支持 SMTP 認證、TLS/SSL、多附件、HTML/文本替代體、嵌入圖片、多收件人、郵件隊列等。

基礎用法(SMTP 發送帶附件)

<?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();
?>

方式四:PEAR Net_SMTP(底層 SMTP 協議控制,輕量)

直接操作 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(); ?>
  • 優點: 無框架開銷、直接控制 SMTP 流程、適合嵌入式/微服務。
  • 缺點: 手動構造 MIME、無自動重試、錯誤處理繁瑣、PEAR 維護狀態較弱。
  • 適用: 極簡環境、需自定義 SMTP 命令、學習協議原理。

選型對比總結

維度mail()管道PHPMailerNet_SMTP
依賴無本地 MTAComposer 包PEAR 包
SMTP 認證不支持不支持完美支持手動實現
TLS/SSL不支持不支持支持手動實現
附件/HTML手動構造手動構造原生支持手動構造
異步/隊列無無需自行實現無
送達率低中高(配合 SPF/DKIM)中
推薦場景測試/極簡高併發本地投遞生產環境首選學習/極簡依賴

最佳實踐建議

  1. 生產環境首選 PHPMailer(或 Symfony Mailer),通過 Composer 管理依賴,配置 SMTP + TLS,啟用異常捕獲與日志記錄。
  2. 異步發送: 將發送任務推入隊列(Redis/RabbitMQ/Database),由 Worker 進程消費,避免阻塞 HTTP 響應。
  3. 郵件模板: 使用模板引擎分離內容與邏輯,支持多語言、變量替換。
  4. 聲譽管理: 配置 SPF、DKIM、DMARC 記錄,監控退信率、投訴率,使用專用發信域名/IP。
  5. 測試驗證: 使用 Mailtrap、Ethereal Email 等測試服務驗證郵件內容與渲染。

選對工具,郵件發送不再是痛點。PHPMailer 以豐富功能、活躍社區、良好文檔成為 PHP 郵件發送的事實標準。

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