在PHP中解析原始电子邮件
我正在寻找良好/有效/简单的方法来使用php代码将原始电子邮件解析为多个部分。
我已经写了几个蛮力解决方案,但是每次都会出现一个小的更改/标题/空格/某些东西,而我的整个解析器都会失败,并且项目会崩溃。
在指出PEAR / PECL之前,我需要实际的代码。我的主机有一些配置错误的东西,我似乎永远无法正确构建.so。如果我确实制作了.so,则path / environment / php.ini中的某些差异并不总是使它可用(apache,cron,cli)。
哦,还有最后一件事,我正在解析原始电子邮件文本,不是POP3和不是IMAP。它通过.qmail电子邮件重定向通过管道传递到php脚本中。
我不希望SOF为我编写它,我正在寻找"正确"使用它的一些技巧/起点。这是我知道已经解决的那些"滚轮"问题之一。
解决方案
回答
我们希望最终得到什么?正文,主题,发件人,附件?我们应该花一些时间使用RFC2822来了解邮件的格式,但是以下是格式正确的电子邮件的最简单规则:
HEADERS\n \n BODY
也就是说,第一个空白行(双换行符)是HEADERS和BODY之间的分隔符。 HEADER看起来像这样:
HSTRING:HTEXT
HSTRING始终从行的开头开始,并且不包含任何空格或者冒号。 HTEXT可以包含各种文本,包括换行符,只要换行符后跟空白字符即可。
" BODY"实际上只是跟随第一个双换行符的任何数据。 (如果要通过SMTP传输邮件,则有不同的规则,但是不必通过管道进行处理)。
因此,以非常简单的大约1982年的RFC822术语来说,电子邮件看起来像这样:
HEADER: HEADER TEXT HEADER: MORE HEADER TEXT INCLUDING A LINE CONTINUATION HEADER: LAST HEADER THIS IS ANY ARBITRARY DATA (FOR THE MOST PART)
不过,大多数现代电子邮件都比这更复杂。标头可以编码为字符集或者RFC2047 MIME单词,或者其他我现在不考虑的其他内容。这些天来,如果我们希望它们变得有意义的话,这些实体真的很难滚动。由MUA生成的几乎所有电子邮件都将进行MIME编码。可能是uuencoded文本,可能是html,也可能是uuencoded excel电子表格。
我希望这有助于为理解一些非常基本的电子邮件桶提供一个框架。如果我们提供有关数据处理背景的信息,我(或者其他人)可能会提供更好的指导。
回答
是的,根据该rfc和其他一些基本教程,我已经能够编写一个基本的解析器。但是它的多部分mime嵌套边界使我一团糟。
我发现从手机发送的MMS(不是SMS)消息只是标准电子邮件,因此我有一个系统可以读取传入的电子邮件,检查发件人(仅允许从我的电话中),并使用正文部分来运行不同的消息我服务器上的命令。有点像通过电子邮件进行的远程控制。
由于该系统旨在发送图片,因此它具有许多不同的编码部分。一个mms.smil.txt部分,一个文本/纯文本部分(没有用,只说"这是html消息"),一个应用程序/ smil部分(电话将在其上显示的部分),一个text / html部分首先是广告,然后是我的信息,但所有信息都包裹在html中,最后是一个文本文件附件,其中包含我的普通信息(这是我使用的部分)(如果我将图像作为附件添加到邮件中,则将其放置在附件1,编码为base64,然后将我的文本部分作为附件2添加)
我使用了运营商提供的准确的邮件格式,但是当我通过别人的手机发送一条消息时,它以一系列悲惨的方式失败了。
我还有其他项目,我想将此电话->邮件->解析->命令系统扩展到其中,但是我需要有一个稳定/可靠/通用的解析器才能从邮件中提取不同的部分以使用它。
我的最终目标是拥有一个可以将原始管道式邮件送入其中的函数,并返回带有标头var:val对的关联子数组的大数组,以及一个用于将正文文本作为整个字符串的数组
我搜索的内容越多,发现到的东西也越多:大型的过度开发的邮件处理软件包,可以在阳光下处理与邮件有关的所有事情,或者是无用的(对我来说,在这个项目中)教程。
我认为我将不得不硬着头皮,只是认真地写一些我自己的东西。
回答
编写自己的MIME解析器可能不会带来很多乐趣。我们发现"邮件处理程序包过度开发"的原因是因为MIME是一组非常复杂的规则/格式/编码。 MIME部分可以是递归的,这很有趣。我认为我们最好的选择是编写最佳的MIME处理程序,解析一条消息,丢弃所有不是text / plain或者text / html的内容,然后强制传入字符串中的命令以COMMAND作为前缀:这样我们就可以在渣土中找到它。如果从这样的规则开始,我们就有机会处理新的提供程序,但是如果有新的提供程序出现,则应该做好调整的准备(如果我们当前的提供程序选择更改其消息传递体系结构,那么应该调整一下)。
回答
我不确定这是否会对我们有所帮助,但一定会帮助有兴趣了解更多有关电子邮件的其他人。 Marcus Bointon在今年3月的PHP伦敦会议上做了题为" Mail()和Mail()之后的生活"的最佳演示之一,幻灯片和MP3都在线。他具有一定的权威性,并在电子邮件和PHP方面进行了广泛的深入研究。
我的看法是,我们在尝试编写一个真正的通用解析器时充满了痛苦。
编辑这些文件似乎已经在PHP London网站上删除了;在Marcus自己的网站上找到了幻灯片:第1部分第2部分尽管在任何地方都看不到MP3
回答
我们可以尝试使用Mailparse函数:http://php.net/manual/en/book.mailparse.php,但是默认情况下不在php conf中。
回答
用PHP解析电子邮件不是不可能的任务。我的意思是,我们不需要团队的工程师来完成它。它可以作为一个个体来实现。我发现最难的部分是创建用于分析IMAP BODYSTRUCTURE结果的FSM。我在互联网上找不到任何地方,所以我写了自己的书。我的例程基本上是从命令输出中创建一个嵌套数组的数组,并且该数组中的深度大约对应于执行查找所需的零件号。因此,它可以很好地处理嵌套的MIME结构。
问题是PHP的默认imap_ *函数不能提供很多粒度...因此我不得不打开IMAP端口的套接字并编写函数以发送和检索必要的信息(IMAP FETCH 1 BODY.PEEK [1.2]例如),这涉及查看RFC文档。
数据的编码(带引号的,base64、7bit,8bit等),消息的长度,内容类型等都已提供给我们。附件,文本,html等。我们可能还必须弄清楚邮件服务器的细微差别,因为并非所有字段都总是100%实现的。
宝石是FSM ...如果我们在Comp Sci中有背景,那么做这个真的很有趣(它们的关键是方括号不是常规语法;));否则,使用传统方法会很麻烦,并且/或者会导致代码难看。我们还需要一些时间!
希望这可以帮助!