EML 是標準郵件格式(RFC 5322),本文提供完整 PHP 類別實作,支援多部分郵件、Base64/Quoted-Printable 編碼、多種字元集(UTF-8/GBK/GB2312)自動轉碼、附件儲存至伺服器。
$eml_file = './yjdata/' . $filename;
$content = file_get_contents($eml_file);
if (!$content) die('File not found');
// 主旨
preg_match('/Subject: (.*?)\s/ims', $content, $m);
$subject = decode_mime($m[1]);
// 寄件人
preg_match('/From: .*?<(.*?)>/ims', $content, $m);
$from = $m[1];
// 收件人(可能多個)
preg_match_all('/<(.*?)>/ims', $to_header, $m);
$to = $m[1];
// 取得 boundary
preg_match('/Content-Type: multipart\/alternative;.*?boundary=(.*?)\s/ims', $content, $m);
$boundary = '--' . $m[1];
$parts = explode($boundary, $content);
foreach ($parts as $part) {
// 解析每個 part 的 Content-Type、charset、encoding
preg_match('/Content-Type: ([^;]*);.*?charset=(.*?)\s+Content-Transfer-Encoding: (.*?)\s/ims', $part, $m);
// 依 encoding 解碼:base64_decode / quoted_printable_decode
// 依 charset 轉 UTF-8:mb_convert_encoding($body, 'UTF-8', $charset)
// 判斷 text/html 優先作為正文
}
preg_match('/Content-Type: multipart\/mixed;.*?boundary=(.*?)\s/ims', $content, $m);
$boundary = '--' . $m[1];
$parts = explode($boundary, $content);
foreach ($parts as $part) {
preg_match('/Content-Type: ([^;]*);.*?name=(.*?)\s+Content-Transfer-Encoding: (.*?)\s+Content-Disposition: attachment;.*?filename=(.*?)\s/ims', $part, $m);
// 解碼附件內容
// 取得副檔名、生成唯一檔名
// mkdirs() 遞迴建立目錄
// flock() 檔案鎖定寫入
}
function decode_mime($str) {
// 處理 =?charset?encoding?data?= 格式
preg_match('/=\?([^?]+)\?([BQ])\?(.*?)\?=/ims', $str, $m);
if ($m) {
$data = ($m[2] === 'B') ? base64_decode($m[3]) : quoted_printable_decode($m[3]);
return mb_convert_encoding($data, 'UTF-8', $m[1]);
}
return $str;
}
class EmlParser {
public function parse($eml_path) { /* 返回結構化陣列 */ }
private function parseHeaders($content) { /* ... */ }
private function parseBody($content) { /* ... */ }
private function parseAttachments($content) { /* ... */ }
private function decodePart($part) { /* ... */ }
private function saveAttachment($data, $filename) { /* ... */ }
}
mailparse 擴展或 PHP-Mime-Parser 等成熟庫mb_detect_encoding() 或 Uchardet本實作展示 EML 解析核心邏輯,適合學習 MIME 結構。生產環境建議使用成熟庫(如 php-mime-mail-parser)確保穩健性與安全性。