我正在寻找好/工作/简单使用PHP代码将原始电子邮件解析为部分.
我已经编写了几个强力解决方案,但每次都会出现一个小的更改/标题/空格/一些东西,我的整个解析器都会失败并且项目会崩溃.
在我指出PEAR/PECL之前,我需要实际的代码.我的主机有一些棘手的配置或东西,我似乎永远不会得到.so的构建正确.如果我确实得到了.so,那么path/environment/php.ini中的一些区别并不总是让它可用(apache vs cron vs cli).
哦,最后一件事,我正在解析原始电子邮件文本,而不是POP3,而不是IMAP.它通过.qmail电子邮件重定向传输到php脚本.
我不期待SOF为我写这篇文章,我正在寻找一些关于"正确"做的提示/起点.这是我知道已经解决的那些"轮子"问题之一.
jj3*_*j33 21
你最终希望最终得到什么?身体,主体,发件人,附件?您应该花一些时间与RFC2822一起了解邮件的格式,但这里是格式良好的电子邮件最简单的规则:
HEADERS\n
\n
BODY
Run Code Online (Sandbox Code Playgroud)
也就是说,第一个空白行(双换行符)是HEADERS和BODY之间的分隔符.HEADER看起来像这样:
HSTRING:HTEXT
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
大多数现代电子邮件比这更复杂.标题可以编码为字符集或RFC2047 mime字,或者其他很多我现在没想到的东西.如果您希望它们有意义,那么这些天的机构真的很难推出自己的代码.几乎所有由MUA生成的电子邮件都将进行MIME编码.这可能是uuencoded文本,它可能是html,它可能是一个uuencoded excel电子表格.
我希望这有助于提供一个框架来理解一些非常基本的电子邮件桶.如果您提供更多有关您尝试处理数据的背景信息,我(或其他人)可能会提供更好的指导.
dan*_*dan 18
尝试使用Plancake PHP电子邮件解析器:https: //github.com/plancake/official-library-php-email-parser
我用它来做我的项目.它工作得很好,它只是一个类,它是开源的.
我把它拼凑在一起,有些代码不是我的,但我不知道它来自哪里......我后来采用了更强大的“MimeMailParser”,但这工作正常,我使用 cPanel 将我的默认电子邮件发送给它,它工作正常伟大的。
#!/usr/bin/php -q
<?php
// Config
$dbuser = 'emlusr';
$dbpass = 'pass';
$dbname = 'email';
$dbhost = 'localhost';
$notify= 'services@.com'; // an email address required in case of errors
function mailRead($iKlimit = "")
{
// Purpose:
// Reads piped mail from STDIN
//
// Arguements:
// $iKlimit (integer, optional): specifies after how many kilobytes reading of mail should stop
// Defaults to 1024k if no value is specified
// A value of -1 will cause reading to continue until the entire message has been read
//
// Return value:
// A string containing the entire email, headers, body and all.
// Variable perparation
// Set default limit of 1024k if no limit has been specified
if ($iKlimit == "") {
$iKlimit = 1024;
}
// Error strings
$sErrorSTDINFail = "Error - failed to read mail from STDIN!";
// Attempt to connect to STDIN
$fp = fopen("php://stdin", "r");
// Failed to connect to STDIN? (shouldn't really happen)
if (!$fp) {
echo $sErrorSTDINFail;
exit();
}
// Create empty string for storing message
$sEmail = "";
// Read message up until limit (if any)
if ($iKlimit == -1) {
while (!feof($fp)) {
$sEmail .= fread($fp, 1024);
}
} else {
while (!feof($fp) && $i_limit < $iKlimit) {
$sEmail .= fread($fp, 1024);
$i_limit++;
}
}
// Close connection to STDIN
fclose($fp);
// Return message
return $sEmail;
}
$email = mailRead();
// handle email
$lines = explode("\n", $email);
// empty vars
$from = "";
$subject = "";
$headers = "";
$message = "";
$splittingheaders = true;
for ($i=0; $i < count($lines); $i++) {
if ($splittingheaders) {
// this is a header
$headers .= $lines[$i]."\n";
// look out for special headers
if (preg_match("/^Subject: (.*)/", $lines[$i], $matches)) {
$subject = $matches[1];
}
if (preg_match("/^From: (.*)/", $lines[$i], $matches)) {
$from = $matches[1];
}
if (preg_match("/^To: (.*)/", $lines[$i], $matches)) {
$to = $matches[1];
}
} else {
// not a header, but message
$message .= $lines[$i]."\n";
}
if (trim($lines[$i])=="") {
// empty line, header section has ended
$splittingheaders = false;
}
}
if ($conn = @mysql_connect($dbhost,$dbuser,$dbpass)) {
if(!@mysql_select_db($dbname,$conn))
mail($email,'Email Logger Error',"There was an error selecting the email logger database.\n\n".mysql_error());
$from = mysql_real_escape_string($from);
$to = mysql_real_escape_string($to);
$subject = mysql_real_escape_string($subject);
$headers = mysql_real_escape_string($headers);
$message = mysql_real_escape_string($message);
$email = mysql_real_escape_string($email);
$result = @mysql_query("INSERT INTO email_log (`to`,`from`,`subject`,`headers`,`message`,`source`) VALUES('$to','$from','$subject','$headers','$message','$email')");
if (mysql_affected_rows() == 0)
mail($notify,'Email Logger Error',"There was an error inserting into the email logger database.\n\n".mysql_error());
} else {
mail($notify,'Email Logger Error',"There was an error connecting the email logger database.\n\n".mysql_error());
}
?>
Run Code Online (Sandbox Code Playgroud)