laravel 发送邮件

本文介绍了如何在Laravel项目中实现邮件发送功能,包括使用官方提供的邮件服务、配置邮件发送方式及第三方邮件服务(如阿里云)。同时,还讨论了邮件发送过程中遇到的各种问题及解决方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

系统目前的通知使用了:
	短信通知
	微信模板消息通知

一直未使用 『邮件通知』,由于项目需要,得添加上这个功能,下面记录下此次从头开始经历的一些过程:

项目使用的是 laravel 5.2
首先,查看官方文档,官方文档是默认支持了 发送邮件
	http://laravelacademy.org/post/3239.html

一定要多读几遍,好好理解它都提供了哪些内容,laravel 中发送邮件很简单:

	use Mail;
	Mail::send('emails.welcome', $data, function ($message) {		// 'email.welcome' 支持解析了 blade 模板后,作为邮件内容。 '$data' 是 blade 模板分配的数据变量
	    $message->from('us@example.com', 'Laravel');		// 发件人
	    $message->to('foo@example.com')->cc('bar@example.com');		// 收件人 & 抄送人
	});

	Mail::send(['text' => 'view'], $data, $callback);		// 支持 '纯文本邮件'
	Mail::raw('欢迎您!', $callback);							// 支持 '原生字符串邮件'

	支持 『附件』
	支持 『邮件视图中插入附件 - html邮件格式的图片等』

	支持 『邮件队列』

	等等...,就不一一说明了,查看文档


关于邮件的配置,同一般服务配置一样,涉及:
	.env
	config/mail.php

关于 '驱动'
	laravel 的邮件服务支持多种 driver:
		"smtp", "mail", "sendmail", "mailgun", "mandrill", "ses", "log"

	log 是记录到 '日志' 里,供我们本地模拟测试,而不是真实发送邮件
	mailgun, mandrill, ses 是一些第三方服务。
	smpt, mail, sendmail 是我们自己可以通过配置,发送邮件的

之前自己真没有搞过邮件发送,自己都感觉有点不可思议,经常听说,但是就是没有测试过。正好通过这个机会稍微了解下。

	邮件发送,是需要 '邮件服务器' 的。我们自己不搭建的话,只能借助第三方的邮件服务。

	1.关注PHP中发送邮件,参考:
		http://www.php.cn/php-weizijiaocheng-381273.html

	2.本地 laravel 使用 smtp 发送邮件,参考:
		https://www.jianshu.com/p/8ccb2820df23

	3.163或126邮箱 开启 SMTP 服务:
		http://www.yii-china.com/post/detail/10.html

	4.邮件服务端口:
		https://blog.youkuaiyun.com/zhangpan19910604/article/details/45065629

	5.搭建邮件服务器(没搭建过,百度或google搜索一大堆):
		https://www.jianshu.com/p/610d9bf0ae8b
		https://bfchengnuo.com/2017/03/21/%E7%94%A8Centos%E6%90%AD%E5%BB%BA%E8%87%AA%E5%B7%B1%E7%9A%84%E9%82%AE%E4%BB%B6%E7%B3%BB%E7%BB%9F/

	6.邮件的参数:
		/*
			$message->from($address, $name = null);
			$message->sender($address, $name = null);
			$message->to($address, $name = null);
			$message->cc($address, $name = null);
			$message->bcc($address, $name = null);
			$message->replyTo($address, $name = null);
			$message->subject($subject);
			$message->priority($level);
			$message->attach($pathToFile, array $options = []);
			// 从$data字符串追加文件...
			$message->attachData($data, $name, array $options = []);
			// 获取底层SwiftMailer消息实例...
			$message->getSwiftMessage();
		 */
		发现文档中,邮件的一些参数,完全不明白是啥意思,就想找找邮件参数里的解释,看了点 laravel 源码,了解到使用的是:
			swiftmailer

		查看 swiftmailer 文档,里面有一些见解,当然更多的、具体的内容,我们可以自己展开搜索:
			https://swiftmailer.symfony.com/docs/messages.html

看过文档之后,简单了解了下 邮件发送 的一些基础知识,我们按照上面的 '2' 参考教程,配置后,可以正常发送邮件了。

但考虑到,是不是通过这种情况(或 免费的服务),不专业啊?会不会效率很慢等等,想到是不是应该使用一个第三方服务。
就直接搜索 "阿里云",果然有 "邮件服务",就开启使用。
	
	阿里云 - 邮件推送文档:
		https://help.aliyun.com/product/29412.html

	这里得吐槽下,开启 "邮件服务" 我是搞了半天,半天不懂一堆域名啥是干嘛的!

	"设置发信域名",不明白的是,发送邮件为什么还需要域名,域名只有一个,因为怕影响线上的业务,和客服沟通了大半天,才敢尝试。

		直接按这个 '域名配置相关问题',一步步执行即可。
			https://help.aliyun.com/document_detail/57804.html

	又开始看 '阿里云-发送邮件文档',对于一个全新的东西,得好好了解...
		阿里云发送邮件,支持3种方式:
			1.控制台发送批量邮件。
			2.API 发送触发邮件和批量邮件。
			3.SMTP 发送触发邮件和批量邮件。

		2 和 3,都是程序实现
			API 接口 - 目前暂不支持添加附件
			SMTP 接口 - 支持附件

