PHP中的imap_open函数有时会看到空白邮件正文

时间:2013-12-11 14:49:14

标签: php

我在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 ...继续

如何将整个邮件正文转换为纯文本

2 个答案:

答案 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)

给定的代码仅处理具有至多一个子部分且没有编码的简单文本消息。这基本上是最简单的电子邮件。世界曾经是那么简单,遗憾的是不再!!

要处理更多电子邮件,必须扩展您的代码以处理:

  1. 多份
  2. 编码
  3. 多部分是将单个电子邮件消息(一堆数据)划分为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-printablebase64。虽然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/