php redis 群发邮件,redis的简单使用 异步发送邮件

你是否也困在redis,知其然不知其所以然~~ 项目中,到底怎么用?? 一个简单的实例,使用消息队列实现下yii异步发送邮件

redis~~准备工作:

使用composer安装redis的依赖库

php composer.phar require --prefer-dist yiisoft/yii2-redis

web.php的相关配置:

return [

//....

'components' => [

'redis' => [

'class' => 'yii\redis\Connection',

'hostname' => 'localhost',

'port' => 6379,

'database' => 0,

],

]

];

到此,yii中就可以使用redis进行操作了

redis~~同步与异步

那么如何实现异步消息队列发送邮件呢??

传统的操作方法是这样的:

用户输入邮件信息

服务器获取用户输入的数据,提交到第三方的邮件服务器

第三方邮件服务器发送邮件,返回处理结果

异步的处理邮件发送:

用户输入邮件相关信息

将注册信息存储在内存队列,通知用户发送成功

服务器端监听内存队列,将内存队列中的邮件数据依次发送 用户感知不到

两者的区别在哪?

异步相对于同步来说,页面非阻塞,减少了用户等待的时间体验相对来说比较好

redis~~邮件发送

原理:

用户输入邮件信息,服务器接收到输入的邮件信息,调用mail的过程,实则是对mail类属性赋值的过程,这个时候,我们可以抓取用户的信息,存储到队列,然后在队列中,依次读取邮件信息,进行发送

//实例化mail组件

$mailer = Yii::$app->mailer->compose();

$mailer->setFrom('发件人地址');

$mailer->setTo('收件人地址');

$mailer->setSubject('发送标题');

//if ($mailer->send() && $this->reg($data, 'regbymail')) {

//注意这里 本身是直接调用 send方法 进行发送 现在重写父类方法 使用redis进行处理

if ($mailer->queue()) {

return true;

}

这个时候 会去实例化mail类 进行邮件发送,这个时候 我们可以抓取邮件信息 存储到队列中

namespace mail\mailerqueue;

use Yii;

class Message extends \yii\swiftmailer\Message

{

/*抓取邮件信息到redis的队列*/

public function queue()

{

$redis = Yii::$app->redis;

if (empty($redis)) {

throw new \yii\base\InvalidConfigException('redis not found in config.');

}

// 0 - 15 select 0 select 1

// db => 1

$mailer = Yii::$app->mailer;

//mail邮件存储的数据库 是否存在

if (empty($mailer) || !$redis->select($mailer->db)) {

throw new \yii\base\InvalidConfigException('db not defined.');

}

//抓取邮件信息

$message = [];

$message['from'] =array_keys($this->from);

$message['to'] = array_keys($this->getTo());

$message['cc'] = array_keys($this->getCc());

$message['bcc'] = array_keys($this->getBcc());

$message['reply_to'] = array_keys($this->getReplyTo());

$message['charset'] = array_keys($this->getCharset());

$message['subject'] = array_keys($this->getSubject());

//获取邮件信息及子信息

$parts = $this->getSwiftMessage()->getChildren();

if (!is_array($parts) || !sizeof($parts)) {

$parts = [$this->getSwiftMessage()];

}

foreach ($parts as $part) {

if (!$part instanceof \Swift_Mime_Attachment) {

//获取内容类型

switch($part->getContentType()) {

case 'text/html':

$message['html_body'] = $part->getBody();

break;

case 'text/plain':

$message['text_body'] = $part->getBody();

break;

}

if (!$message['charset']) {

$message['charset'] = $part->getCharset();

}

}

}

//序列化抓取的内容 存放到队列中

return $redis->rpush($mailer->key, json_encode($message));

}

}

接下来就是读取redis队列,进行发送的过程

namespace mail\mailerqueue;

use Yii;

class MailerQueue extends \yii\swiftmailer\Mailer

{

public $messageClass = "doctorjason\mailerqueue\Message";

public $key = 'mails';

public $db = '1';

/*发送邮件*/

public function process()

{

$redis = Yii::$app->redis;

if (empty($redis)) {

throw new \yii\base\InvalidConfigException('redis not found in config.');

}

//如果队列中 存在数据

if ($redis->select($this->db) && $messages = $redis->lrange($this->key, 0, -1)) {

$messageObj = new Message;

//遍历邮件列表

foreach ($messages as $message) {

$message = json_decode($message, true);

if (empty($message) || !$this->setMessage($messageObj, $message)) {

throw new \ServerErrorHttpException('message error');

}

if ($messageObj->send()){

$redis->lrem($this->key, -1, json_encode($message));

}

}

}

return true;

}

//设置消息头部

public function setMessage($messageObj, $message)

{

if (empty($messageObj)) {

return false;

}

if (!empty($message['from']) && !empty($message['to'])) {

$messageObj->setFrom($message['from'])->setTo($message['to']);

if (!empty($message['cc'])) {

$messageObj->setCc($message['cc']);

}

if (!empty($message['bcc'])) {

$messageObj->setBcc($message['bcc']);

}

if (!empty($message['reply_to'])) {

$messageObj->setReplyTo($message['reply_to']);

}

if (!empty($message['charset'])) {

$messageObj->setCharset($message['charset']);

}

if (!empty($message['subject'])) {

$messageObj->setSubject($message['subject']);

}

if (!empty($message['html_body'])) {

$messageObj->setHtmlBody($message['html_body']);

}

if (!empty($message['text_body'])) {

$messageObj->setTextBody($message['text_body']);

}

return $messageObj;

}

return false;

}

}

到此 我们就实现了redis队列异步发送邮件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值