PHP laravel使用自定義郵件類實(shí)現(xiàn)發(fā)送郵件
當(dāng)?shù)卿涏]箱為騰訊企業(yè)郵箱的時(shí)候。
Phpmailer發(fā)送郵件就不好用了,具體哪里不好用,我沒真沒找到。
但是,郵件得發(fā)啊,怎么辦呢?
我這里搞了一個(gè)自定義的發(fā)送郵件類,騰訊企業(yè)郵箱也可用。
但是,郵件發(fā)送失敗,不會(huì)返回報(bào)錯(cuò)信息,這個(gè)可能是有點(diǎn)坑。
源碼如下:
<?php?namespace?App\Extend;use?Exception;/**?*?一個(gè)簡(jiǎn)單的PHP?SMTP?發(fā)送郵件類?*/?class?SmtpMail{????/**?????*?@var?string?郵件傳輸代理用戶名?????*?@access?private?????*/????private?$_userName;?????/**?????*?@var?string?郵件傳輸代理密碼?????*?@access?private?????*/????private?$_password;?????/**?????*?@var?string?郵件傳輸代理服務(wù)器地址?????*?@access?private?????*/????private?$_sendServer;?????/**?????*?@var?int?郵件傳輸代理服務(wù)器端口?????*?@access?private?????*/????private?$_port;?????/**?????*?@var?string?發(fā)件人?????*?@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?錯(cuò)誤信息?????*?@access?protected?????*/????protected?$_errorMessage;?????protected?$_debug?=?false;????/*輸出調(diào)試信息*/????private?function?debug($msg)????{????????if?($this->_debug)?{????????????echo?$msg,?"<br>",?"\n";????????}????}????public?function?setDebug($val?=?true)????{????????$this->_debug?=?$val;????}?????/**?????*?設(shè)置郵件傳輸代理,如果是可以匿名發(fā)送有郵件的服務(wù)器,只需傳遞代理服務(wù)器地址就行?????*?@access?public?????*?@param?string?$server?代理服務(wù)器的ip或者域名?????*?@param?string?$username?認(rèn)證賬號(hào)?????*?@param?string?$password?認(rèn)證密碼?????*?@param?int?$port?代理服務(wù)器的端口,smtp默認(rèn)25號(hào)端口?????*?@param?boolean?$isSecurity?到服務(wù)器的連接是否為安全連接,默認(rèn)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;????}?????/**?????*?設(shè)置發(fā)件人?????*?@access?public?????*?@param?string?$from?發(fā)件人地址?????*?@return?boolean?????*/????public?function?setFrom($from)????{????????$this->_from?=?$from;????????return?true;????}?????/**?????*?設(shè)置收件人,多個(gè)收件人,調(diào)用多次.?????*?@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;????????}????}?????/**?????*?設(shè)置抄送,多個(gè)抄送,調(diào)用多次.?????*?@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;????????}????}?????/**?????*?設(shè)置秘密抄送,多個(gè)秘密抄送,調(diào)用多次?????*?@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;????????}????}?????/**?????*?設(shè)置郵件附件,多個(gè)附件,調(diào)用多次?????*?@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;????????}????}?????/**?????*?設(shè)置郵件信息?????*?@access?public?????*?@param?string?$body?郵件主題?????*?@param?string?$subject?郵件主體內(nèi)容,可以是純文本,也可是是HTML文本?????*?@return?boolean?????*/????public?function?setMail($subject,?$body)????{????????$this->_subject?=?$subject;????????$this->_body?=?base64_encode($body);????????return?true;????}?????/**?????*?發(fā)送郵件?????*?@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;????????????}????????}?????????//其實(shí)這里也沒必要關(guān)閉,smtp命令:QUIT發(fā)出之后,服務(wù)器就關(guān)閉了連接,本地的socket資源會(huì)自動(dòng)釋放????????$this->_isSecurity???$this->closeSecutity()?:?$this->close();????????return?true;????}?????/**?????*?返回錯(cuò)誤信息?????*?@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);????????}?????????//設(shè)置發(fā)件人????????$command[]?=?array("MAIL?FROM:?<"?.?$this->_from?.?">\r\n",?250);????????$header?=?"FROM:?<"?.?$this->_from?.?">\r\n";?????????//設(shè)置收件人????????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";????????}?????????//設(shè)置抄送????????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";????????????}????????}?????????//設(shè)置秘密抄送????????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))?{????????????//含有附件的郵件頭需要聲明成這個(gè)????????????$header?.=?"Content-Type:?multipart/mixed;\r\n";????????}?elseif?(false)?{????????????//郵件體含有圖片資源的需要聲明成這個(gè)????????????$header?.=?"Content-Type:?multipart/related;\r\n";????????}?else?{????????????//html或者純文本的郵件聲明成這個(gè)????????????$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";????????????}????????}?????????//結(jié)束郵件數(shù)據(jù)發(fā)送????????$header?.=?"\r\n.\r\n";?????????$command[]?=?array("DATA\r\n",?354);????????$command[]?=?array($header,?250);????????$command[]?=?array("QUIT\r\n",?221);?????????return?$command;????}?????/**?????*?發(fā)送命令?????*?@access?protected?????*?@param?string?$command?發(fā)送到服務(wù)器的smtp命令?????*?@param?int?$code?期望服務(wù)器返回的響應(yīng)嗎?????*?@return?boolean?????*/????protected?function?sendCommand($command,?$code)????{????????//debug("Send?command:"?.?$command?.?",expected?code:"?.?$code?);????????//發(fā)送命令給服務(wù)器????????try?{????????????if?(socket_write($this->_socket,?$command,?strlen($command)))?{?????????????????//當(dāng)郵件內(nèi)容分多次發(fā)送時(shí),沒有$code,服務(wù)器沒有返回????????????????if?(empty($code))?{????????????????????return?true;????????????????}?????????????????//讀取服務(wù)器返回????????????????$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();????????}????}?????/**?????*?發(fā)送命令?????*?@access?protected?????*?@param?string?$command?發(fā)送到服務(wù)器的smtp命令?????*?@param?int?$code?期望服務(wù)器返回的響應(yīng)嗎?????*?@return?boolean?????*/????protected?function?sendCommandSecurity($command,?$code)????{????????//debug("Send?command:"?.?$command?.?",expected?code:"?.?$code?);????????try?{????????????if?(fwrite($this->_socket,?$command))?{????????????????//當(dāng)郵件內(nèi)容分多次發(fā)送時(shí),沒有$code,服務(wù)器沒有返回????????????????if?(empty($code))?{????????????????????return?true;????????????????}????????????????//讀取服務(wù)器返回????????????????$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();????????}????}?????/**?????*?讀取附件文件內(nèi)容,返回base64編碼后的文件內(nèi)容?????*?@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;????????}????}?????/**?????*?建立到服務(wù)器的網(wǎng)絡(luò)連接?????*?@access?private?????*?@return?boolean?????*/????private?function?socket()????{????????//創(chuàng)建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);?//設(shè)置阻塞模式?????????//連接服務(wù)器????????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;????}?????/**?????*?建立到服務(wù)器的SSL網(wǎng)絡(luò)連接?????*?@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;????????}?????????//設(shè)置加密連接,默認(rèn)是ssl,如果需要tls連接,可以查看php手冊(cè)stream_socket_enable_crypto函數(shù)的解釋????????stream_socket_enable_crypto($this->_socket,?true,?STREAM_CRYPTO_METHOD_SSLv23_CLIENT);?????????stream_set_blocking($this->_socket,?1);?//設(shè)置阻塞模式????????$str?=?fread($this->_socket,?1024);????????if?(!strpos($str,?"220"))?{????????????$this->_errorMessage?=?$str;????????????return?false;????????}?????????return?true;????}?????/**?????*?關(guān)閉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;????}?????/**?????*?關(guān)閉安全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;????}}
關(guān)于laravel5.8框架如何引入第三方類庫(kù),請(qǐng)參考下文補(bǔ)充內(nèi)容 laravel8大同小異。
調(diào)用方法:
/**?????*?@name:?發(fā)送郵件方法?????*?@author:?camellia?????*?@date:?2021-01-19??????*?@param:??$email??string??發(fā)送給誰(shuí)?????*?@param:??$mail_title?string??郵件標(biāo)題?????*?@param:??$mail_body??string??郵件內(nèi)容?????*?@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);?//參數(shù)1(qq郵箱使用smtp.qq.com,qq企業(yè)郵箱使用smtp.exmail.qq.com),參數(shù)2(郵箱登陸賬號(hào)),參數(shù)3(郵箱登陸密碼,也有可能是獨(dú)立密碼,就是開啟pop3/smtp時(shí)的授權(quán)碼),參數(shù)4(默認(rèn)25,騰云服務(wù)器屏蔽25端口,所以用的465),參數(shù)5(是否開啟ssl,用465就得開啟)//$mail->setServer("XXXXX",?"joffe@XXXXX",?"XXXXX",?465,?true);????????$mail->setFrom(SEND_EMAIL,"時(shí)間里的博客");?//發(fā)送者郵箱????????$mail->setReceiver($email);?//接收者郵箱????????$mail->addAttachment("");?//Attachment?附件,不用可注釋????????$mail->setMail($mail_title,?$mail_body);?//標(biāo)題和內(nèi)容????????$result?=?$mail->send();?//可以var_dump一下,發(fā)送成功會(huì)返回true,失敗false????????return?$result;//*/????}
代碼親測(cè)可用。
補(bǔ)充
laravel5.8引入第三方類庫(kù)的方法詳解
有需求需要使用PHPMailer發(fā)送郵件。
那么首先需要引入PHPMailer這個(gè)第三方的類庫(kù)。我是這樣做的:
1:在app目錄下新建Extend目錄。如下圖所示:
將PHPMailer放入Extend目錄下。如下圖所示
2:修改項(xiàng)目根目錄下的composer.json文件
"autoload": {"psr-4": { "App\\": "app/"},"classmap": [ "database/seeds", "database/factories", "app/Extend/PHPMailer/src"] },
添加你第三方類庫(kù)的位置到autoload中
3:執(zhí)行composer命令,在網(wǎng)站根目錄下:
composer dump-autoload
4:調(diào)用:
(1):使用命名空間
use PHPMailer\src\PHPMailer;
(2):調(diào)用
//實(shí)例化PHPMailer核心類$mail = new PHPMailer();
如果報(bào)錯(cuò),就在實(shí)例化前邊加一個(gè)轉(zhuǎn)義符\
至此,laravel引入第三方類庫(kù)成功。
以上就是PHP laravel使用自定義郵件類實(shí)現(xiàn)發(fā)送郵件的詳細(xì)內(nèi)容,更多關(guān)于PHP laravel發(fā)送郵件的資料請(qǐng)關(guān)注其它相關(guān)文章!
