最好的邮件编码解码类

编码

<?
class mime_decode {

    var $content     = Array();
    function mime_encode_headers($string) {
        if($string == "") return;
        if(!eregi("^([[:print:]]*)$",$string))
            $string = "=?ISO-8859-1?Q?".str_replace("+","_",str_replace("%","=",urlencode($string)))."?=";
        return $string;
    }

    function decode_mime_string($string) {
        if(($pos = strpos($string,"=?")) === false) return $string;
        while(!($pos === false)) {
            $newresult .= substr($string,0,$pos);
            $string = substr($string,$pos+2,strlen($string));
            $intpos = strpos($string,"?");
            $charset = substr($string,0,$intpos);
            $enctype = strtolower(substr($string,$intpos+1,1));
            $string = substr($string,$intpos+3,strlen($string));
            $endpos = strpos($string,"?=");
            $mystring = substr($string,0,$endpos);
            $string = substr($string,$endpos+2,strlen($string));
            if($enctype == "q") {
                $mystring = str_replace("_"," ",$mystring);
                $mystring = $this->decode_qp($mystring);
            } else if ($enctype == "b")
                $mystring = base64_decode($mystring);
            $newresult .= $mystring;
            $pos = strpos($string,"=?");
        }
        return $newresult.$string;
    }

    function decode_header($header) {
        $headers = explode("\r\n",$header);
        $decodedheaders = Array();
        for($i=0;$i<count($headers);$i++) {
            $thisheader = $headers[$i];
            if(strpos($thisheader,": ") === false) {
                $decodedheaders[$lasthead] .= " $thisheader";
            } else {
                $dbpoint = strpos($thisheader,": ");
                $headname = strtolower(substr($thisheader,0,$dbpoint));
                $headvalue = trim(substr($thisheader,$dbpoint+1));
                if($decodedheaders[$headname] != "") $decodedheaders[$headname] .= "; $headvalue";
                else $decodedheaders[$headname] = $headvalue;
                $lasthead = $headname;
            }
        }
        return $decodedheaders;
    }

    function fetch_structure($email) {
        $ARemail = Array();
        $separador = "\r\n\r\n";
        $header = trim(substr($email,0,strpos($email,$separador)));
        $bodypos = strlen($header)+strlen($separador);
        $body = substr($email,$bodypos,strlen($email)-$bodypos);
        $ARemail["header"] = $header; $ARemail["body"] = $body;
        return $ARemail;
    }

    function get_names($strmail) {
        $ARfrom = Array();
        $strmail = stripslashes(ereg_replace("\t","",ereg_replace("\n","",ereg_replace("\r","",$strmail))));
        if(trim($strmail) == "") return $ARfrom;

        $armail = Array();
        $counter = 0;  $inthechar = 0;
        $chartosplit = ",;"; $protectchar = "\""; $temp = "";
        $lt = "<"; $gt = ">";
        $closed = 1;

        for($i=0;$i<strlen($strmail);$i++) {
            $thischar = $strmail[$i];
            if($thischar == $lt && $closed) $closed = 0;
            if($thischar == $gt && !$closed) $closed = 1;
            if($thischar == $protectchar) $inthechar = ($inthechar)?0:1;
            if(!(strpos($chartosplit,$thischar) === false) && !$inthechar && $closed) {
                $armail[] = $temp; $temp = "";
            } else
                $temp .= $thischar;
        }

        if(trim($temp) != "")
            $armail[] = trim($temp);

        for($i=0;$i<count($armail);$i++) {
            $thisPart = trim(eregi_replace("^\"(.*)\"$", "\\1", trim($armail[$i])));
            if($thisPart != "") {
                if (eregi("(.*)<(.*)>", $thisPart, $regs)) {
                    $email = trim($regs[2]);
                    $name = trim($regs[1]);
                } else {
                    if (eregi("([-a-z0-9_$+.]+@[-a-z0-9_.]+[-a-z0-9_]+)((.*))", $thisPart, $regs)) {
                        $email = $regs[1];
                        $name = $regs[2];
                    } else
                        $email = $thisPart;
                }
                $email = eregi_replace("^\<(.*)\>$", "\\1", $email);
                $name = eregi_replace("^\"(.*)\"$", "\\1", trim($name));
                $name = eregi_replace("^\((.*)\)$", "\\1", $name);
                if ($name == "") $name = $email;
                if ($email == "") $email = $name;
                $ARfrom[$i]["name"] = $this->decode_mime_string($name);
                $ARfrom[$i]["mail"] = $email;
                unset($name);unset($email);
            }
        }
        return $ARfrom;
    }

