我在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 ...继续
如何将整个邮件正文转换为纯文本
答案 0 :(得分:1)
总的来说,这就是我的用法。 $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')
答案 1 :(得分:1)
给定的代码仅处理具有至多一个子部分且没有编码的简单文本消息。这基本上是最简单的电子邮件。世界曾经是那么简单,遗憾的是不再!!
要处理更多电子邮件,必须扩展您的代码以处理:
多部分是将单个电子邮件消息(一堆数据)划分为multiple, logically-separate pieces的概念。在最简单的情况下,只有一部分:消息的文本。在下一个最简单的情况下,有一个带有单个附件的消息文本。下一个最简单的情况是消息文本和多个附件。然后它开始变得困难,当消息的文本内联或嵌入附件时(想想带有图像的HTML消息 - 该图像可以是与“本地”CSS链接或作为例如base64数据URL嵌入的附件)。
编码是指电子邮件需要适应Internet上SMTP服务器的最小公分母。从1971年到1990年代初,most email messages were plain text using 7-bit US ASCII字符集 - 中间的SMTP邮件程序依赖于这个7位框架。随着对字符集的需求变得更加明显,同时需要发送二进制数据(例如图像),8位SMTP邮件程序也出现了,因为各种方法将鞋带8-bit clean数据转换为7位。其中包括quoted-printable和base64。虽然7-bit is virtually dead,我们仍然可以通过这段历史的所有环节来跳过。
PHP.net上有一段很好的代码可以处理多部分编码消息,而不是重新发明轮子。请参阅david at hundsness dot com的评论。您可以使用这样的代码:
$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/