从原始身体发送邮件用于测试目的

时间:2011-02-18 17:00:47

标签: php email testing eml

我正在开发一个需要从电子邮件服务器检索任意电子邮件的PHP应用程序。然后,消息被完全解析并存储在数据库中。

当然,我必须做很多测试,因为这项任务对于阳光下所有不同的邮件格式来说并不是真的微不足道。因此,我开始“收集”来自某些客户并具有不同内容的电子邮件。

我想要一个脚本,以便我可以自动将这些电子邮件发送到我的应用程序以测试邮件处理。

因此,我需要一种方法来发送原始电子邮件 - 这样结构与它们来自相应客户端的结构完全相同。我将电子邮件存储为.eml文件。

有人知道如何通过提供原始身体来发送电子邮件吗?

修改 更具体一点:我正在寻找一种使用源代码发送多部分电子邮件的方法。例如,我希望能够使用类似的东西(带有普通和HTML部分的电子邮件,HTML部分有一个内联附件)。

 --Apple-Mail-159-396126150
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;

The plain text email!

--=20    

=20
=20

--Apple-Mail-159-396126150
Content-Type: multipart/related;
    type="text/html";
    boundary=Apple-Mail-160-396126150


--Apple-Mail-160-396126150
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html;
    charset=iso-8859-1

<html><head>
    <title>Daisies</title>=20
</head><body style=3D"background-attachment: initial; background-origin: =
initial; background-image: =
url(cid:4BFF075A-09D1-4118-9AE5-2DA8295BDF33/bg_pattern.jpg); =
background-position: 50% 0px; ">

[ - snip - the html email content ]


</body></html>=

--Apple-Mail-160-396126150
Content-Transfer-Encoding: base64
Content-Disposition: inline;
    filename=bg_pattern.jpg
Content-Type: image/jpg;
    x-apple-mail-type=stationery;
    name="bg_pattern.jpg"
Content-Id: <4BFF075A-09D1-4118-9AE5-2DA8295BDF33/tbg.jpg>

/9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAASAAA/+IFOElDQ19QUk9GSUxFAAEB
[ - snip - the image content ]
nU4IGsoTr47IczxmCMvPypi6XZOWKYz/AB42mcaD/9k=

--Apple-Mail-159-396126150--

5 个答案:

答案 0 :(得分:0)

使用PHPMailer,您可以直接设置邮件正文:

$mail->Body = 'the contents of one of your .eml files here'

如果你的邮件包含任何mime附件,这很可能无法正常工作,因为一些MIME内容必须进入邮件的标题。你必须按摩.eml来提取那些特定的标题,并将它们作为自定义标题添加到PHPMailer邮件中

答案 1 :(得分:0)

您可以使用telnet程序发送这些电子邮件:

$ telnet <host> <port>                  // execute telnet
HELO my.domain.com                      // enter HELO command
MAIL FROM: sender@address.com           // enter MAIL FROM command
RCPT TO: recipient@address.com          // enter RCPT TO command
<past here, without adding a newline>   // enter the raw content of the message
[ctrl]+d                                // hit [ctrl] and d simultaneously to end the message

如果您真的想在PHP中执行此操作,可以使用fsockopen()stream_socket_client()系列。基本上你做同样的事情:直接与邮件服务器交谈。

// open connection
$stream = @stream_socket_client($host . ':' . $port);

// write HELO command
fwrite($stream, "HELO my.domain.com\r\n");

// read response
$data = '';
while (!feof($stream)) {
    $data += fgets($stream, 1024);
}

// repeat for other steps
// ...

// close connection
fclose($stream);

答案 2 :(得分:0)

您可以使用PHP函数mail中的构建。 body部分不一定只是文本,它也可以包含混合部分数据。

请记住,这是一个概念证明。 sendEmlFile函数可以使用更多检查,例如“文件是否存在”和“它是否有边界集”。正如你所提到的,它是用于测试/开发的,我没有把它包括在内。