    function build_alternative_body($ctype,$body) {
        global $mime_show_html;
        $boundary = $this->get_boundary($ctype);
        $part = $this->split_parts($boundary,$body);
        $thispart = ($mime_show_html)?$part[1]:$part[0];
        $email = $this->fetch_structure($thispart);
        $header = $email["header"];
        $body = $email["body"];
        $headers = $this->decode_header($header);
        $body = $this->compile_body($body,$headers["content-transfer-encoding"]);
        return $body;
    }

    function build_related_body($ctype,$body) {
        global $mime_show_html,$sid,$lid,$ix,$folder;
        $Rtype = trim(substr($ctype,strpos($ctype,"type=")+5,strlen($ctype)));

        if(strpos($Rtype,";") != 0)
            $Rtype = substr($Rtype,0,strpos($Rtype,";"));
        if(substr($Rtype,0,1) == "\"" && substr($Rtype,-1) == "\"")
            $Rtype = substr($Rtype,1,strlen($Rtype)-2);

        $boundary = $this->get_boundary($ctype);
        $part = $this->split_parts($boundary,$body);

        for($i=0;$i<count($part);$i++) {
            $email = $this->fetch_structure($part[$i]);
            $header = $email["header"];
            $body = $email["body"];
            $headers = $this->decode_header($header);
            $ctype = $headers["content-type"];
            $cid = $headers["content-id"];
            $Actype = split(";",$headers["content-type"]);
            $types = split("/",$Actype[0]); $rctype = strtolower($Actype[0]);
            if($rctype == "multipart/alternative")
                $msgbody = $this->build_alternative_body($ctype,$body);
            elseif($rctype == "text/plain" && strpos($headers["content-disposition"],"name") === false) {
                $body = $this->compile_body($body,$headers["content-transfer-encoding"]);
                $msgbody = $this->build_text_body($body);
            } elseif($rctype == "text/html" && strpos($headers["content-disposition"],"name") === false) {
                $body = $this->compile_body($body,$headers["content-transfer-encoding"]);
                if(!$mime_show_html) $body = $this->build_text_body(strip_tags($body));
                $msgbody = $body;
            } else {
                $thisattach = $this->build_attach($header,$body,$boundary,$i);
                if($cid != "") {
                    if(substr($cid,0,1) == "<" && substr($cid,-1) == ">")
                        $cid = substr($cid,1,strlen($cid)-2);
                    $cid = "cid:$cid";
                    $thisfile = "download.php?sid=$sid&lid=$lid&folder=".urlencode($folder)."&ix=".$ix."&bound=".base64_encode($thisattach["boundary"])."∂=".$thisattach["part"]."&filename=".urlencode($thisattach["name"]);
                    $msgbody = str_replace($cid,$thisfile,$msgbody);
                }
            }
        }
        return $msgbody;
    }

    function linesize($message="", $length=70) {
        $line = explode("\r\n",$message);
        unset($message);
        for ($i=0 ;$i < count($line); $i++) {
            $line_part = explode(" ",trim($line[$i]));
            unset($buf);
            for ($e = 0; $e<count($line_part); $e++) {
                $buf_o = $buf;
                if ($e == 0) $buf .= $line_part[$e];
                else $buf .= " ".$line_part[$e];
                if (strlen($buf) > $length and $buf_o != "") {
                    $message .= "$buf_o\r\n";
                    $buf = $line_part[$e];
                }
            }
            $message .= "$buf\r\n";
        }
        return($message);
    }
function build_text_body($body) {
        return "\n<pre>".$this->make_link_clickable($this->linesize(htmlspecialchars($body),85))."</pre>\n";
    }

    function decode_qp($text) {
        $text = quoted_printable_decode($text);
        /*
        $text = str_replace("\r","",$text);
        $text = ereg_replace("=\n", "", $text);
        $text = str_replace("\n","\r\n",$text);
        */
        $text = ereg_replace("=\r", "\r", $text);
        return $text;
    }

