6

我正在开发一个需要从电子邮件服务器检索任意电子邮件的 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--
4

5 回答 5

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 的回答)。

于 2014-05-21T11:16:17.180 回答
0

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

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

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

您也可以使用脚本与邮件服务器交谈,以发送emls带有模板正文的邮件。

于 2014-05-21T16:02:43.473 回答
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);
于 2014-05-14T21:17:18.680 回答
0

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

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

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

于 2011-02-18T17:06:58.110 回答
0

您可以只使用 PHP 中的构建函数mailbody零件不必只是文本,它还可以包含混合零件数据。

请记住,这是一个概念证明。该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. 我不得不使用单独的工具来创建文件,因为默认情况下您无法.eml使用 Outlook 保存。

您可以下载邮件脚本的示例。它包含两个版本。

简单版有两个文件,一个是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");
?>
于 2014-05-15T09:41:31.507 回答