PHP發送郵件之頭頭是道完全釋疑

火星人 @ 2014-03-12 , reply:0
←手機掃碼閱讀

  

站應用中向客戶發送郵件是常見的一個功能。SMTP協議貌似簡單,而且資料繁多,但要徹底搞清楚客戶端伺服器之間的身份和關係處理,也不是件容易的事。

本文簡明扼要對smtp交換過程中身份和條件進行說明,使初次接觸smtp開發的能有個清晰的處理思路。錯誤之處請多指正。

先說說smtp的基本原理, 郵件客戶端(outlook)和發送方smtp伺服器之間,  發送方smtp伺服器和接受方smtp伺服器之間,走的都是smtp協議.

先說說我們最常見的情況:用outlook發郵件,從 www.linuxidc@linuxidc.com 發往 www.linuxidc.net@linuxidc.net。 outlook里寫好郵件后發送,會連接到帳號里登記的smtp伺服器25埠,開始smtp會話:

   mail from:

linuxidc.com伺服器發現郵件的mail from 是本域的(linuxidc.com),這種情況下smtp伺服器一般需要驗證用戶身份,驗證通過提交郵件,郵件進入伺服器的發送隊列。 伺服器投遞郵件的進程或線程,掃描發送隊列,取出郵件後分析要往哪發。 伺服器發現郵件是發往 linuxidc.net,不是本域,先通過dns伺服器查詢 linuxidc.net域的mx記錄,假設為 smtp.linuxidc.net,郵件投遞進程連接 smtp.linuxidc.net 的25埠,開始smtp會話

   mail from:

linuxidc.net伺服器判斷郵件是來自別的域,發往本域,所以不需要驗證用戶。不過有可能的情況是linuxidc.net伺服器先檢查一下發信伺服器的ip地址,和mail from 里的域名對應的mx記錄是否匹配,不匹配的拒收。如果沒有符合什麼拒收條件,那麼linuxidc.net手下這封信,放入rose的郵件夾,rose可以通過pop3收取郵件。

如果 linuxidc.com發送郵件失敗的話,郵件進入發送失敗隊列,可能直接扔掉,或者再試著重發n次,如果都不成功,會通知發件人或別的什麼,這要看伺服器的處理。

現在再說說php發郵件,首先要搞清楚,要用什麼身份發送郵件。第一種:把自己當作outlook之類的客戶端,先連到發信伺服器,提交郵件后讓發件伺服器往外發送。第二種:把自己當作發信伺服器,直接通過smtp連接收件人的伺服器發送郵件。

這裡我不推薦第二種方式,原因是:如果你php所在伺服器的域名,ip,mx記錄沒有嚴格設置好的話,一般收件伺服器有很大的幾率會拒收;發送郵件本身的傳輸過程時間無法控制,如果和收件伺服器有很大的延時,會嚴重影響自己的web伺服器的工作,另外也不具有失敗重發等處理。

對於發送郵件,windows和unix和很大的差別。windows一般來說都是像outlook那樣的方式,用smtp協議連到發件伺服器發送郵件。unix有自己的傳統方式,就是unix主機自帶 smtp server,傳統的就是sendmail。另外還有個“sendmail”的概念,這裡說的是一個程序的名字,無論是sendmail,qmail,postfix等等,都提供這個命令程序,通過它,可以把郵件放入本地郵件發送隊列,讓sendmail,qmail,postfix之類的投遞程序去投遞發送。sendmail程序一般是從標準輸入里讀入郵件內容。php的mail()函數實際上會打開sendmail程序,通過標準輸入把郵件內容傳給它,由sendmail程序來發送,剩下的就不管了。

所以大家可以看到,php里關於mail() 這個函數的說明,如果是在windows上,一般是設置 php.ini里 SMTP 和 smtp_port 選項的值,通過類outlook客戶端的方式發送,但是這種方式的致命弱點是不支持smtp驗證,而現在郵件伺服器基本都是需要smtp驗證的。uxni下一般需要設置 sendmail_path ,來說明sendmail程序的路徑。當然windows上也可以用sendmail程序發送。

如果是unix,最理想的情況是,你的php所在的web伺服器本身也是個smtp server,並設置好了mx記錄等等,或者你有個能發送郵件的sendmail程序(自己寫,封裝smtp發送)那麼先配置好 php.ini 里的sendmail_path,通過mail()函數就直接發送了。

如果沒有能用的sendmail程序,那麼就要通過socket 用smtp協議發送了,php這方面有很多擴展的庫,可以直接拿來用。建議連上一個伺服器讓他幫你發,不建議直接連收件伺服器(原因前面說了)。這裡還有就是不建議直接在網頁上php里連接發送,推薦的方式是把郵件寫到資料庫或文件里,讓另一個程序(php,perl,python 都可以寫)掃描后通過sokcet連接發送。這樣既給用戶有了好的響應體驗,也可以控制發送的過程。






[火星人 via ] PHP發送郵件之頭頭是道完全釋疑已經有191次圍觀

http://www.coctec.com/docs/net/show-post-68209.html