    function make_link_clickable($text){
        $text = eregi_replace("([[:alnum:]]+)://([^[:space:]]*)([[:alnum:]#?/&=])",
            "<a class=\"autolink\" href=\"\\1://\\2\\3\" target=\"_new\">\\1://\\2\\3</a>", $text);
        $text = eregi_replace("([0-9a-z]([-_.]?[0-9a-z])*@[0-9a-z]([-.]?[0-9a-z])*\\.[a-z]{2,3})","<a class=\"autolink\"  href=\"newmsg.php?mailto=\\1&nameto=\\1\">\\1</a>", $text);
        return $text;
    }

    function process_message($header,$body) {
        global $mime_show_html;
        $mail_info = $this->get_mail_info($header);

        $ctype = $mail_info["content-type"];
        $ctenc = $mail_info["content-transfer-encoding"];

        if($ctype == "") $ctype = "text/plain";

        $type = $ctype;

        $ctype = split(";",$ctype);
        $types = split("/",$ctype[0]);

        $maintype = strtolower($types[0]);
        $subtype = strtolower($types[1]);

        switch($maintype) {
        case "text":
            $body = $this->compile_body($body,$ctenc);
            switch($subtype) {
            case "html":
                if(!$mime_show_html)
                    $body = $this->build_text_body(strip_tags($body));
                $msgbody = $body;
                break;
            default:
                $msgbody = $this->build_text_body($body);
                break;
            }
            break;
        case "multipart":
            switch($subtype) {
            case "mixed":
                $boundary = $this->get_boundary($type);
                $part = $this->split_parts($boundary,$body);

                for($i=0;$i<count($part);$i++) {
                    $thispart = trim($part[$i]);

                    if($thispart != "") {
                        $email = $this->fetch_structure($thispart);
    
                        $header = $email["header"];
                        $body = $email["body"];
                        $headers = $this->decode_header($header);
                        $ctype = $headers["content-type"];
    
                        $Actype = split(";",$headers["content-type"]);
                        $types = split("/",$Actype[0]); $rctype = strtolower($Actype[0]);
    
                        if($rctype == "multipart/alternative")
                            $msgbody = $this->build_alternative_body($ctype,$body);
                        elseif($rctype == "text/plain" && strpos($headers["content-disposition"],"name") === false) {
                            $msgbody = $this->build_text_body($this->compile_body($body,$headers["content-transfer-encoding"]));
                        } elseif($rctype == "text/html" && strpos($headers["content-disposition"],"name") === false) {
                            $body = $this->compile_body($body,$headers["content-transfer-encoding"]);
                            if(!$mime_show_html)
                                $body = $this->build_text_body(strip_tags($body));
                            $msgbody = $body;
                        } elseif($rctype == "multipart/related" && strpos($headers["content-disposition"],"name") === false) {
                            $msgbody = $this->build_related_body($ctype,$body);
                        } else {
                            $thisattach = $this->build_attach($header,$body,$boundary,$i);
                        }
                    }
                }
                break;
            case "alternative":
                $msgbody = $this->build_alternative_body($ctype[1],$body);
                break;
            case "related":
                $msgbody = $this->build_related_body($type,$body);
                break;
            default:
                $thisattach = $this->build_attach($header,$body,"",0);
            }
            break;
        default:
            $thisattach = $this->build_attach($header,$body,"",0);
        }
        return $msgbody;
    }

