如何使用 imap 扩展获取原始电子邮件数据?
Posted
技术标签:
【中文标题】如何使用 imap 扩展获取原始电子邮件数据?【英文标题】:How to get raw email data with the imap extension? 【发布时间】:2012-05-04 20:03:59 【问题描述】:我正在寻找一种下载整个原始电子邮件数据(包括附件)的方法,类似于您在 Gmail 中单击“显示原始数据”所获得的方法。
目前,我可以通过以下代码获取原始标题和邮件正文的某些部分:
$this->MailBox = imap_open($mailServer, $userName, $password, OP_SILENT);
...
$email->RawEmail = imap_fetchbody($this->MailBox, $msgNo, "0");
$email->RawEmail .= "\n".imap_fetchbody($this->MailBox, $msgNo, "1");
我也知道更改 imap_fetchbody 的第三个参数可能会返回编码的附件。我想我这里需要一个循环来部分获取原始电子邮件,但是停止循环的条件是什么?
有没有一种简单的方法可以一次获取整封电子邮件?
任何帮助将不胜感激。
【问题讨论】:
【参考方案1】:我的回答是“过度完成”,如果您不需要电子邮件。
如果要获取全部,则需要获取
标头imap_fetchheader
。
获取邮件的正文数量imap_fetchstructure
。
每个矿井头都有imap_fetchmime
。
它拥有imap_fetchbody
的每个实体。
由于 mime-message 可以有多个正文,您需要一个接一个地处理每个部分。要减少服务器的负载,请使用imap_fetchheader
的FT_PREFETCHTEXT
选项。一些示例 code about imap_fetchstructure
in another answer 显示了处理 imap 连接并通过封装对消息的部分进行迭代。
【讨论】:
向下滚动,使用imap_fetchbody($imap_stream, $msg_num, "")
更简单,而且效果很好!
我也不确定这是否回答了这个问题,因为它没有界限。【参考方案2】:
我在搜索相同问题时遇到了这个问题。我知道它必须比 hakre 的解决方案更容易,并且我在 post from 5 years ago 的 imap_fetchbody
页面上找到了正确答案。
要获取完整的原始消息,只需使用以下命令:
$imap_stream = imap_open($server, $username, $password);
$raw_full_email = imap_fetchbody($imap_stream, $msg_num, "");
注意空字符串作为imap_fetchbody
的第三个参数,这表示电子邮件的所有部分和子部分,包括标题和所有正文。
【讨论】:
太棒了!它会获取附件吗? @VeeeneX 是的,它会获取所有内容。附件确实需要解码,它们通常是 base64 编码的。现在电子邮件提供商允许使用 OneDrive/GoogleDrive 发送“附件”,这些不是真正的附件,它们不会被获取。 这是最好的解决方案——只用一行来检索完整的消息,这样您就可以将其输入解析器。 $raw_full_email = imap_fetchbody($handle, $num, ""); $Parser = new phpMimeMailParser\Parser(); $Parser->setText($raw_full_email); 有没有其他人从这个PHP Warning: imap_fetchbody(): Bad message number in ...
得到错误?【参考方案3】:
hakre 的回答过于完整,如果您不真正关心结构,那么您将不需要imap_fetchstructure。
对于一个简单的“显示源”,您应该只需要 imap_fetchheader 和 imap_body。
示例:
$conn = imap_open(''."$mailServer:$port/pop3INBOX", $userName, $password, OP_SILENT && OP_READONLY);
$msgs = imap_fetch_overview($conn, '1:5'); /** first 5 messages */
foreach ($msgs as $msg)
$source = imap_fetchheader($conn, $msg->msgno) . imap_body($conn, $msg->msgno);
print $source;
【讨论】:
【参考方案4】:一个常见的错误是使用"\n"
或PHP_EOL
。
根据 RFC RFC821, RFC2060, RFC1939 "\r\n"
应该被使用。
虽然一些邮件服务器会自动转换错误,但 Cyrus 不会并抛出一个很好的错误。
PHP_EOL
是一个系统依赖常量,例如在 Linux 上是 "\n"
,在 Mac 上是 "\r"
,在 Windows 上是 "\r\n"
。
此外,imap_fetchheader()
包含尾随 "\r\n"
,正如预期的那样。所以正确的例子是:
$source = imap_fetchheader($conn, $msg->msgno) . imap_body($conn, $msg->msgno);
【讨论】:
以上是关于如何使用 imap 扩展获取原始电子邮件数据?的主要内容,如果未能解决你的问题,请参考以下文章