在php中解析原始电子邮件

Ube*_*zzy 28 php email

我正在寻找好/工作/简单使用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

我用它来做我的项目.它工作得很好,它只是一个类,它是开源的.

  • 可以确认Plancake是垃圾.似乎在处理从Outlook发送的电子邮件方面表现不佳.五年内没有更新. (2认同)

Car*_*ole 6

我把它拼凑在一起,有些代码不是我的,但我不知道它来自哪里......我后来采用了更强大的“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)