Php 如何从多部分电子邮件中获取文本内容?
那么,我如何才能将电子邮件的纯文本区域输入到我的文件或脚本中,以便进一步处理Php 如何从多部分电子邮件中获取文本内容?,php,email-parsing,Php,Email Parsing,那么,我如何才能将电子邮件的纯文本区域输入到我的文件或脚本中,以便进一步处理 提前谢谢。stackoverflow很棒 要隔离电子邮件正文的纯文本部分,您必须采取四个步骤: 1。获取MIME边界字符串 我们可以使用正则表达式搜索标题(假设它们位于单独的变量中,$headers): 正则表达式将搜索包含边界字符串的内容类型标题,然后将其捕获到第一个标题中。然后将捕获组复制到变量$boundary中 2。将电子邮件正文拆分为多个部分 一旦我们有了边界,我们就可以将正文分割成不同的部分(在您的消息正文
提前谢谢。stackoverflow很棒 要隔离电子邮件正文的纯文本部分,您必须采取四个步骤: 1。获取MIME边界字符串 我们可以使用正则表达式搜索标题(假设它们位于单独的变量中,
$headers
):
正则表达式将搜索包含边界字符串的内容类型
标题,然后将其捕获到第一个标题中。然后将捕获组复制到变量$boundary
中
2。将电子邮件正文拆分为多个部分
一旦我们有了边界,我们就可以将正文分割成不同的部分(在您的消息正文中,每次出现正文时,正文的前面都会有--
)。根据该协议,第一个边界之前的所有内容都应忽略
$matches = array();
preg_match('#Content-Type: multipart\/[^;]+;\s*boundary="([^"]+)"#i', $headers, $matches);
list(, $boundary) = $matches;
这将给我们留下一个包含所有线段的数组,忽略第一个边界之前的所有内容
3。确定哪一段是纯文本。
纯文本段将有一个MIME类型为text/plain的内容类型
标题。现在,我们可以在每个段中搜索具有该标题的第一个段:
$email_segments = explode('--' . $boundary, $message);
array_shift($email_segments); // drop everything before the first boundary
因为我们寻找的是一个常量,所以我们可以使用(在字符串中查找子字符串的第一个实例,不区分大小写)而不是正则表达式。如果找到内容类型
标题,我们就得到了片段
4。从段中删除任何标题
现在我们需要从找到的段中删除任何头,因为我们只需要实际的消息内容。这里可以显示四种类型:内容类型
,正如我们前面看到的,内容ID
,内容处置
和内容传输编码
。标头由\r\n
终止,因此我们可以使用它来确定标头的结尾:
foreach ($email_segments as $segment)
{
if (stristr($segment, "Content-Type: text/plain") !== false)
{
// We found the segment we're looking for!
}
}
正则表达式末尾的s
使点与任何换行符匹配*?
将收集尽可能少的字符(即\r\n
之前的所有字符);?
是一个打开的*
在这一点之后,$text
将包含您的电子邮件内容
因此,要将其与您的代码结合起来:
$text = preg_replace('/Content-(Type|ID|Disposition|Transfer-Encoding):.*?\r\n/is', "", $segment);
有一个答案:
您只需更改以下两行:
<?php
// read from stdin
$fd = fopen("php://stdin", "r");
$email = "";
while (!feof($fd))
{
$email .= fread($fd, 1024);
}
fclose($fd);
$matches = array();
preg_match('#Content-Type: multipart\/[^;]+;\s*boundary="([^"]+)"#i', $email, $matches);
list(, $boundary) = $matches;
$text = "";
if (isset($boundary) && !empty($boundary)) // did we find a boundary?
{
$email_segments = explode('--' . $boundary, $email);
foreach ($email_segments as $segment)
{
if (stristr($segment, "Content-Type: text/plain") !== false)
{
$text = trim(preg_replace('/Content-(Type|ID|Disposition|Transfer-Encoding):.*?\r\n/is', "", $segment));
break;
}
}
}
// At this point, $text will either contain your plain text body,
// or be an empty string if a plain text body couldn't be found.
$savefile = "savehere.txt";
$sf = fopen($savefile, 'a') or die("can't open file");
fwrite($sf, $text);
fclose($sf);
?>
这是完整的电子邮件吗?它缺少内容类型:multipart/mixed
标题,该标题应指定边界字符串是什么(找到的代码需要该字符串)。这只是保存到文件中的电子邮件的一部分。这是我使用第一个代码示例所能得到的最简单的信息。边界标头对于能够解析电子邮件非常重要,因为它指定了电子邮件的每个部分的开始和结束位置。没有它,你所能做的就是猜测,你知道他们怎么说假设…;)例如,对于您引用的电子邮件,应该有如下标题:Content-Type:multipart/mixed;boundary=“----=\u NextPart_000_0163_01CB4EA5.46466520”
来自不同的基于pc的电子邮件客户端或流行的免费电子邮件帐户的边界是相同的吗?我将标题变量添加到文件中并编辑了我的问题,以便为你们这些家伙/女孩添加这些信息……我想,我开始理解了。。所以,为了测试我会在//空变量之后替换所有内容吗???不完全是。这取决于您想做什么(例如,您可能希望继续拆分头或收集“特殊”头)。我的代码要求您有一个标题文本块和一个消息文本块,但您可以将我代码中的$headers
和$message
替换为$email
,根据您的代码,它应该包含整个电子邮件。啊,我不明白!如何在上面的代码示例中实现这一点,以便对其进行测试?我能把你的片段放在写文件之前吗?然后写$text而不是$message?我真的很感谢你对这个初学者的帮助和耐心。我更新了我的代码,以便在电子邮件中阅读(按照你的代码)并处理它。我的代码片段应该按照您想要的方式工作,而无需进行任何修改。如果你想对这封邮件做任何其他的事情,我将把它留给你(或者你可以在这里问另一个问题以获得进一步的帮助)。这是一篇旧文章,但我想我会根据我发现的一个bug添加一个快速更新。在步骤3中,我发现正则表达式与多部分头不匹配,因为它们后面并不总是有回车符。如果您删除该preg中的“\r”,我相信它适用于所有情况(因为如果有,它将被“*?”捕获)。因此,新的一个看起来像$text=trim(preg|u replace('/Content-(Type | ID | Disposition | Transfer-Encoding):.*?\n/is',“”,$segment))@詹姆斯·加里斯不再(在撰写本评论时)
foreach ($email_segments as $segment)
{
if (stristr($segment, "Content-Type: text/plain") !== false)
{
// We found the segment we're looking for!
}
}
$text = preg_replace('/Content-(Type|ID|Disposition|Transfer-Encoding):.*?\r\n/is', "", $segment);
<?php
// read from stdin
$fd = fopen("php://stdin", "r");
$email = "";
while (!feof($fd))
{
$email .= fread($fd, 1024);
}
fclose($fd);
$matches = array();
preg_match('#Content-Type: multipart\/[^;]+;\s*boundary="([^"]+)"#i', $email, $matches);
list(, $boundary) = $matches;
$text = "";
if (isset($boundary) && !empty($boundary)) // did we find a boundary?
{
$email_segments = explode('--' . $boundary, $email);
foreach ($email_segments as $segment)
{
if (stristr($segment, "Content-Type: text/plain") !== false)
{
$text = trim(preg_replace('/Content-(Type|ID|Disposition|Transfer-Encoding):.*?\r\n/is', "", $segment));
break;
}
}
}
// At this point, $text will either contain your plain text body,
// or be an empty string if a plain text body couldn't be found.
$savefile = "savehere.txt";
$sf = fopen($savefile, 'a') or die("can't open file");
fwrite($sf, $text);
fclose($sf);
?>
require_once('/path/to/class/rfc822_addresses.php');
require_once('/path/to/class/mime_parser.php');