Decoding of POP3 messages with PHP (c) _php

Source: Internet
Author: User
Keywords mail implementation Content if reg text EC
Tags ereg image identifier strtok
POP3

Classes that implement MIME decoding
(Author: Chen Junqing October 24, 2000 15:11)

A class that implements MIME decoding

This class implements decoding method is decode ($head =null, $body =null, $content _num=-1), in order to handle the convenience, the input is two character array, in our previous article, the Pop class used to receive is two such an array, One is the message header content, one is the body content of the message. Confined to the space, not to do a detailed explanation, the realization of the idea is similar to the Pop class described in the previous article. Please refer to the comments.

A large number of regular expressions are used in this class, and for unfamiliar readers, refer to the relevant data of the regular expressions.

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 in the message header section after decoding:

var $body;

After decoding, the resulting body data 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 methods used in some of the global temporary variables, 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 ("Jan" =>1, "Feb" =>2, "Mar" =>3, "APR" =>4, "may" =>5, "June" =>6, "Jul" =>7,

"=>8", "Sep" =>9, "Oct" =>10, "Nov" =>11, "Dec" =>12); Convert the English month into a numeric month

function decode ($head =null, $body =null, $content _num=-1)//The Main method of the call, $head and $body are two arrays, $content _num represents when the body has multiple parts, Only the content of the specified part is removed to improve efficiency, the default is-1, which means decoding the entire content, if the decoding succeeds, the method returns True

{

if (! $head and! $body)

{

$this->err_str= "No header and content for the specified 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 arrays";

return false;

}

}

function Decode_head ($head)//message header content decoding, take out the message header meaningful content

{

$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 message header information from the content

if ($this->debug) echo $summ. ":----:". $content. "
";

Switch (Strtoupper ($SUMM))

{

Case ' from '://Sender's address and name (may not have a 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 e-mail address from Sender

}

Break

Case ' to '://Recipient's address and name (may not have a 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 recipient's email address

}

Break

Case "Date"://Send date, for ease of handling, this returns a Unix timestamp, can be used date ("y-m-d", $this->mail_time) to get the general format of the day

$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, $year);

Break

Case "SUBJECT"://Email 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 for the entire message, eregi ("([^;] *); ", $content, $reg);

$this->body_type=trim ($reg [1]);

if (eregi ("multipart", $content))//If it is a multipart type, get the delimiter

{

while (!eregi (' boundary=\ ' (. *) \ "', $head [$i], $reg) and $head [$i])

$i + +;

$this->boundary= $reg [1];

}

else//For general body type, direct access to its encoding method

{

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-to address is the sender's address

$this->reply_to= $this->from_mail;

}//End Function Define

function decode_body ()//body decoding, which uses a lot of message header decoding information obtained

{

$i = 0;

if (!eregi ("multipart", $this->body_type))//If it is not a composite type, it can be decoded directly

{

$tem _body=implode ($this->body_temp, "\ r \ n");

Switch (Strtolower ($this->body_code_type))//Body_code_type, the body encoding method, obtained by 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); Calling the decoding method of a composite type

}

}

function Decode_mult ($type, $boundary, $begin _row)//This method implements the decoding of compound type message body by recursive method, the message source file is taken from the body_temp array, and the type, delimiter and The start pointer in the BODY_TEMP array

{

$i = $begin _row;

$lines =count ($this->body_temp);

while ($i < $lines)//This is a part of the end of the logo;

{

while (!eregi ($boundary, $this->body_temp[$i])//Find a start identity

$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 is also a plurality of parts;

{

while (!eregi (' boundary=\ ' ([^\]*) \ "', $this->body_temp[$i], $reg) and $this->body_temp[$i])

$i + +;

$sub _boundary= $reg [The delimiter of the 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))//image 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 starts retrieving the body

if ($this->get_content_num==-1 or $this->get_content_num== $this->tem_num)//Determine if this part is needed. -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, skipped here.

}

}//End Class define

A special note here is the decoding of the images used in the HTML body. When you send an HTML-formatted body, you will encounter problems with how the image is routed. A picture is a label in an HTML document, and the key is where the source file comes from. Many messages are handled using an absolute URL identifier, which is a tag in the HTML body of the message, so that when you read the message, the message reader (usually an embedded browser) automatically downloads the image from the web, but if the message is received, the connection to the Internet is broken, The picture will not display properly.

So the better way is to put the picture in the mail and send it together. In MIME encoding, the relationship between the picture and the body is described, in addition to the multipart/related MIME header information mentioned above, a Content-id: property is used to establish a relationship between the picture and the HTML body. A picture in an HTML document is encoded with a content-id:122223443556dsdf@ntsever-like attribute in its MIME header, and 122223443556dsdf@ntsever is a unique identifier, in an HTML document, tags are modified to, in fact, in the decoding of the HTML body of these tags to be modified to point to the decoded image of the specific path. However, given the specific decoding process for the image will be different processing, so in this decoding class, the HMTL body of the label is not modified. So in the actual use of this class, for the image of the HTML text, but also need some processing. The picture in the body can be saved with temporary files, or it can be saved with a database.

We have now introduced the principle of POP3 receiving mail and MIME decoding. Here is a small program that uses these two classes:

  
Include ("pop3.inc.php");

Include ("mime.inc.php");

$host = "pop.china.com";

$user = "Boss_ch";

$pass = "MyPassword";

$rec =new POP3 ($host, 110,2);

$decoder =new Decode_mail ();

if (! $rec->open ()) Die ($rec->err_str);

if (! $rec->login ($user, $pass)) die ($rec->err_str);

if (! $rec->stat ()) Die ($rec->err_str);

echo "Shared". $rec->messages. " Letter, Total ". $rec->size." BYTE size
";

if ($rec->messages>0)

{

if (! $rec->listmail ()) Die ($rec->err_str);

echo "The following are the contents of the letter:
";

for ($i =1; $i <=count ($rec->mail_list); $i + +)

{

echo "letter". $rec->mail_list[$i][num]. ", Size:". $rec->mail_list[$i][size]. "
";

$rec->getmail ($rec->mail_list[$i][num]);

$decoder->decode ($rec->head, $rec->body);

echo "

Contents of the message header:


";

echo $decoder->from_name. " (". $decoder->from_mail.") To ". Date" ("Y-m-d h:i:s", $decoder->mail_time). "Send". $decoder->to_name. " (". $decoder->to_mail.");

echo "\ n
CC: ";

if ($decoder->cc_to) echo $decoder->cc_to;else echo "None";

echo "\ n
Subject: ". $decoder->subject;

echo "\ n
Reply to: ". $decoder->reply_to;

  

echo "

Message body:


";

echo "Body type:". $decoder->body_type;

echo "
The contents of the text: ";

for ($j =0; $j body); $j + +)

{

echo "\ n
Type: ". $decoder->body[$j][type];

echo "\ n
Name: ". $decoder->body[$j][name];

echo "\ n
Size: ". $decoder->body[$j][size];

echo "\ n
content_id: ". $decoder->body[$j][content_id];

echo "\ n
Body character set ". $decoder->body[$j][char_set];

echo "




echo "
";

}

$rec->dele ($i);

}

}

$rec->close ();

?>

If you want to get complete source code of friends, please contact me: boss_ch@netease.com



<全文完>
  • Related Article

    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.