Decoding of POP3 messages with PHP (III.)

Source: Internet
Author: User
Tags arrays base64 ereg expression header strlen strtok trim

Classes that implement MIME decoding

This class of decoding method is decode ($head =null, $body =null, $content _num=-1), in order to deal with the convenience, requires input is two character array, in our last chapter, the use of pop class is charged with two such arrays, One is the content of the message header, and one is the body content of the message. It is limited to space and does not give a detailed description of its implementation, similar to the Pop class described in the previous article. Please refer to the comments.

This class uses a large number of regular expression operations, the unfamiliar reader, please refer to the regular expression of the relevant information.

Class Decode_mail
{
var $from _name;var $to _name;var $mail _time;var $from _mail;var $to _mail;
var $reply _to;var $cc _to;var $subject;
Message after decoding the header portion of the message:
var $body;
After decoding, the body data obtained is an array.
var $body _type; Body type
var $tem _num=0;
var $get _content_num=0;
var $body _temp=array ();
var $body _code_type;
var $boundary;
These are some of the global temporary variables used in some methods, because PHP can not do a good encapsulation, so can only be placed here to define
var $err _str; Error message
var $debug = 0; Debug tags
var $month _num=array ("The =>1", "Feb" =>2, "the Mar" =>3, "APR" =>4, "may" =>5, "June" =>6, "" "=>7,
"Aug" =>8, "Sep" =>9, "Oct" =>10, "Nov" =>11, "Dec" =>12); Converts the English month into a digital month
function decode ($head =null, $body =null, $content _num=-1)//Calling the Main method, $head and $body are two arrays, $content _num represents when the body has multiple parts, Remove only the contents of the specified section to increase efficiency by default of-1, which means decoding the entire contents and, if the decoding succeeds, returns true
{
if (! $head and! $body)
{
$this->err_str= "does not specify the header and content!! of the message";
return false;
}
if (GetType ($head) = = "Array")
{
$have _decode=true;
$this->decode_head ($head);
}
if (GetType ($body) = = "Array")
{
$this->get_content_num= $content _num;
$this->body_temp= $body;
$have _decode=true;
$this->decode_body ();
unset ($this->body_temp);
}
if (! $have _decode)
{
$this->err_str= "passed the wrong argument, usage: New Decode_mail (head,body) two parameters are array";
return false;
}
}
function Decode_head ($head)//decoding of message headers, removing meaningful content from headers
{
$i = 0;
$this->from_name= $this->to_name= $this->mail_time= $this->from_mail= $this->
to_mail= $this->reply_to= $this->cc_to= $this->subject= "";
$this->body_type= $Sthis->boundary= $this->body_code_type= "";
while ($head [$i])
{
if (Strpos ($head [$i], "=?"))
$head [$i]= $this->decode_mime ($head [$i]); If there is encoded content, then decoding, decoding function is described above decode_mime ()
$pos =strpos ($head [$i], ":");
$summ =substr ($head [$i],0, $pos);
$content =substr ($head [$i], $pos + 1); Separate the identity of the message header from the content
if ($this->debug) echo $summ. ":----:". $content. " <BR> ";
Switch (Strtoupper ($SUMM))
{
Case "from"://Sender's address and name (may not have name, only address information)
if ($left _tag_pos=strpos ($content, "<"))
{
$mail _lenth=strrpos ($content, ">")-$left _tag_pos-1;
$this->from_name=substr ($content, 0, $left _tag_pos);
$this->from_mail=substr ($content, $left _tag_pos+1, $mail _lenth);
if (Trim ($this->from_name) = "") $this->from_name= $this->from_mail;
Else
if (Ereg ("[\" |\ '] ([^\ ' \ "]+) [\ ' |\"] ", $this->from_name, $reg))
$this->from_name= $reg [1];
}
Else
{
$this->from_name= $content;
$this->from_mail= $content;
No sender's e-mail address
}
Break
Case "to"://Recipient address and name (may not have name)
if ($left _tag_pos=strpos ($content, "<"))
{
$mail _lenth=strrpos ($content, ">")-$left _tag_pos-1;
$this->to_name=substr ($content, 0, $left _tag_pos);
$this->to_mail=substr ($content, $left _tag_pos+1, $mail _lenth);
if (Trim ($this->to_name) = "") $this->to_name= $this->to_mail;
Else
if (Ereg ("[\" |\ '] ([^\ ' \ "]+) [\ ' |\"] ", $this->to_name, $reg))
$this->to_name= $reg [1];
}
Else
{
$this->to_name= $content;
$this->to_mail= $content;
No separate mail addresses for recipients
}
Break
Case "Date"://Send date, for easy handling, here is a Unix timestamp, which can be used date ("y-m-d", $this->mail_time) to get a general format
$content =trim ($content);
$day =strtok ($content, "");
$day =substr ($day, 0,strlen ($day)-1);
$date =strtok ("");
$month = $this->month_num[strtok ("")];
$year =strtok ("");
$time =strtok ("");
$time =split (":", $time);
$this->mail_time=mktime ($time [0], $time [1], $time [2], $month, $date, and $year);
Break
Case "SUBJECT"://Mail subject
$this->subject= $content;
Break
Case "reply_to"://Reply to address (may not be)
if (Ereg ("< ([^>]+) >", $content, $reg))
$this->reply_to= $reg [1];
else $this->reply_to= $content;
Break
Case "Content-type"://CONTENT type of the entire message, eregi ([^;] *); ", $content, $reg);
$this->body_type=trim ($reg [1]);
if (eregi ("multipart", $content))//If multipart type, get separator
{
while (!eregi (. *) \ ", $head [$i], $reg) and $head [$i])
$i + +;
$this->boundary= $reg [1];
}
else//For general body type, get the encoding method directly
{
while (!eregi ("charset=[\" |\ "] (. *) [\ ' |\ ']", $head [$i], $reg))
$i + +;
$this->body_char_set= $reg [1];
while (!eregi ("content-transfer-encoding: (. *)", $head [$i], $reg))
$i + +;
$this->body_code_type=trim ($reg [1]);
}
Break
Case "CC"://CC to..
if (Ereg ("< ([^>]+) >", $content, $reg))
$this->cc_to= $reg [1];
Else
$this->cc_to= $content;
Default
Break
}//End switch

$i + +;
}//End While

if (Trim ($this->reply_to) = "")//If no reply address is specified, the reply address is the sender's address
$this->reply_to= $this->from_mail;
}//End Function Define
function decode_body ()//text decoding, which uses a number of message headers to decode the information obtained
{
$i = 0;
if (!eregi ("multipart", $this->body_type))//If not a composite type, you can decode it directly
{
$tem _body=implode ($this->body_temp, "\ r \ n");
Switch (Strtolower ($this->body_code_type))//Body_code_type, encoding of the body, obtained from the message header information
{case "base64":
$tem _body=base64_decode ($tem _body);
Break
Case "Quoted-printable":
$tem _body=quoted_printable_decode ($tem _body);
Break
}
$this->tem_num=0;
$this->body=array ();
$this->body[$this->tem_num][content_id]= "";
$this->body[$this->tem_num][type]= $this->body_type;
Switch (Strtolower ($this->body_type))
{
Case "text/html":
$this->body[$this->tem_num][name]= "Hypertext text";
Break
Case "Text/plain":
$this->body[$this->tem_num][name]= "text body";
Break
Default
$this->body[$this->tem_num][name]= "Unknown Body";
}

$this->body[$this->tem_num][size]=strlen ($tem _body);
$this->body[$this->tem_num][content]= $tem _body;
unset ($tem _body);
}
else//If it is a composite type
{
$this->body=array ();
$this->tem_num=0;
$this->decode_mult ($this->body_type, $this->boundary,0); To invoke a decoding method of a composite type
}
}
function Decode_mult ($type, $boundary, $begin _row)//This method uses a recursive method to decode the message body of a compound type, which is taken from a body_temp array, given the type of the compound type, separator, and The start pointer in the BODY_TEMP array
{
$i = $begin _row;
$lines =count ($this->body_temp);
while ($i < $lines)//This is the end of a part of the logo;
{
while (!eregi ($boundary, $this->body_temp[$i))//Find a start ID
$i + +;
if (Eregi ($boundary.) -", $this->body_temp[$i]))
{
return $i;
}
while (!eregi ("Content-type: [^;] *); ", $this->body_temp[$i], $reg) and $this->body_temp[$i])
$i + +;
$sub _type=trim ($reg [1]); The type that gets this part is milt or text ....
if (eregi ("multipart", $sub _type))//The sub part has several parts;
{
while (!eregi (' boundary=\ "([^\"]*) \ "', $this->body_temp[$i], $reg) and $this->body_temp[$i])
$i + +;
$sub the delimiter of the _boundary= $reg [1];//sub section;
$i + +;
$last _row= $this->decode_mult ($sub _type, $sub _boundary, $i);
$i = $last _row;
}
Else
{
$comm = "";
while (Trim ($this->body_temp[$i])!= "")
{
if (Strpos ($this->body_temp[$i], "=?")
$this->body_temp[$i]= $this->decode_mime ($this->body_temp[$i]);
if (Eregi ("content-transfer-encoding: (. *)", $this->body_temp[$i], $reg))
$code _type=strtolower (Trim ($reg [1])); Encoding method
$comm. = $this->body_temp[$i]. " \ r \ n ";
$i + +;
//Comm is the description part of the encoding
if (eregi (' name=[\ "] ([^\]*) [\] ', $comm, $reg))
$name = $reg [1];
if (Eregi ("Content-disposition: (. *);", $comm, $reg))
$disp = $reg [1];
if (eregi ("charset=[\" |\ "] (. *) [\ ' |\"] ", $comm, $reg))
$char _set= $reg [1];
if (eregi ("content-id:[]*\< (. *) \>", $comm, $reg))//Picture identifier.
$content _id= $reg [1];
$this->body[$this->tem_num][type]= $sub _type;
$this->body[$this->tem_num][content_id]= $content _id;
$this->body[$this->tem_num][char_set]= $char _set;
if ($name)
$this->body[$this->tem_num][name]= $name;
Else
Switch (Strtolower ($sub _type))
{
Case "text/html":
$this->body[$this->tem_num][name]= "Hypertext text";
Break
Case "Text/plain":
$this->body[$this->tem_num][name]= "text body";
Break
Default
$this->body[$this->tem_num][name]= "Unknown Body";
}

The next line begins to retrieve the body
if ($this->get_content_num==-1 or $this->get_content_num== $this->tem_num)//Determine if this part is required. -1 means all
{
$content = "";
while (!ereg ($boundary, $this->body_temp[$i]))
{
$content []= $this->body_temp[$i];
$content. = $this->body_temp[$i]. " \ r \ n ";
$i + +;
}
$content =implode ("\ r \ n", $content);
Switch ($code _type)
{
Case "Base64":
$content =base64_decode ($content);
Break
Case "Quoted-printable":
$content =str_replace ("\ n", "\ r \ n", Quoted_printable_decode ($content));
Break
}
$this->body[$this->tem_num][size]=strlen ($content);
$this->body[$this->tem_num][content]= $content;
}
Else
{
while (!ereg ($boundary, $this->body_temp[$i]))
$i + +;
}
$this->tem_num++;
}
End Else
}//End while;
}//End Function define
function Decode_mime ($string) {
Decode_mime has been given in the above, skipping over here.
}
}//End Class define

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.