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

Zend Framework Zend_Mail 發送郵件驗證實戰:解決標題亂碼、HTML 內容、SMTP 認證

     編輯:PHP 綜合知識

前言:Zend_Mail 核心能力

Zend Framework 1.x 的 Zend_Mail 元件提供統一介面發送純文字、HTML、多部分 MIME 郵件,支援 Sendmail (本機 MTA) 與 SMTP 兩種傳輸方式。本文示範:基本發送、SMTP 認證 (Gmail 範例)、HTML 內容、附件、以及**解決中文主題 Base64 編碼亂碼**的標準做法。

一、最簡單發送:本機 Sendmail

require_once 'Zend/Mail.php';
$mail = new Zend_Mail('UTF-8');
$mail->setBodyText('純文字內容')
     ->setFrom('sender@example.com', '發件人名稱')
     ->addTo('recipient@example.com', '收件人名稱')
     ->setSubject('=?UTF-8?B?'.base64_encode('中文主題').'?=') // 關鍵:RFC 2047 編碼
     ->send();

關鍵點:setSubject 必須手動進行 =?charset?encoding?encoded-text?= 編碼,否則中文主題在多數郵件客戶端會顯示亂碼。

二、SMTP 認證發送 (以 Gmail 為例)

require_once 'Zend/Mail.php';
require_once 'Zend/Mail/Transport/Smtp.php';

$config = [
    'auth'     => 'login',
    'username' => 'your@gmail.com',
    'password' => 'your_app_password', // 需開啟兩步驟驗證並產生應用程式密碼
    'ssl'      => 'ssl',             // 或 'tls' 對應 587 port
    'port'     => 465,               // SSL port
];
$transport = new Zend_Mail_Transport_Smtp('smtp.gmail.com', $config);
Zend_Mail::setDefaultTransport($transport);

$mail = new Zend_Mail('UTF-8');
$mail->setBodyHtml('歡迎註冊!
點此啟用帳號') ->setFrom('your@gmail.com', '系統名稱') ->addTo('user@example.com', '用戶名稱') ->setSubject('=?UTF-8?B?'.base64_encode('帳號啟用驗證郵件').'?=') ->send();
  • Gmail SMTP 需「應用程式密碼」,不可直接用登入密碼。
  • ssl 參數值:ssl (465 port) 或 tls (587 port)。

三、進階:HTML + 純文字替代、附件、內嵌圖片

$mail = new Zend_Mail('UTF-8');
// 1. 同時提供 HTML 與純文字 (multipart/alternative)
$mail->setBodyHtml($htmlContent);
$mail->setBodyText(strip_tags($htmlContent)); // 簡易純文字版

// 2. 添加附件
$at = $mail->createAttachment(file_get_contents('/path/report.pdf'));
$at->type        = 'application/pdf';
$at->disposition = Zend_Mime::DISPOSITION_ATTACHMENT;
$at->encoding    = Zend_Mime::ENCODING_BASE64;
$at->filename    = 'report.pdf';

// 3. 內嵌圖片 (CID)
$img = $mail->createAttachment(file_get_contents('/path/logo.png'));
$img->type        = 'image/png';
$img->disposition = Zend_Mime::DISPOSITION_INLINE;
$img->encoding    = Zend_Mime::ENCODING_BASE64;
$img->id          = 'logo_cid'; // HTML 中用 
// HTML 內容: Logo

$mail->send();

四、批次發送與效能優化

  • 複用 Transport:Zend_Mail::setDefaultTransport($transport) 設定一次,後續 new Zend_Mail() 自動使用。
  • 單次連線發送多封:SMTP 連線建立較慢,可手動控制:
    $transport = new Zend_Mail_Transport_Smtp('smtp.gmail.com', $config);
    $transport->connect();
    foreach ($users as $user) {
        $mail = new Zend_Mail('UTF-8');
        // ... 設定內容 ...
        $mail->send($transport); // 傳入 transport,不關閉連線
    }
    $transport->disconnect();
  • 非同步發送:結合隊列 (如前文 Laravel 隊列) 將郵件 Job 推入隊列,Worker 背景發送。

五、常見問題排查

結語

Zend_Mail 雖屬 ZF1 時代產物,但其 MIME 組裝、SMTP 傳輸、編碼處理邏輯仍具參考價值。現代專案建議改用 symfony/mailer、phpmailer/phpmailer 或 Laravel 內建 Mail Facade,底層同樣遵循 RFC 2047/5322 標準。理解「主題必須 Base64 編碼」、「HTML/文字替代部份」、「SMTP 連線複用」三大原則,無論換何框架都能快速上手。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
現象原因解決
主題亂碼未 RFC 2047 編碼setSubject('=?UTF-8?B?'.base64_encode($subject).'?=')
Gmail 認證失敗用登入密碼/未開兩步驟生成應用程式密碼、確認 ssl/tls port
附件名稱亂碼檔名未編碼$at->filename = '=?UTF-8?B?'.base64_encode($filename).'?='
大量發送被退信觸發反垃圾郵件機制配置 SPF/DKIM/DMARC、控制頻率、使用專業郵件服務