    function build_attach($header,$body,$boundary,$part) {
        global $mail,$temporary_directory,$userfolder;

        $headers = $this->decode_header($header);
        $cdisp = $headers["content-disposition"];
        $ctype = $headers["content-type"]; $ctype2 = explode(";",$ctype); $ctype2 = $ctype2[0];
        
        $Atype = split("/",$ctype);
        $Acdisp = split(";",$cdisp);

        $tenc = $headers["content-transfer-encoding"];

        if($temp) $dir_to_save = $userfolder; //"temporary_files/";

        if($Atype[0] == "message") {
            $divpos = strpos($body,"\n\r");
            $attachheader = substr($body,0,$divpos);
            $attachheaders = $this->decode_header($attachheader);
            $filename = $this->decode_mime_string($attachheaders["subject"]);
            if($filename == "")
                $filename = uniqid("");
            $filename = substr(ereg_replace("[^A-Za-z0-9]","_",$filename),0,20).".eml";
        } else {
            $fname = $Acdisp[1];
            $filename = substr($fname,strpos($fname,"filename=")+9,strlen($fname));
            if($filename == "")
                $filename = substr($ctype,strpos($ctype,"name=")+5,strlen($ctype));
            if(substr($filename,0,1) == "\"" && substr($filename,-1) == "\"")
                $filename = substr($filename,1,strlen($filename)-2);
            $filename = $this->decode_mime_string($filename);
        }

        if($Atype[0] != "message")
            $body = $this->compile_body($body,$tenc);

        $indice = count($this->content["attachments"]);
        $this->content["attachments"][$indice]["name"] = $filename;
        $this->content["attachments"][$indice]["size"] = strlen($body);
        $this->content["attachments"][$indice]["temp"] = $temp;
        $this->content["attachments"][$indice]["content-type"] = $ctype2; //$Atype[0];
        $this->content["attachments"][$indice]["content-disposition"] = $Acdisp[0];
        $this->content["attachments"][$indice]["boundary"] = $boundary;
        $this->content["attachments"][$indice]["part"] = $part;
        return $this->content["attachments"][$indice];
    }

    function compile_body($body,$enctype) {
        $enctype = explode(" ",$enctype); $enctype = $enctype[0];
        if(strtolower($enctype) == "base64")
            $body = base64_decode($body);
        elseif(strtolower($enctype) == "quoted-printable")
            $body = $this->decode_qp($body);
        return $body;

    }

    function download_attach($header,$body,$down=1) {
        $headers = $this->decode_header($header);

        $cdisp = $headers["content-disposition"];
        $ctype = $headers["content-type"];

        $type = split(";",$ctype); $type = $type[0];
        $Atype = split("/",$ctype);
        $Acdisp = split(";",$cdisp);
        $tenc = strtolower($headers["content-transfer-encoding"]);

        if($Atype[0] == "message") {
            $divpos = strpos($body,"\n\r");
            $attachheader = substr($body,0,$divpos);
            $attachheaders = $this->decode_header($attachheader);
            $filename = $this->decode_mime_string($attachheaders["subject"]);
            if($filename == "")
                $filename = uniqid("");
            $filename = substr(ereg_replace("[^A-Za-z0-9]","_",$filename),0,20);
            $filename .= ".eml";
        } else {
            $fname = $Acdisp[1];
            $filename = substr($fname,strpos(strtolower($fname),"filename=")+9,strlen($fname));
            if($filename == "")
                $filename = substr($ctype,strpos(strtolower($ctype),"name=")+5,strlen($ctype));
            if(substr($filename,0,1) == "\"" && substr($filename,-1) == "\"")
                $filename = substr($filename,1,strlen($filename)-2);
            $filename = $this->decode_mime_string($filename);
        }

        if($Atype[0] != "message")
            $body = $this->compile_body($body,$tenc);

        $content_type = ($down)?"application/octet-stream":strtolower($type);
        $filesize = strlen($body);

        header("Content-Type: $content_type; name=\"$filename\"\r\n"
        ."Content-Length: $filesize\r\n");
        $cdisp = ($down)?"attachment":"inline";
        header("Content-Disposition: $cdisp; filename=\"$filename\"\r\n");
        echo($body);
    }

    function get_mail_info($header) {
        $myarray = Array();
        $headers = $this->decode_header($header);

        /*
        echo("<pre>");
        print_r($headers);
        echo("</pre>");
        */

        $message_id = $headers["message-id"];

        if(substr($message_id,0,1) == "<" && substr($message_id,-1) == ">")
            $message_id = substr($message_id,1,strlen($message_id)-2);

        $myarray["content-type"] = $headers["content-type"];
        $myarray["content-transfer-encoding"] = str_replace("GM","-",$headers["content-transfer-encoding"]);
        $myarray["message-id"] = $message_id;

        $received = $headers["received"];

        if($received != "") {
            $received = explode(";",$received);
            $mydate = $received[1];
        } else
            $mydate = $headers["date"];

        $myarray["date"] = $this->build_mime_date($mydate);
        $myarray["subject"] = $this->decode_mime_string($headers["subject"]);
        $myarray["from"] = $this->get_names($headers["from"]);
        $myarray["to"] = $this->get_names($headers["to"]);
        $myarray["cc"] = $this->get_names($headers["cc"]);
        $myarray["status"] = $headers["status"];
        $myarray["read"] = ($headers["status"] == "N")?0:1;

        return $myarray;

    }

