2011-02-18 155 views
5

我正在開發一個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-- 
+0

你有沒有找到解決這個問題的辦法? – Johannes 2013-04-30 08:04:55

+0

不,不幸的不是。 – hbit 2013-04-30 22:46:36

+0

我認爲你錯過了主要部分,與標題標題,並與多部分,所以你的MTA會知道該怎麼做。因此你的.eml文件是不完整的。在多部分電子郵件中,根部分(缺少的部分)必須包含這樣的內容:「Content-Type:multipart/alternative; boundary =」____ = = _ MCPart_465790590「」。這將指定任何mimeparser至此首先閱讀,依此類推。 – 2014-05-21 11:14:27

回答

0

使用PHPMailer,您可以直接設置郵件的正文:

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

如果您的郵件包含任何MIME附件,這將很可能無法正常工作,因爲一些MIME東西都有進入郵件的標題。你不得不按摩的.eml提取那些特定的標題,並將它們添加到PHPMailer的郵件作爲customheader

+0

不幸的是,這並沒有多大幫助。例如,一個有趣的測試案例是Apple Mail中的附件通常具有「內聯」處置,而大多數其他客戶端只使用「附件」。因此,我想發送如下內容: - Apple-Mail-4-698704782 內容處置:內聯; \t filename =「bla.pdf」 .... 我知道某些頭文件也需要進入新郵件,但這應該不是一個大問題:只過濾重要的東西(收到的,發件人,...),並再次使用剩餘的標題字段。 – hbit 2011-02-18 17:46:38

0

你可以只使用telnet程序來發送這些郵件:

$ telnet <host> <port>     // execute telnet 
HELO my.domain.com      // enter HELO command 
MAIL FROM: [email protected]   // enter MAIL FROM command 
RCPT TO: [email protected]   // 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); 
0

您可以在PHP函數mail中使用它。 body部分不一定只是文本,它也可以包含混合部分數據。

請記住,這是一個概念證明。 sendEmlFile函數可以使用一些更多的檢查,如「文件是否存在」和「是否有邊界設置」。正如你所提到的,它是用於測試/開發的,我沒有包括它。

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

    //basic settings 
    $from = "Example mail<[email protected]>"; 

    //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"); 
?> 
0

只需製作一個快速shell腳本來處理一個目錄,並在需要時調用它。使用atcrontab

,因爲我在做ls /mydir/cat I | awk .. | sendmail -options

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

你也可以只使用腳本來發送emls用模板身體聊到郵件服務器..