愤怒的大鸟 发表于 2015-2-4 00:09:40

PHP教程之最好的邮件编码解码类

没有人会喜欢和见异思迁的人交朋友,因为这种人太不安分,太不可靠,因此,你必须要强迫自己完成自己的目标,哪怕可能会很难受,也得坚持,毅力就是这么锻炼出来的。编码   <?
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);
                  $name = trim($regs);
                } else {
                  if (eregi("([-a-z0-9_$+.]+@[-a-z0-9_.]+[-a-z0-9_]+)((.*))", $thisPart, $regs)) {
                        $email = $regs;
                        $name = $regs;
                  } 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:$part;
      $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); $rctype = strtolower($Actype);
            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"])."&part=".$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("(([-_.]?)*@([-.]?)*\\.{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);

      $maintype = strtolower($types);
      $subtype = strtolower($types);

      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); $rctype = strtolower($Actype);
   
                        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,$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;
      
      $Atype = split("/",$ctype);
      $Acdisp = split(";",$cdisp);

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

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

      if($Atype == "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;
            $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 != "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;
      $this->content["attachments"][$indice]["content-disposition"] = $Acdisp;
      $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;
      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;
      $Atype = split("/",$ctype);
      $Acdisp = split(";",$cdisp);
      $tenc = strtolower($headers["content-transfer-encoding"]);

      if($Atype == "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;
            $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 != "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;
      } 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);
      $parts = explode(" ",$mydate);
      if(count($parts) < 4) { return time(); }
      $day = $parts;

      switch(strtolower($parts)) {
            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;
      $ahours = explode(":",$parts);
      $hour = $ahours; $min = $ahours; $sec = $ahours;

      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;

      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;
    }

}
?>
也许您在学习PHP的时候只想尽快的开发一个网站,也就会想我做网站,干嘛要学什么网页这些小儿科?不难看出,眼高手低的新手不在少数,这种思想无疑于建造空中楼阁,你不建地基,何来的房顶呢?

乐观 发表于 2015-2-4 09:34:56

本人接触php时间不长,算是phper中的小菜鸟一只吧。由于刚开始学的时候没有名师指,碰过不少疙瘩,呗很多小问题卡过很久,白白浪费不少宝贵的时间,在次分享一些子的学习的心得。

海妖 发表于 2015-2-9 02:19:09

找到的的资料很多都是在论坛里的,需要注册,所以我一般没到一个论坛都注册一个id,所有的id都注册成一样的,这样下次再进来的时候就不用重复注册啦。当然有些论坛的某些资料是需要的付费的。

小女巫 发表于 2015-2-26 18:27:09

其实没啥难的,多练习,练习写程序,真正的实践比看100遍都有用。不过要熟悉引擎

飘飘悠悠 发表于 2015-3-11 12:22:56

当然这种网站的会员费就几十块钱。

冷月葬花魂 发表于 2015-3-18 10:38:11

学好程序语言,多些才是王道,写两个小时代码的作用绝对超过看一天书,这个我是深有体会(顺便还能练打字速度)。

若相依 发表于 2015-3-21 17:16:17

说php的话,首先得提一下数组,开始的时候我是最烦数组的,总是被弄的晕头转向,不过后来呢,我觉得数组里php里最强大的存储方法,所以建议新手们要学好数组。

深爱那片海 发表于 2015-4-7 13:56:11

在我安装pear包的时候老是提示,缺少某某文件,才发现 那群extension 的排列是应该有一点的顺序,而我安装的版本的排序不是正常的排序。没办法我只好把那群冒号加了上去,只留下我需要使用的扩展。

分手快乐 发表于 2015-4-11 03:09:59

说php的话,首先得提一下数组,开始的时候我是最烦数组的,总是被弄的晕头转向,不过后来呢,我觉得数组里php里最强大的存储方法,所以建议新手们要学好数组。

老尸 发表于 2015-4-12 15:19:36

基础有没有对学习php没有太大区别,关键是兴趣。

爱飞 发表于 2015-4-26 17:41:05

实践是检验自己会不会的真理。

小妖女 发表于 2015-4-29 12:06:10

如果你可以写完像留言板这样的程序,那么你可以去一些别人的代码了,

愤怒的大鸟 发表于 2015-4-30 07:58:44

写js我最烦的就是 ie 和 firefox下同样的代码 结果显示的结果千差万别,还是就是最好不要用遨游去调试,因为有时候遨游是禁用js的,有可能代码是争取结果被遨游折腾的认为是代码写错。

山那边是海 发表于 2015-5-1 02:11:34

开发工具也会慢慢的更专业,每个公司的可能不一样,但是zend studio是个大伙都会用的。

透明 发表于 2015-6-16 12:39:06

遇到出错的时候,我经常把错误信息直接复制到 google的搜索栏,一般情况都是能搜到结果的,不过有时候会搜出来一大片英文的出来,这时候就得过滤一下,吧中文的弄出来,挨着式方法。

莫相离 发表于 2015-6-18 21:02:15

对于懒惰的朋友,我推荐php的集成环境xampp或者是wamp。这两个软件安装方便,使用简单。但是我还是强烈建议自己动手搭建开发环境。

蒙在股里 发表于 2015-6-19 11:47:36

爱上php,他也会爱上你。

活着的死人 发表于 2015-6-20 02:40:49

微软最近出的新字体“微软雅黑”,虽然是挺漂亮的,不过firefox支持的不是很好,所以能少用还是少用的好。

金色的骷髅 发表于 2015-6-21 05:53:24

建议加几个专业的phper的群,当然啦需要说话的人多,一处一点问题能有人回答你的,当然啦要让人回答你的问题,平时就得躲在里面聊天,大家混熟啦,愿意回答你问题的人自然就多啦。

小魔女 发表于 2015-6-27 05:00:11

装在C盘下面可以利用windows的ghost功能可以还原回来(顺便当做是重转啦),当然啦我的编译目录要放在别的盘下,不然自己的劳动成果就悲剧啦。
页: [1]
查看完整版本: PHP教程之最好的邮件编码解码类