    function build_mime_date($mydate) {

        $mydate = explode(",",$mydate);
        $mydate = trim($mydate[count($mydate)-1]);
        $parts = explode(" ",$mydate);
        if(count($parts) < 4) { return time(); }
        $day = $parts[0];

        switch(strtolower($parts[1])) {
            case "jan": $mon = 1; break;
            case "feb":    $mon = 2; break;
            case "mar":    $mon = 3; break;
            case "apr":    $mon = 4; break;
            case "may":    $mon = 5; break;
            case "jun": $mon = 6; break;
            case "jul": $mon = 7; break;
            case "aug": $mon = 8; break;
            case "sep": $mon = 9; break;
            case "oct": $mon = 10; break;
            case "nov": $mon = 11; break;
            case "dec": $mon = 12; break;
        }
        
        $year = $parts[2];
        $ahours = explode(":",$parts[3]);
        $hour = $ahours[0]; $min = $ahours[1]; $sec = $ahours[2];

        return mktime ($hour, $min, $sec, $mon, $day, $year);

    }

    function initialize($email) {
        $email = $this->fetch_structure($email);
        $body = $email["body"];
        $header = $email["header"];
        $mail_info = $this->get_mail_info($header);

        $this->content["headers"] = $header;
        $this->content["date"] = $mail_info["date"];
        $this->content["subject"] = $mail_info["subject"];
        $this->content["message-id"] = $mail_info["message-id"];
        $this->content["from"] = $mail_info["from"];
        $this->content["to"] = $mail_info["to"];
        $this->content["cc"] = $mail_info["cc"];
        $this->content["body"] = $this->process_message($header,$body);
        $this->content["read"] = $mail_info["read"];
    }

    function split_parts($boundary,$body) {
        $startpos = strpos($body,"$boundary")+strlen("$boundary")+2;
        $lenbody = strpos($body,"\r\n$boundary--") - $startpos;
        $body = substr($body,$startpos,$lenbody);
        return split($boundary."\r\n",$body);
    }

    function get_boundary($ctype){
        $boundary = trim(substr($ctype,strpos(strtolower($ctype),"boundary=")+9,strlen($ctype)));
        $boundary = split(";",$boundary);$boundary = $boundary[0];

        if(substr($boundary,0,1) == "\"" && substr($boundary,-1) == "\"")
            $boundary = substr($boundary,1,strlen($boundary)-2);
        $boundary = "--".$boundary;
        return $boundary;
    }

    function set_as($email,$type=1) {
        $status = ($type)?"Y":"N";
        $tempmail = $this->fetch_structure($email);
        $thisheader = $tempmail["header"];
        $mail_info = $this->get_mail_info($thisheader);
        $decoded_headers = $this->decode_header($thisheader);

        while(list($key,$val) = each($decoded_headers))
            if (eregi("status",$key)) {
                $newmail .= ucfirst($key).": $status\r\n"; $headerok = 1;
            } else $newmail .= ucfirst($key).": ".trim($val)."\r\n";
        if(!$headerok) $newmail .= "Status: $status\r\n";
        $newmail = trim($newmail)."\r\n\r\n".trim($tempmail["body"]);
        return $newmail;
    }

}
?>

时间: 2024-11-10 01:08:08

最好的邮件编码解码类的相关文章

最好的邮件编码解码类,再没有比这个好的了!贴不下了(1)

