八月 06
加入書籤 Google Bookmarks HemiDemi Del.icio.us MyShare Baidu Yahoo! My Web Digg technorati furl YouPush udn共享書籤 Fiigo網路分享書籤

因為 php 上面提供的 mailparse 模組實在是爛到一個不行,看不下去只有自己寫,這就是網路。有興趣的人請自行取用~~註明出處即可。

/* 作者:丁昶文
    電郵:charlie@ics.com.tw
*/

class        mail_parser    {
    function    mail_parser()    {
        $this->tree        =    array() ;
        $this->header    =    array() ;
        $this->body        =    array() ;
        $this->counter    =    0 ;
    }
    function    explode($message,$pid=0) {
        if    ($pid == 0)    {
            $segment        =    preg_split("/\r*\n\r*\n/",$message,2) ;
            $this->header[0]=    iconv_mime_decode_headers(trim($segment[0]),2,SCRIPT_CHARSET) ;
            $this->body[0]    =    trim($segment[1]) ;
        }
        if    (preg_match("/boundary=\"([^\"]+)\"/i",$message,$m))    {
            $boundary    =    $m[1] ;
            $tail_off    =    array_shift(explode("--{$boundary}--",$message)) ;
            $parts        =    explode("--{$boundary}",$tail_off) ;
            array_shift($parts) ;
            if    (!isset($this->tree[$pid]))    $this->tree[$pid]    =    array() ;

            foreach    ($parts as $this_one => $part)    {
                $segment                            =    preg_split("/\r*\n\r*\n/",$part,2) ;
                $this->counter                        +=    1 ;
                $oid                                =    count($this->tree[$pid]) + 1 ;
                $this->tree[$pid][$oid]                =    $this->counter ;
                $this->tree["<-{$this->counter}"]    =    $pid ;
                $this->header[$this->counter]        =    iconv_mime_decode_headers(trim($segment[0]),2,SYSTEM_CHARSET) ;
                $this->body[$this->counter]            =    trim($segment[1]) ;

                $this->explode($part,$this->counter) ;
            }
        }
    }
}
 

用法就是:
$mp = new mail_parser() ;
$mp->explode(MAIL_CONTENT_FROM_EML_FILE) ;
然後它就會幫你把整封信炸開,之後,你可以用二種方式去捉資料。

  1. for ($i = 0 ; $i <= $mp->counter ; $i++) {
        $header = $mp->header[$i] ;
        $body = $mp->body[$i] ;
    }
  2. 也可以用樹狀的方式去捉出信包中各區塊的關係,重點就是從 $mp->tree[0] 開始,然後逐層去撈。找到 index 後,一樣從 $mp->header 和 $mp->body 去捉檔頭和內容。

這個類別基本上只作信包拆解的部份,而且是不管什麼死人骨頭全部拆光光。純粹是為了處理 mailparse 在 body 解析上的無厘頭表現而已。至於打包部份,目前我沒需求,就也沒作囉。不過就是反其道而行就對了。
email 的關鍵就是 boundary 和 mime type 處理好,然後拆拆裝裝而已。

附註:

  1. 類別中用了 SCRIPT_CHARSET 和 SYSTEM_CHARSET 這個定義,是用來將標頭內容轉成指定的字集,別忘了 define (SCRIPT_CHARSET,'***') ; 和 define (SYSTEM_CHARSET,'***') ; 先。
  2. 樹狀結構的存取就自行處理囉。
  3. php 指令 iconv_mime_decode_headers 也有點不盡理想。主要在 header 長度過長被切斷成數行的情況時,重組的結果會有不可預期的空白出現。另外則是部份 mail agent 的設計失當,在 header 中使用特定字集而未加以編碼,造成還原上的錯誤。這部份,可以考慮自行改寫 header 的反解功能來取代它。

 


迴響

  1. wow gold Says:

    zlzly0810 wazly1015
    wow gold
    wow gold
    wow gold
    item4sale
    item4sale
    item4sale
    item4sale
    item4sale
    item4sale
    item4sale
    AoC gold
    AoC gold
    AoC gold
    AoC gold
    AoC gold
    洗涤设备
    洗涤设备
    全自动干洗机
    全自动干洗机
    门禁
    门禁
    擦鞋机
    擦鞋机
    加盟干洗连锁
    加盟干洗连锁
    加盟连锁干洗
    加盟连锁干洗
    开洗衣店
    开洗衣店
    水洗厂
    水洗厂
    门禁系统
    门禁系统
    日本留学费用
    日本留学网
    日本留学申请
    日本留学签证
    日本大学排名
    日本留学中介
    日本留学论坛
    wow gold
    wow gold
    wow gold
    wow gold
    wow gold
    wow gold
    wow gold
    wow gold

發表迴響
 authimage