文章詳情頁
PHP laravel使用自定義郵件類實現發送郵件
瀏覽:34日期:2022-06-06 09:20:48
當登錄郵箱為騰訊企業郵箱的時候。
Phpmailer發送郵件就不好用了,具體哪里不好用,我沒真沒找到。
但是,郵件得發啊,怎么辦呢?
我這里搞了一個自定義的發送郵件類,騰訊企業郵箱也可用。
但是,郵件發送失敗,不會返回報錯信息,這個可能是有點坑。
源碼如下:
<?php?namespace?App\Extend;use?Exception;/**?*?一個簡單的PHP?SMTP?發送郵件類?*/?class?SmtpMail{????/**?????*?@var?string?郵件傳輸代理用戶名?????*?@access?private?????*/????private?$_userName;?????/**?????*?@var?string?郵件傳輸代理密碼?????*?@access?private?????*/????private?$_password;?????/**?????*?@var?string?郵件傳輸代理服務器地址?????*?@access?private?????*/????private?$_sendServer;?????/**?????*?@var?int?郵件傳輸代理服務器端口?????*?@access?private?????*/????private?$_port;?????/**?????*?@var?string?發件人?????*?@access?protected?????*/????protected?$_from;?????/**?????*?@var?string?收件人?????*?@access?protected?????*/????protected?$_to;?????/**?????*?@var?string?抄送?????*?@access?protected?????*/????protected?$_cc;?????/**?????*?@var?string?秘密抄送?????*?@access?protected?????*/????protected?$_bcc;?????/**?????*?@var?string?主題?????*?@access?protected?????*/????protected?$_subject;?????/**?????*?@var?string?郵件正文?????*?@access?protected?????*/????protected?$_body;?????/**?????*?@var?string?附件?????*?@access?protected?????*/????protected?$_attachment;?????/**?????*?@var?reource?socket資源?????*?@access?protected?????*/????protected?$_socket;?????/**?????*?@var?reource?是否是安全連接?????*?@access?protected?????*/????protected?$_isSecurity;?????/**?????*?@var?string?錯誤信息?????*?@access?protected?????*/????protected?$_errorMessage;?????protected?$_debug?=?false;????/*輸出調試信息*/????private?function?debug($msg)????{????????if?($this->_debug)?{????????????echo?$msg,?"<br>",?"\n";????????}????}????public?function?setDebug($val?=?true)????{????????$this->_debug?=?$val;????}?????/**?????*?設置郵件傳輸代理,如果是可以匿名發送有郵件的服務器,只需傳遞代理服務器地址就行?????*?@access?public?????*?@param?string?$server?代理服務器的ip或者域名?????*?@param?string?$username?認證賬號?????*?@param?string?$password?認證密碼?????*?@param?int?$port?代理服務器的端口,smtp默認25號端口?????*?@param?boolean?$isSecurity?到服務器的連接是否為安全連接,默認false?????*?@return?boolean?????*/????public?function?setServer($server,?$username?=?"",?$password?=?"",?$port?=?25,?$isSecurity?=?false)????{????????$this->_sendServer?=?$server;????????$this->_port?=?$port;????????$this->_isSecurity?=?$isSecurity;????????$this->_userName?=?empty($username)???""?:?base64_encode($username);????????$this->_password?=?empty($password)???""?:?base64_encode($password);????????return?true;????}?????/**?????*?設置發件人?????*?@access?public?????*?@param?string?$from?發件人地址?????*?@return?boolean?????*/????public?function?setFrom($from)????{????????$this->_from?=?$from;????????return?true;????}?????/**?????*?設置收件人,多個收件人,調用多次.?????*?@access?public?????*?@param?string?$to?收件人地址?????*?@return?boolean?????*/????public?function?setReceiver($to)????{????????if?(isset($this->_to))?{????????????if?(is_string($this->_to))?{????????????????$this->_to?=?array($this->_to);????????????????$this->_to[]?=?$to;????????????????return?true;????????????}?elseif?(is_array($this->_to))?{????????????????$this->_to[]?=?$to;????????????????return?true;????????????}?else?{????????????????return?false;????????????}????????}?else?{????????????$this->_to?=?$to;????????????return?true;????????}????}?????/**?????*?設置抄送,多個抄送,調用多次.?????*?@access?public?????*?@param?string?$cc?抄送地址?????*?@return?boolean?????*/????public?function?setCc($cc)????{????????if?(isset($this->_cc))?{????????????if?(is_string($this->_cc))?{????????????????$this->_cc?=?array($this->_cc);????????????????$this->_cc[]?=?$cc;????????????????return?true;????????????}?elseif?(is_array($this->_cc))?{????????????????$this->_cc[]?=?$cc;????????????????return?true;????????????}?else?{????????????????return?false;????????????}????????}?else?{????????????$this->_cc?=?$cc;????????????return?true;????????}????}?????/**?????*?設置秘密抄送,多個秘密抄送,調用多次?????*?@access?public?????*?@param?string?$bcc?秘密抄送地址?????*?@return?boolean?????*/????public?function?setBcc($bcc)????{????????if?(isset($this->_bcc))?{????????????if?(is_string($this->_bcc))?{????????????????$this->_bcc?=?array($this->_bcc);????????????????$this->_bcc[]?=?$bcc;????????????????return?true;????????????}?elseif?(is_array($this->_bcc))?{????????????????$this->_bcc[]?=?$bcc;????????????????return?true;????????????}?else?{????????????????return?false;????????????}????????}?else?{????????????$this->_bcc?=?$bcc;????????????return?true;????????}????}?????/**?????*?設置郵件附件,多個附件,調用多次?????*?@access?public?????*?@param?string?$file?文件地址?????*?@return?boolean?????*/????public?function?addAttachment($file)????{????????if?(!file_exists($file))?{????????????$this->_errorMessage?=?"file?"?.?$file?.?"?does?not?exist.";????????????return?false;????????}????????if?(isset($this->_attachment))?{????????????if?(is_string($this->_attachment))?{????????????????$this->_attachment?=?array($this->_attachment);????????????????$this->_attachment[]?=?$file;????????????????return?true;????????????}?elseif?(is_array($this->_attachment))?{????????????????$this->_attachment[]?=?$file;????????????????return?true;????????????}?else?{????????????????return?false;????????????}????????}?else?{????????????$this->_attachment?=?$file;????????????return?true;????????}????}?????/**?????*?設置郵件信息?????*?@access?public?????*?@param?string?$body?郵件主題?????*?@param?string?$subject?郵件主體內容,可以是純文本,也可是是HTML文本?????*?@return?boolean?????*/????public?function?setMail($subject,?$body)????{????????$this->_subject?=?$subject;????????$this->_body?=?base64_encode($body);????????return?true;????}?????/**?????*?發送郵件?????*?@access?public?????*?@return?boolean?????*/????public?function?send()????{????????$command?=?$this->getCommand();?????????$this->_isSecurity???$this->socketSecurity()?:?$this->socket();?????????foreach?($command?as?$value)?{????????????$result?=?$this->_isSecurity???$this->sendCommandSecurity($value[0],?$value[1])?:?$this->sendCommand($value[0],?$value[1]);????????????if?($result)?{????????????????continue;????????????}?else?{????????????????return?false;????????????}????????}?????????//其實這里也沒必要關閉,smtp命令:QUIT發出之后,服務器就關閉了連接,本地的socket資源會自動釋放????????$this->_isSecurity???$this->closeSecutity()?:?$this->close();????????return?true;????}?????/**?????*?返回錯誤信息?????*?@return?string?????*/????public?function?error()????{????????if?(!isset($this->_errorMessage))?{????????????$this->_errorMessage?=?"";????????}????????return?$this->_errorMessage;????}?????/**?????*?返回mail命令?????*?@access?protected?????*?@return?array?????*/????protected?function?getCommand()????{????????$separator?=?"----=_Part_"?.?md5($this->_from?.?time())?.?uniqid();?//分隔符?????????$command?=?array(????????????array("HELO?sendmail\r\n",?250)????????);????????if?(!empty($this->_userName))?{????????????$command[]?=?array("AUTH?LOGIN\r\n",?334);????????????$command[]?=?array($this->_userName?.?"\r\n",?334);????????????$command[]?=?array($this->_password?.?"\r\n",?235);????????}?????????//設置發件人????????$command[]?=?array("MAIL?FROM:?<"?.?$this->_from?.?">\r\n",?250);????????$header?=?"FROM:?<"?.?$this->_from?.?">\r\n";?????????//設置收件人????????if?(is_array($this->_to))?{????????????$count?=?count($this->_to);????????????for?($i?=?0;?$i?<?$count;?$i++)?{????????????????$command[]?=?array("RCPT?TO:?<"?.?$this->_to[$i]?.?">\r\n",?250);????????????????if?($i?==?0)?{????????????????????$header?.=?"TO:?<"?.?$this->_to[$i]?.?">";????????????????}?elseif?($i?+?1?==?$count)?{????????????????????$header?.=?",<"?.?$this->_to[$i]?.?">\r\n";????????????????}?else?{????????????????????$header?.=?",<"?.?$this->_to[$i]?.?">";????????????????}????????????}????????}?else?{????????????$command[]?=?array("RCPT?TO:?<"?.?$this->_to?.?">\r\n",?250);????????????$header?.=?"TO:?<"?.?$this->_to?.?">\r\n";????????}?????????//設置抄送????????if?(isset($this->_cc))?{????????????if?(is_array($this->_cc))?{????????????????$count?=?count($this->_cc);????????????????for?($i?=?0;?$i?<?$count;?$i++)?{????????????????????$command[]?=?array("RCPT?TO:?<"?.?$this->_cc[$i]?.?">\r\n",?250);????????????????????if?($i?==?0)?{????????????????????????$header?.=?"CC:?<"?.?$this->_cc[$i]?.?">";????????????????????}?elseif?($i?+?1?==?$count)?{????????????????????????$header?.=?",<"?.?$this->_cc[$i]?.?">\r\n";????????????????????}?else?{????????????????????????$header?.=?",<"?.?$this->_cc[$i]?.?">";????????????????????}????????????????}????????????}?else?{????????????????$command[]?=?array("RCPT?TO:?<"?.?$this->_cc?.?">\r\n",?250);????????????????$header?.=?"CC:?<"?.?$this->_cc?.?">\r\n";????????????}????????}?????????//設置秘密抄送????????if?(isset($this->_bcc))?{????????????if?(is_array($this->_bcc))?{????????????????$count?=?count($this->_bcc);????????????????for?($i?=?0;?$i?<?$count;?$i++)?{????????????????????$command[]?=?array("RCPT?TO:?<"?.?$this->_bcc[$i]?.?">\r\n",?250);????????????????????if?($i?==?0)?{????????????????????????$header?.=?"BCC:?<"?.?$this->_bcc[$i]?.?">";????????????????????}?elseif?($i?+?1?==?$count)?{????????????????????????$header?.=?",<"?.?$this->_bcc[$i]?.?">\r\n";????????????????????}?else?{????????????????????????$header?.=?",<"?.?$this->_bcc[$i]?.?">";????????????????????}????????????????}????????????}?else?{????????????????$command[]?=?array("RCPT?TO:?<"?.?$this->_bcc?.?">\r\n",?250);????????????????$header?.=?"BCC:?<"?.?$this->_bcc?.?">\r\n";????????????}????????}?????????//主題????????$header?.=?"Subject:?"?.?$this->_subject?.?"\r\n";????????if?(isset($this->_attachment))?{????????????//含有附件的郵件頭需要聲明成這個????????????$header?.=?"Content-Type:?multipart/mixed;\r\n";????????}?elseif?(false)?{????????????//郵件體含有圖片資源的需要聲明成這個????????????$header?.=?"Content-Type:?multipart/related;\r\n";????????}?else?{????????????//html或者純文本的郵件聲明成這個????????????$header?.=?"Content-Type:?multipart/alternative;\r\n";????????}?????????//郵件頭分隔符????????$header?.=?"\t"?.?"boundary=""?.?$separator?.?""";????????$header?.=?"\r\nMIME-Version:?1.0\r\n";????????$header?.=?"\r\n--"?.?$separator?.?"\r\n";????????$header?.=?"Content-Type:text/html;?charset=utf-8\r\n";????????$header?.=?"Content-Transfer-Encoding:?base64\r\n\r\n";????????$header?.=?$this->_body?.?"\r\n";????????$header?.=?"--"?.?$separator?.?"\r\n";?????????//加入附件????????if?(isset($this->_attachment)?&&?!empty($this->_attachment))?{????????????if?(is_array($this->_attachment))?{????????????????$count?=?count($this->_attachment);????????????????for?($i?=?0;?$i?<?$count;?$i++)?{????????????????????$header?.=?"\r\n--"?.?$separator?.?"\r\n";????????????????????$header?.=?"Content-Type:?"?.?$this->getMIMEType($this->_attachment[$i])?.?";?name=""?.?basename($this->_attachment[$i])?.?"""?.?"\r\n";????????????????????$header?.=?"Content-Transfer-Encoding:?base64\r\n";????????????????????$header?.=?"Content-Disposition:?attachment;?filename=""?.?basename($this->_attachment[$i])?.?"""?.?"\r\n";????????????????????$header?.=?"\r\n";????????????????????$header?.=?$this->readFile($this->_attachment[$i]);????????????????????$header?.=?"\r\n--"?.?$separator?.?"\r\n";????????????????}????????????}?else?{????????????????$header?.=?"\r\n--"?.?$separator?.?"\r\n";????????????????$header?.=?"Content-Type:?"?.?$this->getMIMEType($this->_attachment)?.?";?name=""?.?basename($this->_attachment)?.?"""?.?"\r\n";????????????????$header?.=?"Content-Transfer-Encoding:?base64\r\n";????????????????$header?.=?"Content-Disposition:?attachment;?filename=""?.?basename($this->_attachment)?.?"""?.?"\r\n";????????????????$header?.=?"\r\n";????????????????$header?.=?$this->readFile($this->_attachment);????????????????$header?.=?"\r\n--"?.?$separator?.?"\r\n";????????????}????????}?????????//結束郵件數據發送????????$header?.=?"\r\n.\r\n";?????????$command[]?=?array("DATA\r\n",?354);????????$command[]?=?array($header,?250);????????$command[]?=?array("QUIT\r\n",?221);?????????return?$command;????}?????/**?????*?發送命令?????*?@access?protected?????*?@param?string?$command?發送到服務器的smtp命令?????*?@param?int?$code?期望服務器返回的響應嗎?????*?@return?boolean?????*/????protected?function?sendCommand($command,?$code)????{????????//debug("Send?command:"?.?$command?.?",expected?code:"?.?$code?);????????//發送命令給服務器????????try?{????????????if?(socket_write($this->_socket,?$command,?strlen($command)))?{?????????????????//當郵件內容分多次發送時,沒有$code,服務器沒有返回????????????????if?(empty($code))?{????????????????????return?true;????????????????}?????????????????//讀取服務器返回????????????????$data?=?trim(socket_read($this->_socket,?1024));????????????????//debug(?"response:"?.?$data);?????????????????if?($data)?{????????????????????$pattern?=?"/^"?.?$code?.?"/";????????????????????if?(preg_match($pattern,?$data))?{????????????????????????return?true;????????????????????}?else?{????????????????????????$this->_errorMessage?=?"Error:"?.?$data?.?"|**|?command:";????????????????????????return?false;????????????????????}????????????????}?else?{????????????????????$this->_errorMessage?=?"Error:"?.?socket_strerror(socket_last_error());????????????????????return?false;????????????????}????????????}?else?{????????????????$this->_errorMessage?=?"Error:"?.?socket_strerror(socket_last_error());????????????????return?false;????????????}????????}?catch?(Exception?$e)?{????????????$this->_errorMessage?=?"Error:"?.?$e->getMessage();????????}????}?????/**?????*?發送命令?????*?@access?protected?????*?@param?string?$command?發送到服務器的smtp命令?????*?@param?int?$code?期望服務器返回的響應嗎?????*?@return?boolean?????*/????protected?function?sendCommandSecurity($command,?$code)????{????????//debug("Send?command:"?.?$command?.?",expected?code:"?.?$code?);????????try?{????????????if?(fwrite($this->_socket,?$command))?{????????????????//當郵件內容分多次發送時,沒有$code,服務器沒有返回????????????????if?(empty($code))?{????????????????????return?true;????????????????}????????????????//讀取服務器返回????????????????$data?=?trim(fread($this->_socket,?1024));????????????????//debug(?"response:"?.?$data?);?????????????????if?($data)?{????????????????????$pattern?=?"/^"?.?$code?.?"/";????????????????????if?(preg_match($pattern,?$data))?{????????????????????????return?true;????????????????????}?else?{????????????????????????$this->_errorMessage?=?"Error:"?.?$data?.?"|**|?command:";????????????????????????return?false;????????????????????}????????????????}?else?{????????????????????return?false;????????????????}????????????}?else?{????????????????$this->_errorMessage?=?"Error:?"?.?$command?.?"?send?failed";????????????????return?false;????????????}????????}?catch?(Exception?$e)?{????????????$this->_errorMessage?=?"Error:"?.?$e->getMessage();????????}????}?????/**?????*?讀取附件文件內容,返回base64編碼后的文件內容?????*?@access?protected?????*?@param?string?$file?文件?????*?@return?mixed?????*/????protected?function?readFile($file)????{????????if?(file_exists($file))?{????????????$file_obj?=?file_get_contents($file);????????????return?base64_encode($file_obj);????????}?else?{????????????$this->_errorMessage?=?"file?"?.?$file?.?"?dose?not?exist";????????????return?false;????????}????}?????/**?????*?獲取附件MIME類型?????*?@access?protected?????*?@param?string?$file?文件?????*?@return?mixed?????*/????protected?function?getMIMEType($file)????{????????if?(file_exists($file))?{????????????$mime?=?mime_content_type($file);????????????if?(!preg_match("/gif|jpg|png|jpeg/",?$mime))?{????????????????$mime?=?"application/octet-stream";????????????}????????????return?$mime;????????}?else?{????????????return?false;????????}????}?????/**?????*?建立到服務器的網絡連接?????*?@access?private?????*?@return?boolean?????*/????private?function?socket()????{????????//創建socket資源????????$this->_socket?=?socket_create(AF_INET,?SOCK_STREAM,?getprotobyname("tcp"));?????????if?(!$this->_socket)?{????????????$this->_errorMessage?=?socket_strerror(socket_last_error());????????????return?false;????????}?????????socket_set_block($this->_socket);?//設置阻塞模式?????????//連接服務器????????if?(!socket_connect($this->_socket,?$this->_sendServer,?$this->_port))?{????????????$this->_errorMessage?=?socket_strerror(socket_last_error());????????????return?false;????????}????????$str?=?socket_read($this->_socket,?1024);????????if?(!strpos($str,?"220"))?{????????????$this->_errorMessage?=?$str;????????????return?false;????????}?????????return?true;????}?????/**?????*?建立到服務器的SSL網絡連接?????*?@access?private?????*?@return?boolean?????*/????private?function?socketSecurity()????{????????$remoteAddr?=?"tcp://"?.?$this->_sendServer?.?":"?.?$this->_port;????????$this->_socket?=?stream_socket_client($remoteAddr,?$errno,?$errstr,?30);????????if?(!$this->_socket)?{????????????$this->_errorMessage?=?$errstr;????????????return?false;????????}?????????//設置加密連接,默認是ssl,如果需要tls連接,可以查看php手冊stream_socket_enable_crypto函數的解釋????????stream_socket_enable_crypto($this->_socket,?true,?STREAM_CRYPTO_METHOD_SSLv23_CLIENT);?????????stream_set_blocking($this->_socket,?1);?//設置阻塞模式????????$str?=?fread($this->_socket,?1024);????????if?(!strpos($str,?"220"))?{????????????$this->_errorMessage?=?$str;????????????return?false;????????}?????????return?true;????}?????/**?????*?關閉socket?????*?@access?private?????*?@return?boolean?????*/????private?function?close()????{????????if?(isset($this->_socket)?&&?is_object($this->_socket))?{????????????$this->_socket->close();????????????return?true;????????}????????$this->_errorMessage?=?"No?resource?can?to?be?close";????????return?false;????}?????/**?????*?關閉安全socket?????*?@access?private?????*?@return?boolean?????*/????private?function?closeSecutity()????{????????if?(isset($this->_socket)?&&?is_object($this->_socket))?{????????????stream_socket_shutdown($this->_socket,?STREAM_SHUT_WR);????????????return?true;????????}????????$this->_errorMessage?=?"No?resource?can?to?be?close";????????return?false;????}}
關于laravel5.8框架如何引入第三方類庫,請參考下文補充內容 laravel8大同小異。
調用方法:
/**?????*?@name:?發送郵件方法?????*?@author:?camellia?????*?@date:?2021-01-19??????*?@param:??$email??string??發送給誰?????*?@param:??$mail_title?string??郵件標題?????*?@param:??$mail_body??string??郵件內容?????*?@return:?$result?bool????true/false?????*/????public?function?send_mail($email,?$mail_title,?$mail_body)????{????????$mail?=?new?SmtpMail();????????$mail->setServer(EMAIL_SERVER,?SEND_EMAIL,?EMAIL_SECERT,?465,?true);?//參數1(qq郵箱使用smtp.qq.com,qq企業郵箱使用smtp.exmail.qq.com),參數2(郵箱登陸賬號),參數3(郵箱登陸密碼,也有可能是獨立密碼,就是開啟pop3/smtp時的授權碼),參數4(默認25,騰云服務器屏蔽25端口,所以用的465),參數5(是否開啟ssl,用465就得開啟)//$mail->setServer("XXXXX",?"joffe@XXXXX",?"XXXXX",?465,?true);????????$mail->setFrom(SEND_EMAIL,"時間里的博客");?//發送者郵箱????????$mail->setReceiver($email);?//接收者郵箱????????$mail->addAttachment("");?//Attachment?附件,不用可注釋????????$mail->setMail($mail_title,?$mail_body);?//標題和內容????????$result?=?$mail->send();?//可以var_dump一下,發送成功會返回true,失敗false????????return?$result;//*/????}
代碼親測可用。
補充
laravel5.8引入第三方類庫的方法詳解
有需求需要使用PHPMailer發送郵件。
那么首先需要引入PHPMailer這個第三方的類庫。我是這樣做的:
1:在app目錄下新建Extend目錄。如下圖所示:
將PHPMailer放入Extend目錄下。如下圖所示
2:修改項目根目錄下的composer.json文件
"autoload": {"psr-4": { "App\\": "app/"},"classmap": [ "database/seeds", "database/factories", "app/Extend/PHPMailer/src"] },
添加你第三方類庫的位置到autoload中
3:執行composer命令,在網站根目錄下:
composer dump-autoload
4:調用:
(1):使用命名空間
use PHPMailer\src\PHPMailer;
(2):調用
//實例化PHPMailer核心類$mail = new PHPMailer();
如果報錯,就在實例化前邊加一個轉義符\
至此,laravel引入第三方類庫成功。
以上就是PHP laravel使用自定義郵件類實現發送郵件的詳細內容,更多關于PHP laravel發送郵件的資料請關注其它相關文章!
標簽:
PHP
排行榜