PHP發送有附件的電子郵件

來源:互聯網
上載者:User

我經常聽到這樣一個問題:"我有一個從網站發來的合約。我如何給通過表單發送的電子郵件增加一個附件呢?" 
首先我要說的是要做到這個沒有什麼簡單的辦法。你要很好的理解PHP或其它的伺服器端的指令碼語言。當然你還要一個真正支援PHP的網站的帳號。如果滿足了這個前提,在你讀完了本章後就可以用PHP發送帶附件的電子郵件了。

1. 附件是如何工作的
如果你曾經在PHP的手冊中搜尋過"附件"函數,那麼結果可能是什麼都沒有(至少在我寫本文的時間還沒有)。後來你就要花很多時間來瞭解這方面的知識。
你也許會想當你給某個人發送一封帶附件的電子郵件時,附件是和郵件一起放到收件者的信箱裡的(比如,如果你給他/她發了一個PNG的圖片檔案,他/她的信箱裡會包含一個txt檔案(電子郵件)和一個.png檔案(附件))。但這不是它的工作原理。當你加入一個附件時,你的郵件程式把附件轉換成純文字檔案,並在你寫的內容(實際的電子郵件)後面插入這個文字區塊。這個,當你把所有的東西發出來後,收件者的信箱裡只有一個純文字檔案--一個同時包含附件和實際電子郵件內容的檔案。
下面是一個帶附件(一個HTML檔案)電子郵件的例子:

Return-Path: <someone@example.com> Date: Mon, 22 May 2000 19:17:29 +0000 From: Someone <someone@example.com> To: Person <person@eksempel.dk> Message-id: <83729KI93LI9214@example.com> Content-type: multipart/mixed; boundary="396d983d6b89a" Subject: Here's the subject--396d983d6b89a Content-type: text/plain; charset=iso-8859-1 Content-transfer-encoding: 8bitThis is the body of the email.--396d983d6b89a Content-type: text/html; name=attachment.html Content-disposition: inline; filename=attachment.html Content-transfer-encoding: 8bit<html> <head> <title>The attachment</title> </head> <body> <h2>This is the attached HTML file</h2> </body> </html>

--396d983d6b89a--前面的7行是郵件的頭,其中值得注意的是Content-type頭部分。這個頭告訴郵件程式電子郵件是由一個以上的部分組成的。不含附件的郵件只有一個部分:訊息本身。帶附件的電子通常至少由兩部分組成:訊息和附件。這樣,帶兩個附件的郵件由三部分組成:訊息,第一個附件和第二個附件。

帶附件的電子郵件的不同部分之間用分界線來分隔。分界線在Content-type頭中定義。郵件的每個新部分以兩個連字號(--)和分界線開始。最後一個分界線後也有兩個連字號,表示這個郵件中沒有其它的部分了。
在每個分界線後有一些行,用來告訴郵件程式這個部分的內容的類型。比如,看看上面例子中第一個分界線後面的兩行--以Content-type: text/plain開頭的行。這些行說明後面的部分是ISO-8859-1字元集的純文字。跟在第二個分界線後的行告訴郵件程式現在的部分是一個HTML檔案,它的名字是"attachment.html"。
Content-disposition這持告訴郵件程式如果可能就以內嵌的方式顯示附件。現在新的郵件程式會在訊息後顯示HTML的內容。如果Content-disposition被設為attachment,那麼郵件程式就不會顯示HTML檔案的內容,而是顯示一個串連到檔案的表徵圖(或其它的類似的東西)。收件者要看附件的內容,必須點擊這個表徵圖。一般情況下,如果附件是一些文本(包含HTML),Content-disposition會被設為inline,這是因為現在大部分郵件程式能夠不藉助其它瀏覽器而直接顯示附件(文本)的內容。如果附件不是文本(比片或其它類似的內容),Content-disposition就設為attachment。

2. 用PHP產生帶附件的電子郵件
這裡一個例子,告訴你如果把一個定義好的HTML檔案加為郵件的附件:

<?php # 我們首先寫實際的訊息內容 $emailBody = "This is text that goes into the body of the email.";# 然後我們要作為附件的HTML檔案 $attachment = "<html> <head> <title>The attached file</title> </head> <body> <h2>This is the attached HTML file</h2> </body> </html>";# 建立在郵件中分隔不同部分的分界線。 # 基本上,分界線可以是任意的字串。 # 但是重要的一點是確定一個寫郵件的人 # 這會隨意寫出的字串,所以我們用 # uniqid函數來產生一個隨機的字串。 $boundary = uniqid( "");# 現在我們要建立郵件標頭。不要忘了插入 # Content-type頭來說明這個郵件包含一個或更多的附件。 $headers = "From: someone@example.com Content-type: multipart/mixed; boundary="$boundary"";# 好,現在我們已經有了郵件的所有內容。 # 下一件事是修改郵件的主體。 $emailBody = "--$boundary Content-type: text/plain; charset=iso-8859-1 Content-transfer-encoding: 8bit$emailBody--$boundary Content-type: text/html; name=attachment.html Content-disposition: inline; filename=attachment.html Content-transfer-encoding: 8bit$attachment--$boundary--";# 現在可以把郵件發出去了 mail( "person@eksempel.dk", "The subject", $emailBody, $headers); ?>

 

3. 把使用者上傳的檔案作為附件
你也許會覺得上面的例子難以理解,但下面...。在下面的例子中事情更難了,因為我們要用一個表單讓使用者上傳他們的檔案,並把這個檔案作為我們要發的郵件的附件。麻煩的是我們不能預Crowdsourced Security Testing道檔案的MIME類型。在前面的例子中,我們已經知道該它是一個HTML檔案,所以給這個附件設定Content-type頭是很簡單的。在下面的例子中,MIME類型可能是任意的,因為使用者可能會上傳一個HTML檔案,一個PNG檔案,一個vCard檔案,或者其它的東西。讓我們來看看例子:

<?php # 現在我們來產生表單。在產生可以上傳檔案的表單時,不要忘了把<form>標籤的"enctype"屬性設為"multipart/form-data". echo "<form action='$PHP_SELF' enctype='multipart/form-data' method='post'> "; echo "<input type='text' name='from'><br> "; echo "<input type='text' name='to'><br> "; echo "<input type='text' name='subject'><br> "; echo "<input type='file' name='attachment'><br> "; echo "<textarea name='body'></textarea><br> "; echo "<input type='submit' name='send' value='Send'> "; echo "</form> ";# 如果使用者已經按了"Send"按鈕" if ($send) { # 定義分界線 $boundary = uniqid( "");# 產生郵件標頭 $headers = "From: $from Content-type: multipart/mixed; boundary="$boundary"";# 確定上傳檔案的MIME類型 if ($attachment_type)     $mimeType = $attachment_type; # 如果瀏覽器沒有指定檔案的MIME類型, # 我們可以把它設為"application/unknown". else     $mimeType = "application/unknown";# 確定檔案的名字 $fileName = $attachment_name;# 開啟檔案, 把整個檔案讀入一個變數 $fp = fopen($attachment, "r");$read = fread($fp, filesize($attachment));# 好,現在變數$read中儲存的是包含整個檔案內容的文字區塊。 # 現在我們要把這個文字區塊轉換成郵件程式可以讀懂的格式 # 我們用base64方法把它編碼 $read = base64_encode($read);# 現在我們有一個用base64方法編碼的長字串。 # 下一件事是要把這個長字串切成由每行76個字元組成的小塊 $read = chunk_split($read);# 現在我們可以建立郵件的主體 $body = "--$boundary Content-type: text/plain; charset=iso-8859-1 Content-transfer-encoding: 8bit$body--$boundary Content-type: $mimeType; name=$fileName Content-disposition: attachment; filename=$fileName Content-transfer-encoding: base64$read--$boundary--";# 發送郵件 mail($to, $subject, $body, $headers); } ?> 
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.