当登录邮箱为腾讯企业邮箱的时候。
Phpmailer发送邮件就不好用了,具体哪里不好用,我没真没找到。
但是,邮件得发啊,怎么办呢?
我这里搞了一个自定义的发送邮件类,腾讯企业邮箱也可用。
但是,邮件发送失败,不会返回报错信息,这个可能是有点坑。
源码如下: - <?php
- namespaceApp\Extend;
- useException;
- /**
- *一个简单的PHPSMTP发送邮件类
- */
- classSmtpMail
- {
- /**
- *@varstring邮件传输代理用户名
- *@accessprivate
- */
- private$_userName;
- /**
- *@varstring邮件传输代理密码
- *@accessprivate
- */
- private$_password;
- /**
- *@varstring邮件传输代理服务器地址
- *@accessprivate
- */
- private$_sendServer;
- /**
- *@varint邮件传输代理服务器端口
- *@accessprivate
- */
- private$_port;
- /**
- *@varstring发件人
- *@accessprotected
- */
- protected$_from;
- /**
- *@varstring收件人
- *@accessprotected
- */
- protected$_to;
- /**
- *@varstring抄送
- *@accessprotected
- */
- protected$_cc;
- /**
- *@varstring秘密抄送
- *@accessprotected
- */
- protected$_bcc;
- /**
- *@varstring主题
- *@accessprotected
- */
- protected$_subject;
- /**
- *@varstring邮件正文
- *@accessprotected
- */
- protected$_body;
- /**
- *@varstring附件
- *@accessprotected
- */
- protected$_attachment;
- /**
- *@varreourcesocket资源
- *@accessprotected
- */
- protected$_socket;
- /**
- *@varreource是否是安全连接
- *@accessprotected
- */
- protected$_isSecurity;
- /**
- *@varstring错误信息
- *@accessprotected
- */
- protected$_errorMessage;
- protected$_debug=false;
- /*输出调试信息*/
- privatefunctiondebug($msg)
- {
- if($this->_debug){
- echo$msg,'<br>',"\n";
- }
- }
- publicfunctionsetDebug($val=true)
- {
- $this->_debug=$val;
- }
- /**
- *设置邮件传输代理,如果是可以匿名发送有邮件的服务器,只需传递代理服务器地址就行
- *@accesspublic
- *@paramstring$server代理服务器的ip或者域名
- *@paramstring$username认证账号
- *@paramstring$password认证密码
- *@paramint$port代理服务器的端口,smtp默认25号端口
- *@paramboolean$isSecurity到服务器的连接是否为安全连接,默认false
- *@returnboolean
- */
- publicfunctionsetServer($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);
- returntrue;
- }
- /**
- *设置发件人
- *@accesspublic
- *@paramstring$from发件人地址
- *@returnboolean
- */
- publicfunctionsetFrom($from)
- {
- $this->_from=$from;
- returntrue;
- }
- /**
- *设置收件人,多个收件人,调用多次.
- *@accesspublic
- *@paramstring$to收件人地址
- *@returnboolean
- */
- publicfunctionsetReceiver($to)
- {
- if(isset($this->_to)){
- if(is_string($this->_to)){
- $this->_to=array($this->_to);
- $this->_to[]=$to;
- returntrue;
- }elseif(is_array($this->_to)){
- $this->_to[]=$to;
- returntrue;
- }else{
- returnfalse;
- }
- }else{
- $this->_to=$to;
- returntrue;
- }
- }
- /**
- *设置抄送,多个抄送,调用多次.
- *@accesspublic
- *@paramstring$cc抄送地址
- *@returnboolean
- */
- publicfunctionsetCc($cc)
- {
- if(isset($this->_cc)){
- if(is_string($this->_cc)){
- $this->_cc=array($this->_cc);
- $this->_cc[]=$cc;
- returntrue;
- }elseif(is_array($this->_cc)){
- $this->_cc[]=$cc;
- returntrue;
- }else{
- returnfalse;
- }
- }else{
- $this->_cc=$cc;
- returntrue;
- }
- }
- /**
- *设置秘密抄送,多个秘密抄送,调用多次
- *@accesspublic
- *@paramstring$bcc秘密抄送地址
- *@returnboolean
- */
- publicfunctionsetBcc($bcc)
- {
- if(isset($this->_bcc)){
- if(is_string($this->_bcc)){
- $this->_bcc=array($this->_bcc);
- $this->_bcc[]=$bcc;
- returntrue;
- }elseif(is_array($this->_bcc)){
- $this->_bcc[]=$bcc;
- returntrue;
- }else{
- returnfalse;
- }
- }else{
- $this->_bcc=$bcc;
- returntrue;
- }
- }
- /**
- *设置邮件附件,多个附件,调用多次
- *@accesspublic
- *@paramstring$file文件地址
- *@returnboolean
- */
- publicfunctionaddAttachment($file)
- {
- if(!file_exists($file)){
- $this->_errorMessage="file".$file."doesnotexist.";
- returnfalse;
- }
- if(isset($this->_attachment)){
- if(is_string($this->_attachment)){
- $this->_attachment=array($this->_attachment);
- $this->_attachment[]=$file;
- returntrue;
- }elseif(is_array($this->_attachment)){
- $this->_attachment[]=$file;
- returntrue;
- }else{
- returnfalse;
- }
- }else{
- $this->_attachment=$file;
- returntrue;
- }
- }
- /**
- *设置邮件信息
- *@accesspublic
- *@paramstring$body邮件主题
- *@paramstring$subject邮件主体内容,可以是纯文本,也可是是HTML文本
- *@returnboolean
- */
- publicfunctionsetMail($subject,$body)
- {
- $this->_subject=$subject;
- $this->_body=base64_encode($body);
- returntrue;
- }
- /**
- *发送邮件
- *@accesspublic
- *@returnboolean
- */
- publicfunctionsend()
- {
- $command=$this->getCommand();
- $this->_isSecurity?$this->socketSecurity():$this->socket();
- foreach($commandas$value){
- $result=$this->_isSecurity?$this->sendCommandSecurity($value[0],$value[1]):$this->sendCommand($value[0],$value[1]);
- if($result){
- continue;
- }else{
- returnfalse;
- }
- }
- //其实这里也没必要关闭,smtp命令:QUIT发出之后,服务器就关闭了连接,本地的socket资源会自动释放
- $this->_isSecurity?$this->closeSecutity():$this->close();
- returntrue;
- }
- /**
- *返回错误信息
- *@returnstring
- */
- publicfunctionerror()
- {
- if(!isset($this->_errorMessage)){
- $this->_errorMessage="";
- }
- return$this->_errorMessage;
- }
- /**
- *返回mail命令
- *@accessprotected
- *@returnarray
- */
- protectedfunctiongetCommand()
- {
- $separator="----=_Part_".md5($this->_from.time()).uniqid();//分隔符
- $command=array(
- array("HELOsendmail\r\n",250)
- );
- if(!empty($this->_userName)){
- $command[]=array("AUTHLOGIN\r\n",334);
- $command[]=array($this->_userName."\r\n",334);
- $command[]=array($this->_password."\r\n",235);
- }
- //设置发件人
- $command[]=array("MAILFROM:<".$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("RCPTTO:<".$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("RCPTTO:<".$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("RCPTTO:<".$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("RCPTTO:<".$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("RCPTTO:<".$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("RCPTTO:<".$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;
- }
- /**
- *发送命令
- *@accessprotected
- *@paramstring$command发送到服务器的smtp命令
- *@paramint$code期望服务器返回的响应吗
- *@returnboolean
- */
- protectedfunctionsendCommand($command,$code)
- {
- //debug('Sendcommand:'.$command.',expectedcode:'.$code);
- //发送命令给服务器
- try{
- if(socket_write($this->_socket,$command,strlen($command))){
- //当邮件内容分多次发送时,没有$code,服务器没有返回
- if(empty($code)){
- returntrue;
- }
- //读取服务器返回
- $data=trim(socket_read($this->_socket,1024));
- //debug('response:'.$data);
- if($data){
- $pattern="/^".$code."/";
- if(preg_match($pattern,$data)){
- returntrue;
- }else{
- $this->_errorMessage="Error:".$data."|**|command:";
- returnfalse;
- }
- }else{
- $this->_errorMessage="Error:".socket_strerror(socket_last_error());
- returnfalse;
- }
- }else{
- $this->_errorMessage="Error:".socket_strerror(socket_last_error());
- returnfalse;
- }
- }catch(Exception$e){
- $this->_errorMessage="Error:".$e->getMessage();
- }
- }
- /**
- *发送命令
- *@accessprotected
- *@paramstring$command发送到服务器的smtp命令
- *@paramint$code期望服务器返回的响应吗
- *@returnboolean
- */
- protectedfunctionsendCommandSecurity($command,$code)
- {
- //debug('Sendcommand:'.$command.',expectedcode:'.$code);
- try{
- if(fwrite($this->_socket,$command)){
- //当邮件内容分多次发送时,没有$code,服务器没有返回
- if(empty($code)){
- returntrue;
- }
- //读取服务器返回
- $data=trim(fread($this->_socket,1024));
- //debug('response:'.$data);
- if($data){
- $pattern="/^".$code."/";
- if(preg_match($pattern,$data)){
- returntrue;
- }else{
- $this->_errorMessage="Error:".$data."|**|command:";
- returnfalse;
- }
- }else{
- returnfalse;
- }
- }else{
- $this->_errorMessage="Error:".$command."sendfailed";
- returnfalse;
- }
- }catch(Exception$e){
- $this->_errorMessage="Error:".$e->getMessage();
- }
- }
- /**
- *读取附件文件内容,返回base64编码后的文件内容
- *@accessprotected
- *@paramstring$file文件
- *@returnmixed
- */
- protectedfunctionreadFile($file)
- {
- if(file_exists($file)){
- $file_obj=file_get_contents($file);
- returnbase64_encode($file_obj);
- }else{
- $this->_errorMessage="file".$file."dosenotexist";
- returnfalse;
- }
- }
- /**
- *获取附件MIME类型
- *@accessprotected
- *@paramstring$file文件
- *@returnmixed
- */
- protectedfunctiongetMIMEType($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{
- returnfalse;
- }
- }
- /**
- *建立到服务器的网络连接
- *@accessprivate
- *@returnboolean
- */
- privatefunctionsocket()
- {
- //创建socket资源
- $this->_socket=socket_create(AF_INET,SOCK_STREAM,getprotobyname('tcp'));
- if(!$this->_socket){
- $this->_errorMessage=socket_strerror(socket_last_error());
- returnfalse;
- }
- socket_set_block($this->_socket);//设置阻塞模式
- //连接服务器
- if(!socket_connect($this->_socket,$this->_sendServer,$this->_port)){
- $this->_errorMessage=socket_strerror(socket_last_error());
- returnfalse;
- }
- $str=socket_read($this->_socket,1024);
- if(!strpos($str,"220")){
- $this->_errorMessage=$str;
- returnfalse;
- }
- returntrue;
- }
- /**
- *建立到服务器的SSL网络连接
- *@accessprivate
- *@returnboolean
- */
- privatefunctionsocketSecurity()
- {
- $remoteAddr="tcp://".$this->_sendServer.":".$this->_port;
- $this->_socket=stream_socket_client($remoteAddr,$errno,$errstr,30);
- if(!$this->_socket){
- $this->_errorMessage=$errstr;
- returnfalse;
- }
- //设置加密连接,默认是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;
- returnfalse;
- }
- returntrue;
- }
- /**
- *关闭socket
- *@accessprivate
- *@returnboolean
- */
- privatefunctionclose()
- {
- if(isset($this->_socket)&&is_object($this->_socket)){
- $this->_socket->close();
- returntrue;
- }
- $this->_errorMessage="Noresourcecantobeclose";
- returnfalse;
- }
- /**
- *关闭安全socket
- *@accessprivate
- *@returnboolean
- */
- privatefunctioncloseSecutity()
- {
- if(isset($this->_socket)&&is_object($this->_socket)){
- stream_socket_shutdown($this->_socket,STREAM_SHUT_WR);
- returntrue;
- }
- $this->_errorMessage="Noresourcecantobeclose";
- returnfalse;
- }
- }
复制代码关于laravel5.8框架如何引入第三方类库,请参考下文补充内容 laravel8大同小异。
调用方法: - /**
- *@name:发送邮件方法
- *@author:camellia
- *@date:2021-01-19
- *@param:$emailstring发送给谁
- *@param:$mail_titlestring邮件标题
- *@param:$mail_bodystring邮件内容
- *@return:$resultbooltrue/false
- */
- publicfunctionsend_mail($email,$mail_title,$mail_body)
- {
- $mail=newSmtpMail();
- $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发送邮件的资料请关注中国红客联盟其它相关文章! |