phpmailer是用php作的一個郵件發送的組件,而163是專業作郵件的大的運營商,這二者之間有什麼瓜葛呢?且聽我細細道來.
筆者基於phpmailer作了個發郵件的小程序,可是給相似"test@vip.163.com"這樣的郵件地址發郵件的時候總會收到這樣的錯誤:"You must provide at least one recipient email address.".開始覺得是郵件服務器有問題,結果去服務器看日誌,居然沒有相關的信息,也就是說確定是程序的問題.網上找了半天也沒有找到什麼有價值的信息,卻是有位同窗說也遇到一樣的問題,不過本身解決了.解決辦法是本身看的代碼,也沒提供怎麼解決的,鬱悶.看來要本身動手了.
雖然用php快一年了,可是對於phpmailer的這樣很規範的代碼我還沒敢研究過.既然有同窗經過讀代碼解決問題了,我也試試唄,誰讓咱也以phper自居呢.經過關鍵字搜索,很快就將問題定位到了class.phpmailer.php的523行.
523 public static function ValidateAddress($address) {
524 if (function_exists('filter_var')) { //Introduced in PHP 5.2
525 if(filter_var($address, FILTER_VALIDATE_EMAIL) === FALSE) {
526 return false;
527 } else {
528 return true;
529 }
530 } else {
531 return preg_match('/^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[a-zA- Z0-9_](?:[a-zA-Z0-9_\-](?!\.)){0,61}[a-zA-Z0-9_-]?\.)+[a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!$)){0,61}[a-zA-Z0-9_]?)|(?:\[(?:(?:[01]?\d{1, 2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/', $address);
532 }
533 }
從字面上就能夠看出這段是用來驗證郵件地址有效性的.php先判斷是否是有內置函數filter_var,若是沒有的話就用perl正則驗證郵件.網上找了一下,發現php在5.2之後提供了filter_var用來驗證郵件地址有效性.因而手工用filter_var驗證了一下"test@vip.163.com",果真不經過!問題找到了,怎麼解決呢?最簡單的,能夠直接把if這一段直接刪除,全部的郵件地址都走perl正則驗證,可是考慮到perl正則的效率,決定不用這個辦法.既然filter_var檢查vip.163.com的郵件會失敗,那就在失敗的時候加個判斷吧.因而把526行,替換成以下內容.
526 if(strpos(strtolower($address),'@vip')){
527 return preg_match('/^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?: [a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!\.)){0,61}[a-zA-Z0-9_-]?\.)+[a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!$)){0,61}[a-zA-Z0-9_]?)|(?:\[(?:(?:[01]? \d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/', $address);
528 }
529 else{
530 return false;
531 }
爲何要這麼改呢?解釋一下:strtolower是將郵件地址裏的字母所有小寫,雖然郵件系統不區別大小寫,可是常常大寫郵件地址估計是隻有中國人才會幹的事兒吧;用strpos是由於這個函數字符串查找效率很高;關鍵是爲何要查找'@vip'呢?由於不止163一家提供郵件的vip服務,估計這也是中國特點吧.改完之後看起來是這樣的:
523 public static function ValidateAddress($address) {
524 if (function_exists('filter_var')) { //Introduced in PHP 5.2
525 if(filter_var($address, FILTER_VALIDATE_EMAIL) === FALSE) {
526 if(strpos(strtolower($address),'@vip.')){
527 return preg_match('/^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?: [a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!\.)){0,61}[a-zA-Z0-9_-]?\.)+[a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!$)){0,61}[a-zA-Z0-9_]?)|(?:\[(?:(?:[01]? \d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/', $address);
528 }
529 else{
530 return false;
531 }
532 } else {
533 return true;
534 }
535 } else {
536 return preg_match('/^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[a-zA- Z0-9_](?:[a-zA-Z0-9_\-](?!\.)){0,61}[a-zA-Z0-9_-]?\.)+[a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!$)){0,61}[a-zA-Z0-9_]?)|(?:\[(?:(?:[01]?\d{1, 2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/', $address);
537 }
538 }
就這樣很痛快的解決了phpmailer和163的vip用戶之間的恩怨(固然了也能夠說是php的filter_var函數和163的vip郵件之間的恩怨).頗有點小成就感呢.最近這段時間精神狀態很好,工做中遇到的問題總能迅速理清思路,迎刃而解.很有"神擋殺神,佛擋殺佛"感受.就讓我繼續這樣開心,努力的工做,就讓暴風雨來得更猛烈些吧:)php