<?class mime_decode {    var $content     = Array();    function mime_encode_headers($string) {        if($string == "") return;        if(!eregi("^([[:print:]]*)$",$string))       $string = "=?ISO-8859-1?Q?".str_replace(&

python模块之email: 电子邮件编码解码 (一、解码邮件)

python模块之email: 电子邮件编码解码 (一.解码邮件) python自带的email模块是个很有意思的东西,它可以对邮件编码解码,用来处理邮件非常好用. 处理邮件是一个很细致的工作,尤其是解码邮件,因为它的格式变化太多了,下面先看看一个邮件的源文件: Received: from 192.168.208.56 ( 192.168.208.56 [192.168.208.56] ) by ajax-webmail-wmsvr37 (Coremail) ; Thu, 12 Apr 200

一个邮件解码类

<?php       /**这个是改自pear中的解码类,增加了多种解码方式,修正了源码的系列bug.将解出的邮件分正文和附件存储,提高了解码效率.     * Mime decode class     *     * this class used at undecode Mime Files     * useage:     *     *    $message=GetMessage($filename,$read_type,$read_size);         *    $st

用PHP实现POP3邮件的解码(三)

实现 MIME 解码的类 该类实现解码的方法是 decode($head=null,$body=null,$content_num=-1),为了处理上的方便,要求输入的是两个字符数组,在我们的上篇中,所用到的POP类所收取得到的就是两个这样的数组,一个是邮件头内容,一个是邮件的正文内容.限于篇幅,不对其做详细的说明,其实现思想跟本文上篇中所介绍的POP类类似.请参考其中的注释. 该类中用到了大量的正则表达式的操作,对此不熟悉的读者,请参考正则表达式的有关资料. class decode_mail

用PHP实现POP3邮件的解码(二)

MIME 编码方式简介 Subject: =?gb2312?B?xOO6w6Oh?= 这里是邮件的主题,可是因为编码了,我们看不出是什么内容,其原来的文本是:"你好!"我们先看看 MIME 编码的两种方法. 对邮件进行编码最初的原因是因为 Internet 上的很多网关不能正确传输8 bit 内码的字符,比如汉字等.编码的原理就是把 8 bit 的内容转换成 7 bit 的形式以能正确传输,在接收方收到之后,再将其还原成 8 bit 的内容. MIME 是"多用途网际邮件扩充

用PHP实现POP3邮件的解码(一)

初步认识邮件的源文件 本文简要说明了通过POP3协议收取邮件.MIME邮件的解码的原理:针对收取和MIME解码,提供了两个实用的PHP类,并提供了使用的样例.分为邮件收取.MIME解码两个部分.我们已经向您介绍过了邮件的收取,现在让我们来为您介绍本文的解码部. 在上一篇里,我们已经完成了一个用PHP通过POP3收取邮件的实例,可是在使用这个类的时候,相信你已经看到了,很多的邮件收下来是一堆乱码,自己根本看不懂!是的.现在的邮件大部分都已经经过了编码,需要一个解码的过程才能变成我们习惯的文字.图片

用 PHP 实现 POP3 邮件的解码(1)

初步认识邮件的源文件 本文简要说明了通过POP3协议收取邮件.MIME邮件的解码的原理:针对收取和MIME解码,提供了两个实用的PHP类,并提供了使用的样例.分为邮件收取.MIME解码两个部分.我们已经向您介绍过了邮件的收取,现在让我们来为您介绍本文的解码部. 在上一篇里,我们已经完成了一个用PHP通过POP3收取邮件的实例,可是在使用这个类的时候,相信你已经看到了,很多的邮件收下来是一堆乱码,自己根本看不懂!是的.现在的邮件大部分都已经经过了编码,需要一个解码的过程才能变成我们习惯的文字.图片

MIME和BASE64编码/解码程序代码

首先我要在这里向各位纠正我犯在一个错误:Base64 只是MIME的一种编码方案,我原来所说的 MIME 其实是MIME的另一种编码方案 -- Quoted-Printable ,所以我对本文作了一些修正,并对由此而给大家带来的误导表示歉意. May.6-01 最近在研究 POP3 时碰到一个问题,即其中的中文都是经过 MIME 编码了的,如 MS Outlook Express 是用 Base64 ,而 FoxMail 则用的是QP ,本来想找几个现成的编码/解码的代码,结果只在 UDDF 中

java中文乱码解决之道(五)—–java是如何编码解码的

编码&解码 1:I/O操作 2:内存 3:数据库 4:javaWeb 下面主要介绍前面两种场景,数据库部分只要设置正确编码格式就不会有什么问题,javaWeb场景过多需要了解URL.get.POST的编码,servlet的解码,所以javaWeb场景下节LZ介绍. I/O操作 在前面LZ就提过乱码问题无非就是转码过程中编码格式的不统一产生的,比如编码时采用UTF-8,解码采用GBK,但最根本的原因是字符到字节或者字节到字符的转换出问题了,而这中情况的转换最主要的场景就是I/O操作的时候.当然I/