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

PHP 解析 EML 郵件文件完整實作:提取正文、附件與編碼處理

     編輯:PHP 相關知識

PHP EML 郵件解析器:從原始郵件提取 HTML 正文與附件

EML 是標準郵件格式(RFC 5322),本文提供完整 PHP 類別實作,支援多部分郵件、Base64/Quoted-Printable 編碼、多種字元集(UTF-8/GBK/GB2312)自動轉碼、附件儲存至伺服器。

核心功能

  • 解析郵件標頭:主旨、寄件人、收件人
  • 提取 HTML/純文字正文,自動處理 multipart/alternative
  • 解析並儲存附件,支援 multipart/mixed
  • 智慧編碼偵測與轉換(Base64、QP、字元集)
  • 建立目錄結構按日期儲存附件

關鍵程式碼片段

1. 讀取 EML 文件

$eml_file = './yjdata/' . $filename;
$content = file_get_contents($eml_file);
if (!$content) die('File not found');

2. 正則提取標頭資訊

// 主旨
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];

3. 解析 Multipart 正文

// 取得 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 優先作為正文
}

4. 附件處理與儲存

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() 檔案鎖定寫入
}

5. MIME 編碼解碼輔助函數

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) { /* ... */ }
}

注意事項與改進方向

  • 正則解析 MIME 結構較脆弱,建議改用 mailparse 擴展或 PHP-Mime-Parser 等成熟庫
  • 大附件需串流處理,避免記憶體耗盡
  • 字元集偵測可整合 mb_detect_encoding() 或 Uchardet
  • 郵件可能包含簽名、加密,需額外處理

總結

本實作展示 EML 解析核心邏輯,適合學習 MIME 結構。生產環境建議使用成熟庫(如 php-mime-mail-parser)確保穩健性與安全性。

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