我在PHP中使用imap_open
函数下载电子邮件并将它们插入mysql数据库。
下面是我的代码,用于获取标题和正文消息等:
$emails = imap_search($inbox,'ALL');
//if emails are returned, cycle through each...
if($emails)
{
//begin output var
$output = '';
//put the newest emails on top
rsort($emails);
//for every email...
foreach($emails as $email_number)
{
//get information specific to this email
$header=imap_headerinfo($inbox,$email_number);
$structure = imap_fetchstructure($inbox,$email_number);
$from = $header->from[0]->mailbox . "@" . $header->from[0]->host;
$toaddress=$header->to[0]->mailbox."@".$header->to[0]->host;
$replyto=$header->reply_to[0]->mailbox."@".$header->reply_to[0]->host;
$datetime=date("Y-m-d H:i:s",$header->udate);
$subject=$header->subject;
$message = quoted_printable_decode(imap_fetchbody($inbox,$email_number,1.1));
if($message == '')
{
$message = quoted_printable_decode(imap_fetchbody($inbox,$email_number,1));
}
}
}
但它似乎并没有得到所有电子邮件的主体。例如,当它收到阅读收据时,它的身体是空白的,和人们发送的其他电子邮件一样。
有时,电子邮件正文看起来像:
PGh0bWw+DQo8aGVhZD4NCjxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0i dGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04Ij4NCjwvaGVhZD4NCjxib2R5IHN0eWxlPSJ3b3JkLXdy YXA6IGJyZWFrLXdvcmQ7IC13ZWJraXQtbmJzcC1tb2RlOiBzcGFjZTsgLXdlYmtpdC1saW5lLWJy ZWFrOiBhZnRlci13aGl0ZS1zcGFjZTsgY29sb3I6IHJnYigwLCAwLCAwKTsgZm9udC1zaXplOiAx NHB4OyBmb250LWZhbWlseTogQ2FsaWJyaSwgc2Fucy1zZXJpZjsiPg0KPGRpdj4NCjxkaXY+DQo8 ZGl2PnJlcGx5PC9kaXY+DQo8ZGl2Pg0KPHAgc3R5bGU9ImZvbnQtZmFtaWx5OiBDYWxpYnJpOyBt YXJnaW46IDBweCAwcHggMTJweDsiPjxiPktpbmQgUmVnYXJkcyw8YnI+DQo8YnI+DQpDaGFybGll IEZvcmQgfCZuYnNwOzwvYj48c3BhbiBzdHlsZT0iY29sb3I6IHJnYigyNTIsIDc5LCA4KTsiPjxi PlRlY2huaWNhbCBNYW5hZ2VyJm5ic3A7PC9iPjwvc3Bhbj48Yj58Jm5ic3A7SW50ZWdyYSBEaWdp dGFsPC9iPjxmb250IGNvbG9yPSIjNTk1OTU ..。续
如何将整个消息正文转换为纯文本?
发布于 2013-12-11 17:04:29
一般情况下,我用的是这个。$email
是指从imap_fetch_overview
返回的对象之一。
$structure = imap_fetchstructure($email->msgno);
$body = imap_fetchbody($email->msgno, '1');
if (3 === $structure->encoding) {
$body = imap_base64($body);
} else if (4 === $structure->encoding) {
$body = imap_qprint($body);
}
注有6种可能的编码(从0到5),我只处理其中的2个(3和4) --您可能需要处理所有这些编码。
还要注意,我也只得到了第一部分(在imap_fetchbody中) --您可能需要遍历这些部分,以便根据需要得到它们。
更新
关于你的代码我注意到了另一件事。你在做imap_fetchbody($inbox,$email_number,1.1)
。第三个参数应该是字符串,而不是数字。取而代之的是这样做:
imap_fetchbody($inbox, $email_number, '1.1')
发布于 2013-12-13 16:25:32
给出的代码只处理简单的文本消息,最多只有一个子部分,没有编码。这基本上是最简单的电子邮件。这个世界曾经是那么简单,可悲的是,再也没有了!
若要处理更多电子邮件,必须展开代码以处理:
多部分是一个概念,一个单一的电子邮件消息(一堆数据)可以划分为多个逻辑上分开的部分。在最简单的情况下,只有一个部分:消息的文本。在下一个最简单的例子中,只有一个附件的消息文本。下一个最简单的情况是消息文本加上多个附件。然后,当消息的文本以内联方式引用或嵌入附件时,它就开始变得困难了(想想带有图像的HTML -该图像可能是一个与“本地”CSS链接的附件,或者是嵌入到base64数据url中的附件)。
编码是指电子邮件需要容纳Internet上SMTP服务器的最低公分母。从1971年到1990年代初,中间的大多数电子邮件都是使用7位美国ASCII的纯文本。字符集和SMTP邮件都依赖于这个7位的框架。随着对字符集的需求变得越来越明显,同时需要发送二进制数据(如图像),8位SMTP邮件机出现了,各种方法可以将8位清洁数据塞进7位。其中包括引文-可打印和base64。虽然7位几乎已经死了,我们仍然有所有的循环这一历史跨越。
与其重新发明轮子,PHP.net上还有一段处理多部分编码消息的好代码。请参阅大卫在hundsness网站的评论。您可以使用这样的代码:
$mailbox = imap_open($service, $username, $password) or die('Cannot open mailbox');
// for all messages
$emails = imap_fetch_overview($mailbox, '1:1'/* . imap_check($mbox)->Nmsgs*/);
foreach ($emails as $email) {
// get the info
getmsg($mailbox, $email->msgno);
// now you have info from this message in these global vars:
// $charset,$htmlmsg,$plainmsg,$attachments
echo $plainmsg; // for example
}
imap_close($mailbox);
(附带注意:他的代码有三个解析错误,其中".=“的意思是”.=“。把这些修好,你就可以走了。
另外,如果你想找一个“从头开始”做这件事的好博客,请查看以下内容:http://www.electrictoolbox.com/php-imap-message-parts/
https://stackoverflow.com/questions/20522211
复制相似问题