标题几乎说明了一切,但我会尝试将这个问题充实。
我的PHP应用程序需要从套接字读取电子邮件(这是一项要求),然后使用其中一些电子邮件(具有api令牌)作为应用程序中的文章(它是一个cms)。 / p>
我已经能够让阅读部分有所进展,但现在我们仍然坚持解析它们;具体来说,我们的问题是,我可能收到的电子邮件将在99%的时间内显示如下:
MIME-Version: 1.0\r\n
Received: by {ip_number} with {protocol}; {iso_date}\r\n
Date: {iso_date}\r\n
Delivered-To: {destination}\r\n
Message-ID: {sample_message_id}\r\n
Subject: {subject}\r\n
From: {sender}\r\n
To: {destination}\r\n
Content-Type: multipart/mixed; boundary={sample_boundary}\r\n
\r\n
--{sample_boundary}\r\n
Content-Type: multipart/alternative; boundary={sample_boundary_2}\r\n
\r\n
--{sample_boundary_2}\r\n
Content-Type: text/plain; charset={charset}\r\n
\r\n
{file_content}\r\n
--\r\n
{signature}\r\n
\r\n
--{sample_boundary_2}\r\n
Content-Type: text/html; charset={charset}\r\n
\r\n
{content_html}\r\n
{signature_html}\r\n
--{sample_boundary_2}--\r\n
--{sample_boundary}\r\n
Content-Type: image/jpeg; name="{file_name}"\r\n
Content-Disposition: attachment; filename="{file_name}"\r\n
Content-Transfer-Encoding: base64\r\n
X-Attachment-Id: {sample_attachment_id}\r\n
\r\n
{quoted_printable_file_contents}\r\n
--{sample_boundary}--\r\n
虽然我一直试图将它们重新出现,但我根本无法做到。标准电子邮件 应该在\n
中结束他们的行,但是某些do in \r\n
与嵌套相结合的事实对我来说太过分了。
PHPClasses中有一个库将电子邮件分成MIME部分(以及其他一些东西),由一些Manuel Lemos家伙编写,他清楚地知道自己在做什么,因为它非常有效并且返回格式和解析得很好,但它并没有为我减少。
图书馆本身由+2500行无法理解的乱码组成,我无法理解(它用3种不同的camelCases编写,并使用各种缩进样式以及不同类型的ifs(如if():
和{ {1}}和if()
以及if(){}
,for(;;)
和for(){}
之类的循环并不会让它变得更简单)
有人请在这里帮忙吗?
非常感谢!
- 已编辑添加
按照Sjoern的建议,我开始为自己的问题建立解决方案(谢谢!!)。我仍然愿意接受更多建议;肯定有更好的方法来做到这一点)
for():
答案 0 :(得分:1)
创建一个解析消息并递归调用它的函数。
首先,解析整个消息。如果你遇到这个:
Content-Type: multipart/mixed; boundary={sample_boundary}
在{sample_boundary}
上拆分邮件。然后解析每个子消息。
function parseMessage($message) {
// Put some code here to determine the split
$messages = explode($boundary, $message);
$result = array();
foreach ($messages as $message) {
$result[] = parseMessage($message);
}
return $result;
}
答案 1 :(得分:0)
我知道这个问题已经过时了,但我不得不为没有IMAP和没有PEAR的附加PDF(廉价主机)做到这一点。
这段代码接收原始电子邮件消息(在$ email中),查看附件的消息,如果找到附件,则将其解压缩,解码并保存。我会添加一些检查以确保附件是您想要的类型 - 例如'pdf'。
适用于从gmail发送的base64 pdf附件 - 尚未测试任何其他内容。编辑:现已测试并使用来自雅虎的电子邮件。
(对不起,线条有点长,因为我没有把所有东西都变成变量)。
使用MAILPARSER功能http://php.net/manual/en/ref.mailparse.php
//TAKES A RAW MESSAGE $email AND FINDS PART WITH ATTACHMENT, CROPS OUT ATTACHMENT, DECODES, SAVES.
$mailparse = mailparse_msg_create();
mailparse_msg_parse($mailparse,$email);
$structure = mailparse_msg_get_structure($mailparse);
foreach($structure as $structurepart) {
//THIS IS THE MODIFIED LINE TO CHECK FOR AN ATTACHMENT THAT IS A PDF
//if (mailparse_msg_get_part_data(mailparse_msg_get_part($mailparse, $structurepart))['content-disposition']==='attachment' && mailparse_msg_get_part_data(mailparse_msg_get_part($mailparse, $structurepart))['content-type']==='application/pdf' )
if (mailparse_msg_get_part_data(mailparse_msg_get_part($mailparse, $structurepart))['content-disposition']==='attachment') {
$startingposition = mailparse_msg_get_part_data(mailparse_msg_get_part($mailparse, $structurepart))['starting-pos-body'];
$length = mailparse_msg_get_part_data(mailparse_msg_get_part($mailparse, $structurepart))['ending-pos-body'] - mailparse_msg_get_part_data(mailparse_msg_get_part($mailparse, $structurepart))['starting-pos-body'];
$filenameasreceived = mailparse_msg_get_part_data(mailparse_msg_get_part($mailparse, $structurepart))['disposition-filename'];
$mime_pdf = substr( $email, $startingposition,$length);
$mime_pdf = base64_decode($mime_pdf);
/* Saves the data into a file */
$fdw = fopen('/home/[userfolder]/public_html/'. $filenameasreceived, "w+");
fwrite($fdw, $mime_pdf);
fclose($fdw);
/* Script End */
echo "<br>file saved.";
}
}
答案 2 :(得分:0)
我必须在以下函数中将14更改为13才能使其正常工作:
protected function hasContentType($string){
return strtolower(trim(substr($string,0,13))) == 'content-type';
}