我搜索下 laravel 的 阿里云邮件服务的包,使用的是 'API' 接口方式(因为当时还没总结,搜索到的包就是 API 接口方式,当时都还不知道有 SMTP 接口),这里就先总结下这个包的使用:

	github地址:
		https://github.com/HyanCat/aliyun-direct-mail

	这里提一个参数:region - 区域
		hyancat/aliyun-direct-mail/lib/aliyun-php-sdk-core/Regions/EndpointConfig.php 里是所有可以填写的 region(不清楚用处是干嘛的...)

	另外,可能是版本的问题,我修改了下源码:
		hyancat/aliyun-direct-mail/src/DirectMailTransport.php

		1.将 'Swift_Mime_SimpleMessage' 类,改为:'Swift_Mime_Message'
		2.修改 sendSingle() 方法,适合我们的返回方式:
		    protected function sendSingle(\Swift_Mime_Message $message)
		    {
		        $request = new DM\SingleSendMailRequest();

		        // 控制台创建的发信地址
		        $request->setAccountName($this->accountName);
		        // 发信人昵称,长度小于 15 个字符
		        $request->setFromAlias($this->accountAlias);
		        // 取值范围 0~1: 0 为随机账号;1 为发信地址(参考阿里邮箱文档)
		        $request->setAddressType(1);
		        // 使用管理控制台中配置的回信地址(状态必须是验证通过)(参考阿里邮箱文档)
		        $request->setReplyToAddress('true');
		        // 目标地址,多个 email 地址可以用逗号分隔,最多100个地址(参考阿里邮箱文档)
		        $request->setToAddress($this->getToAddress($message));
		        // 邮件主题
		        $request->setSubject($message->getSubject());
		        // 邮件HTML正文
		        $request->setHtmlBody($message->getBody());

		        try {
		            $response = $this->createClient()->getAcsResponse($request);

		            return error(0, '发送邮件成功!', (Array) $response);
		        } catch (\ClientException $e) {
		            return error(1, $e->getErrorMessage());
		        } catch (\ServerException $e) {
		            return error(1, $e->getErrorMessage());
		        } catch (\Exception $e) {
		            return error(1, $e->getMessage());
		        } catch (\Throwable $e) {
		            return error(1, $e->getMessage());
		        }
		    }


测试过程中,出现了好多白痴问题:
	1.composer require 安装时,composer 一直报错!
	可能问题:
		.env 文件错误
		config/services.php 当时语法错误
		composer self-update composer自身版本落后

	2.配置不生效问题:
		可能开启了 config 缓存,当时不小心,执行了下命令
			php artisan config:cache
			或
			php artisan config:clear

	3.关于 .env 环境变量配置:

		# HyanCat 阿里邮箱推送配置
		#DIRECT_MAIL_APP_KEY=null
		#DIRECT_MAIL_APP_SECRET=null
		#DIRECT_MAIL_REGION=null
		#DIRECT_MAIL_ACCOUNT_ALIAS=null
		#DIRECT_MAIL_ACCOUNT_NAME=null

	env('配置项', '默认值') 函数,我一直的一个误区!一直以为不写 或者 为null,会使用默认值!发现并不生效!
		DIRECT_MAIL_APP_KEY=			// 不填写值
		DIRECT_MAIL_APP_KEY=null		// 填写为null

	我们来解析下 env() 源码
	    function env($key, $default = null)
	    {
	        $value = getenv($key);		// getenv() 函数,下面详细解释下

	        if ($value === false) {
	            return value($default);
	        }

	        switch (strtolower($value)) {
	            case 'true':
	            case '(true)':
	                return true;
	            case 'false':
	            case '(false)':
	                return false;
	            case 'empty':
	            case '(empty)':
	                return '';
	            case 'null':
	            case '(null)':
	                return;
	        }

	        if (strlen($value) > 1 && Str::startsWith($value, '"') && Str::endsWith($value, '"')) {
	            return substr($value, 1, -1);
	        }

	        return $value;
	    }


    	环境变量的范围,参照:http://www.faqs.org/rfcs/rfc3875.html
	    getenv($key)
	    	返回环境变量 varname 的值, 如果环境变量 varname 不存在则返回 FALSE。
	    	所以:
				DIRECT_MAIL_APP_KEY=			// 不填写值,getenv() 返回的是 ''
				DIRECT_MAIL_APP_KEY=null		// 填写为null,getenv() 返回的是 null
				# DIRECT_MAIL_APP_KEY=			// 只有不存在时,getenv() 返回的才是 false
			而我们的 env() 函数,会判断 "$value === false",才会使用 '默认值',所以要保证使用默认值,我们不可以添加该变量变量(或注释掉)


关于 阿里云的 SMPT API,应该是同其他的(163/126/qq邮箱的) SMTP 服务一样,我们已经开启了,laravel 默认也支持,我们直接使用即可!
	参考:
		https://help.aliyun.com/knowledge_detail/51622.html

	这里我进行测试了,没有问题!
	唯一需要注意的是:
		认证用户名是:控制台创建的发信地址(调试邮箱时各种问题,这个也是个坑)

发送邮件,会阻塞程序进行,为了优化,我们应该采用 laravel 邮件服务的 queue 方法,使用队列!(猜测应该是这样)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值