日期:2011-01-02 浏览次数:20430 次
初步认识邮件的源文件
本文简要说明了通过POP3协议收取邮件、MIME邮件的解码的原理;针对收取和MIME解码,提供了两个实用的PHP类,并提供了使用的样例。分为邮件收取、MIME解码两个部分。我们已经向您介绍过了邮件的收取,现在让我们来为您介绍本文的解码部。
在上一篇里,我们已经完成了一个用PHP通过POP3收取邮件的实例,可是在使用这个类的时候,相信你已经看到了,很多的邮件收下来是一堆乱码,自己根本看不懂!是的。现在的邮件大部分都已经经过了编码,需要一个解码的过程才能变成我们习惯的文字、图片、或是其它的附件。
邮件的源文件
首先,我们来看一段简单的邮件的源文件:(在Foxmail中,选中邮件,点选“查看源文件”就会看到这样的些内容了)
From: <boss_ch@netease.com>
To: <boss_ch@china.com>
Subject: =?gb2312?B?xOO6w6Oh?=
Date: Sun, 8 Oct 2000 20:28:45 +0800
MIME-Version: 1.0
Content-Type: multipart/alternative;
boundary="----=_NextPart_000_0007_01C03166.5B1E9510"
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook Express 5.00.2919.6700
X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2919.6700
This is a multi-part message in MIME format.
------=_NextPart_000_0007_01C03166.5B1E9510
Content-Type: text/plain;
charset="gb2312"
Content-Transfer-Encoding: base64
w7vT0MLSwuuwyaO/DQo=
------=_NextPart_000_0007_01C03166.5B1E9510
Content-Type: text/html;
charset="gb2312"
Content-Transfer-Encoding: base64
PCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMCBUcmFuc2l0aW9uYWwv
L0VOIj4NCjxIVE1MPjxIRUFEPg0KPE1FVEEgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PWdi
MjMxMiIgaHR0cC1lcXVpdj1Db250ZW50LVR5cGU+DQo8TUVUQSBjb250ZW50PSJNU0hUTUwgNS4w
MC4yOTIwLjAiIG5hbWU9R0VORVJBVE9SPg0KPFNUWUxFPjwvU1RZTEU+DQo8L0hFQUQ+DQo8Qk9E
WSBiZ0NvbG9yPSNmZmZmZmY+DQo8RElWPjxGT05UIHNpemU9Mj7Du9PQwtLC67DJo788L0ZPTlQ+
PC9ESVY+PC9CT0RZPjwvSFRNTD4NCg==
------=_NextPart_000_0007_01C03166.5B1E9510-
这样的一段邮件,我想没有人能看得懂的。不要急,我们来仔细看看这些内容。
From: <boy@netease.com>
To: <boss_ch@china.com>
这个是好理解的,邮件由boy@netease.com发送,收件人是boss_ch@china.com,这些标签的含义我们基本可从字面上理解到,像Date:Sun, 8 Oct 2000 20:28:45 +0800表示的是时间,X-Priority: 3表示的是邮件的优先级,X-Mailer: Microsoft Outlook Express 5.00.2919.6700表示的是邮件发送器的名字,这里用的是Outllook 5,不过,这些东西跟邮件的内容是没有很大关系的。我们不需要深究。
MIME 编码方式简介
MIME 编码方式简介
Subject: =?gb2312?B?xOO6w6Oh?=
这里是邮件的主题,可是因为编码了,我们看不出是什么内容,其原来的文本是:“你好!”我们先看看 MIME 编码的两种方法。
对邮件进行编码最初的原因是因为 Internet 上的很多网关不能正确传输8 bit 内码的字符,比如汉字等。编码的原理就是把 8 bit 的内容转换成 7 bit 的形式以能正确传输,在接收方收到之后,再将其还原成 8 bit 的内容。
MIME 是“多用途网际邮件扩充协议”的缩写,在 MIME 协议之前,邮件的编码曾经有过 UUENCODE 等编码方式 ,但是由于 MIME 协议算法简单,并且易于扩展,现在已经成为邮件编码方式的主流,不仅是用来传输 8 bit 的字符,也可以用来传送二进制的文件 ,如邮件附件中的图像、音频等信息,而且扩展了很多基于MIME 的应用。从编码方式来说,MIME 定义了两种编码方法Base64与QP(Quote-Printable) :
Base 64 是一种通用的方法,其原理很简单,就是把三个Byte的数据用 4 个Byte表示,这样,这四个Byte 中,实际用到的都只有前面6 bit,这样就不存在只能传输 7bit 的字符的问题了。Base 64的缩写一般是“B”,像这封信中的Subject 就是用的 Base64 编码。
另一种方法是QP(Quote-Printable) 方法,通常缩写为“Q”方法,其原理是把一个 8 bit 的字符用两个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: =?gb2312?B?xOO6w6Oh?= 这一主题的内容,这不是一段完整的编码,只有部分是编码了的,这个部分用 =? ?= 两个标记括起来,=? 后面说明的是这段文字的字符集是 GB2312 ,然后一个 ? 后面的一个 B 表示的是用的 Base64 编码。通过这段分析,我们来看一下这个 MIME 解码的函数:(该函数由 PHPX.COM 站长 Sadly 提供,本人将其放入一个类中,并做了少量的修改,在此致谢)
function decode_mime($string) {
$pos = strpos($string, '=?');
if (!is_int($pos)) {
return $string;
}