<?php
function sendmail($body,$subject,$to, $boundry='') {
  define ("CRLF", "\r\n");

  //basic settings
  $from = "Example mail<info@example.com>";

  //define headers
  $sHeaders  = "From: ".$from.CRLF;
  $sHeaders .= "X-Mailer: PHP/".phpversion().CRLF;
  $sHeaders .= "MIME-Version: 1.0".CRLF;


  //if you supply a boundry, it will be send with your own data
  //else it will be send as regular html email
    if (strlen($boundry)>0)
        $sHeaders .= "Content-Type: multipart/mixed; boundary=\"".$boundry."\"".CRLF;
    else
    {
      $sHeaders .= "Content-type: text/html;".CRLF."\tcharset=\"iso-8859-1\"".CRLF;
      $sHeaders .= "Content-Transfer-Encoding: 7bit".CRLF."Content-Disposition: inline";
    }

  mail($to,$subject,$body,$sHeaders);
}

function sendEmlFile($subject, $to, $filename) {
  $body = file_get_contents($filename);
  //get first line "--Apple-Mail-159-396126150"
  $boundry = $str = strtok($body, "\n");

  sendmail($body,$subject,$to, $boundry);
}
?>

<强>更新

经过一些测试后,我发现所有.eml文件都不同。可能有一个标准,但在导出到.eml时我有很多选项。我不得不使用单独的工具来创建文件,因为默认情况下使用outlook无法保存到.eml

您可以下载example of the mail script。它包含两个版本。

简单版本有两个文件,一个是发送index.php文件的test.eml文件。这只是我粘贴在您在问题中发布的示例代码中的文件。

高级版使用我创建的实际.eml文件发送电子邮件。它会自己从文件中获取所需的标题。请注意,这也会设置邮件的ToFrom部分,因此请将其更改为与您自己/服务器设置相匹配。

高级代码的工作原理如下:

<?php
function sendEmlFile($filename) {
    //define a clear line
    define ("CRLF", "\r\n");

    //eml content to array.
    $file = file($filename);

    //var to store the headers
    $headers = "";
    $to = "";
    $subject = "";

    //loop trough each line
    //the first part are the headers, until you reach a white line
    while(true) {
        //get the first line and remove it from the file
        $line = array_shift($file);
        if (strlen(trim($line))==0) {
            //headers are complete
            break;
        }

        //is it the To header
        if (substr(strtolower($line), 0,3)=="to:") {
            $to = trim(substr($line, 3));
            continue;
        }

        //Is it the subject header
        if (substr(strtolower($line), 0,8)=="subject:") {
            $subject = trim(substr($line, 8));
            continue;
        }

        $headers .= $line . CRLF;
    }

    //implode the remaining content into the body and trim it, incase the headers where seperated with multiple white lines
    $body = trim(implode('', $file));

    //echo content for debugging
    /*
    echo $headers;
    echo '<hr>';
    echo $to;
    echo '<hr>';
    echo $subject;
    echo '<hr>';
    echo $body;
    */

  //send the email
  mail($to,$subject,$body,$headers);
}


//initiate a test with the test file
sendEmlFile("Test.eml");
?>

答案 3 :(得分:0)

你可以从这里开始

http://www.dreamincode.net/forums/topic/36108-send-emails-using-php-smtp-direct/

我不知道代码有多好,但它会成为一个起点。

您正在做的是直接连接到远程计算机上的端口25,就像使用telnet一样,并发出smtp命令。请参阅例如http://www.yuki-onna.co.uk/email/smtp.html了解正在发生的事情(或参见Jasper N. Brouwer的回答)。

答案 4 :(得分:0)

只需制作一个快速的shell脚本来处理目录并在需要时调用它。使用at crontab

我在ls /mydir/cat I | awk .. | sendmail -options

http://www.manpagez.com/man/1/awk/

你也可以使用脚本与邮件服务器通话,发送带有模板化身体的emls ..