手動構建 multipart/mixed 郵件結構:
<?php
function sendMailWithAttachment($to, $subject, $body, $filePath, $fileName, $from = 'me@example.com') {
$boundary = '==MULTIPART_BOUNDARY_' . md5(microtime()) . '==';
$headers = "From: $from\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: multipart/mixed; boundary=\"$boundary\"\r\n";
$message = "--$boundary\r\n";
$message .= "Content-Type: text/plain; charset=UTF-8\r\n";
$message .= "Content-Transfer-Encoding: base64\r\n\r\n";
$message .= chunk_split(base64_encode($body)) . "\r\n";
if (is_file($filePath)) {
$content = chunk_split(base64_encode(file_get_contents($filePath)));
$message .= "--$boundary\r\n";
$message .= "Content-Type: application/octet-stream; name=\"$fileName\"\r\n";
$message .= "Content-Transfer-Encoding: base64\r\n";
$message .= "Content-Disposition: attachment; filename=\"$fileName\"\r\n\r\n";
$message .= $content . "\r\n";
}
$message .= "--$boundary--\r\n";
return mail($to, '=?UTF-8?B?' . base64_encode($subject) . '?=', $message, $headers);
}
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'vendor/autoload.php';
function sendMailModern($to, $subject, $body, $attachments = [], $from = 'me@example.com', $fromName = '') {
$mail = new PHPMailer(true);
try {
$mail->isSMTP();
$mail->Host = 'smtp.example.com';
$mail->SMTPAuth = true;
$mail->Username = 'user';
$mail->Password = 'pass';
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port = 587;
$mail->setFrom($from, $fromName ?: $from);
$mail->addAddress($to);
$mail->Subject = $subject;
$mail->msgHTML($body);
$mail->AltBody = strip_tags($body);
foreach ($attachments as $att) {
// $att = ['path'=>'/tmp/a.pdf', 'name'=>'report.pdf']
$mail->addAttachment($att['path'], $att['name']);
}
$mail->send();
return true;
} catch (Exception $e) {
error_log("Mailer Error: {$mail->ErrorInfo}");
return false;
}
}
| 維度 | 原生 mail() + MIME | PHPMailer (SMTP) |
|---|---|---|
| 依賴 | 零 (內建) | Composer 套件 |
| 編碼處理 | 手動 base64/quoted-printable | 自動 |
| 附件支援 | 手動組裝 boundary | addAttachment() 一行 |
| HTML 郵件 | 手動構建 multipart/alternative | msgHTML() 自動生成 text 版 |
| SMTP 認證/加密 | 不支援 (需本地 MTA) | 完整支援 TLS/SSL、OAuth2 |
| 錯誤處理/除錯 | 極難 | 詳細異常、SMTP 對話日誌 |
| 發送可靠性 | 低 (依賴本地 sendmail/postfix) | 高 (直連 SMTP 服務商) |
| 效能 (大量發送) | 差 (每封建立連線) | 支援 Keep-Alive、批次發送 |
原生 MIME 組裝適合理解郵件協議結構,但生產系統 **務必** 使用 PHPMailer/Symfony Mailer 等成熟庫搭配專業 SMTP 服務。非同步隊列、模板化、信譽管理是企業級郵件系統的標配三件套。