用 PHP 实现 POP3 邮件的解码(2)-PHP精通-PHP教程-幽默笑话

文章内容用PHP实现POP3邮件的解码(2)修改时间:[2012/03/0412:04]阅读次数:[642]发表者:[起缘]MIME编码方式简介  MIME编码方式简介  Subject:=gb2312BxOO6w6Oh=  这里是邮件的主题,可是因为编码了,我们看不出是什么内容,其原来的文本是:你好!我们先看看MIME编码的两种方法。   对邮件进行编码最初的原因是因为Internet上的很多网关不能正确传输8bit内码的字符,比如汉字等。

编码的原理就是把8bit的内容转换成7bit的形式以能正确传输,在接收方收到之后,再将其还原成8bit的内容。

  MIME是多用途网际邮件扩充协议的缩写,在MIME协议之前,邮件的编码曾经有过UUENCODE等编码方式,但是由于MIME协议算法简单,并且易于扩展,现在已经成为邮件编码方式的主流,不仅是用来传输8bit的字符,也可以用来传送二进制的文件,如邮件附件中的图像、音频等信息,而且扩展了很多基于MIME的应用。 从编码方式来说,MIME定义了两种编码方法Base64与QP(Quote-Printable):  Base64是一种通用的方法,其原理很简单,就是把三个Byte的数据用4个Byte表示,这样,这四个Byte中,实际用到的都只有前面6bit,这样就不存在只能传输7bit的字符的问题了。 Base64的缩写一般是B,像这封信中的Subject就是用的Base64编码。   另一种方法是QP(Quote-Printable)方法,通常缩写为Q方法,其原理是把一个8bit的字符用两个16进制数值表示,然后在前面加=。 所以我们看到经过QP编码后的文件通常是这个样子:=B3=C2=BF=A1=C7=E5=A3=AC=C4=FA=BA=C3=A3=A1。   在PHP里,系统有两个函数可以很方便地实现解码:base64_decode()与quoted_printable_decode(),前者可用于base64编码的解码,后者是用于QP编码方法的解码。   现在我们再来看看Subject:=gb2312BxOO6w6Oh=这一主题的内容,这不是一段完整的编码,只有部分是编码了的,这个部分用==两个标记括起来,=后面说明的是这段文字的字符集是GB2312,然后一个后面的一个B表示的是用的Base64编码。 通过这段分析,我们来看一下这个MIME解码的函数:(该函数由站长Sadly提供,本人将其放入一个类中,并做了少量的修改,在此致谢)  functiondecode_mime($string){  $pos=strpos($string,=);  if(!is_int($pos)){    return$string;  }  $preceding=substr($string,0,$pos);//saveanyprecedingtext  $search=substr($string,$pos+2);/*themimeheaderspecsaysthisisthelongestasingleencodedwordcanbe*/  $d1=strpos($search,);  if(!is_int($d1)){    return$string;  }  $charset=substr($string,$pos+2,$d1);//取出字符集的定义部分  $search=substr($search,$d1+1);//字符集定义以后的部分=$search;  $d2=strpos($search,);  if(!is_int($d2)){    return$string;  }  $encoding=substr($search,0,$d2);////两个 之间的部分编码方式 :q 或 b   $search=substr($search,$d2+1);  $end=strpos($search,=);//$d2+1与$end之间是编码了 的内容:=$endcoded_text;  if(!is_int($end)){    return$string;  }  $encoded_text=substr($search,0,$end);  $rest=substr($string,(strlen($preceding.$charset.$encoding.$encoded_text)+6));//+6是前面去掉的 == 六个字符  switch($encoding){  caseQ:  caseq:    //$encoded_text=str_replace(_,%20,$encoded_text);    //$encoded_text=str_replace(=,%,$encoded_text);    //$decoded=urldecode($encoded_text);  $decoded=quoted_printable_decode($encoded_text);    if(strtolower($charset)==windows-1251){    $decoded=convert_cyr_string($decoded,w,k);    }    break;  caseB:  caseb:    $decoded=base64_decode($encoded_text);    if(strtolower($charset)==windows-1251){    $decoded=convert_cyr_string($decoded,w,k);    }    break;  default:    $decoded==.$charset..$encoding..$encoded_text.=;    break;  }  return$preceding.$decoded.$this-decode_mime($rest);  }  这个函数用了递归的方法来实现一段包含有如上的Subject段的字符的解码。

程序中已经加上了注释。

相信有点PHP编程基础的人都能够看得明白。 该函数也是调用的base64_decode()与quoted_printable_decode()两个系统函数实现的解码,但是需要对邮件源文件进行大量的字符串的分析。

不过,PHP的字符串操作可以算是所有语言里最为方便自由的。

函数的最后return$preceding.$decoded.$this-decode_mime($rest);实现递归解码,因为这个函数实际上是放在后面要介绍的一个MIME解码的类中的,所以用了$this-decode_mime($rest)这种形式的调用方法。

  下面我们来看正文。

这里关系到MIME的一些头信息,我们先做一个简单的介绍(如果读者有兴趣了解更多的内容,请参考MIME的官方文档)。

  MIME-Version:  表示使用的MIME的版本号,一般是;  Content-Type:定义了正文的类型,我们实际上是通过这个标识来知道正文内是什么类型的文件,比如:text/plain表示的是无格式的文本正文,text/html表示的Html文档,image/gif表示的是gif格式的图片等等。

在本文中特别要说明一下的是邮件中常用到的复合类型。

multipart类型表示正文是由多个部分组成的,后面的子类型说明的是这些部分之间的关系,邮件中用到的三个类型有,multipart/alternative:表示正文由两个部分组成,可以选择其中的任意一个。 主要作用是在征文同时有text格式和html格式时,可以在两个正文中选择一个来显示,支持html格式的邮件客户端软件一般会显示其HTML正文,而不支持的则会显示其Text正文;multipart/mixed:表示文档的多个部分是混合的,指正文与附件的关系。

如果邮件的MIME类型是multipart/mixed,即表示邮件带有附件;multipart/related:表示文档的多个部分是相关的,一般用来描述Html正文与其相关的图片。

  这些复合类型又是可以嵌套使用的,比如说一个带有附件的邮件,同时有html与text两种格式的正文,则邮件的结构是:  Content-Type:multipart/mixed  部分一:  ContentType:multipart/alternative:  Text正文;  Html格式的正文   部分二:  附件  邮件结束符;  由于复合类型由多个部分组成,因此,需要一个分隔符来分隔这多个部分,这就是上面的邮件源文件中的boundary=----=_NextPart_000_0007_所描述的,对于每一个Contecttype:multipart/*的内容,都会有这么一个说明,表示多个部分之间的分隔,这个分隔符是正文中不可能出现的一串古字符的组合,在文档中,以 --加上这个boundary来表示一个部分的开始,在文档的结束,以--加boundary再在最后加上--来表示文档的结束。 由于复合类型是可以嵌套使用的,因此,邮件中可能会多个 boundary 。

  还有一个最重要的MIME头标签:  Content-Transfer-Encoding:base64它表示了这个部分文档的编码方式,也就是我们上面所介绍的Base64或QP(Quote-Printable)。 我们只有识别了这个说明,才能用正确的解码方式实现对其解码。

 限于篇幅,对于MIME的介绍就只说到这里。

下面我将给出一个解码MIME邮件的类,并对其做简要说明。

作者:陈俊清转载:中华网。

上一篇:不要一生奔忙,匆匆而过,网络流行经典语句

下一篇:没有了