Zend Framework 1.x 的 Zend_Mail 元件提供統一介面發送純文字、HTML、多部分 MIME 郵件,支援 Sendmail (本機 MTA) 與 SMTP 兩種傳輸方式。本文示範:基本發送、SMTP 認證 (Gmail 範例)、HTML 內容、附件、以及**解決中文主題 Base64 編碼亂碼**的標準做法。
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?= 編碼,否則中文主題在多數郵件客戶端會顯示亂碼。
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();
ssl 參數值:ssl (465 port) 或 tls (587 port)。$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 內容:
$mail->send();
Zend_Mail::setDefaultTransport($transport) 設定一次,後續 new Zend_Mail() 自動使用。$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();
| 現象 | 原因 | 解決 |
|---|---|---|
| 主題亂碼 | 未 RFC 2047 編碼 | setSubject('=?UTF-8?B?'.base64_encode($subject).'?=') |
| Gmail 認證失敗 | 用登入密碼/未開兩步驟 | 生成應用程式密碼、確認 ssl/tls port |
| 附件名稱亂碼 | 檔名未編碼 | $at->filename = '=?UTF-8?B?'.base64_encode($filename).'?=' |
| 大量發送被退信 | 觸發反垃圾郵件機制 | 配置 SPF/DKIM/DMARC、控制頻率、使用專業郵件服務 |