php 基于yii2框架编写插件并提交到composer

在yii2框架中基于swiftmailer和redis编写自定义异步发送邮件的插件,并提交到composer


1、在vendor中创建目录结构如下:
lvfk 此文件夹下可以由多个插件
└── mailerqueue 插件名称
    └── src 存放插件源码
        ├── Mailer.php 继承\yii\swiftmailer\Mailer,自定参数并正真发送Redis中存储的邮件
        └── Message.php 继承\yii\swiftmailer\Message,改写原有发送邮件功能为存储到Redis列表中

2、编写Mail.php 和 Message.php

Message.php
redis;
        if(empty($redis)){
            throw new InvalidConfigException('redis not found in config');
        }

        //检测mailer
        $mailer = \Yii::$app->mailer;
        if(empty($redis) || !$redis->select($mailer->db) || empty($mailer->key)){
            throw new InvalidConfigException('mailer not found in config');
        }
        if(empty($mailer->key)){
            throw new InvalidConfigException('parameter key not found in mailer config');
        }
        if(!$redis->select($mailer->db)){
            throw new InvalidConfigException('parameter db not found in mailer config');
        }


        //发送
        $message = [];
        $message['from'] = array_keys($this->from);
        $message['to'] = array_keys($this->getTo());
        $message['cc'] = !empty($this->getCc())?array_keys($this->getCc()):[];
        $message['bcc'] = !empty($this->getBcc())?array_keys($this->getBcc()):[];
        $message['reply_to'] = !empty($this->getReplyTo())?array_keys($this->getReplyTo()):[];
        $message['charset'] = $this->getCharset();
        $message['subject'] = $this->getSubject();
        //正文处理
        $parts = $this->getSwiftMessage()->getChildren();
        if(!is_array($parts) || count($parts) == 0){
            $parts = [$this->getSwiftMessage()];
        }
        foreach ($parts as $part){
            if(!$parts 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(!empty($message['charset'])){
                $message['charset'] = $part->getCharset();
            }
        }

        return $redis->rpush($mailer->key, json_encode($message));
    }
}
Mail.php 
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;
    }

    /**
     * 发邮件
     */
    public function process(){
        //检测redis
        $redis = \Yii::$app->redis;
        if(empty($redis)){
            throw new 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;
    }
}

3、在web.php中配置,业务代码中即可使用自定义插件

'aliases' => [//在配置添加,实现mailer中class可以找到我们的自定义插件类
	'@lvfk/mailerqueue' => '@vendor/lvfk/mailerqueue/src'
],

以下两个在components数组中配置:
//自定义mailer组件
'mailer' => [
	'class' => 'lvfk\mailerqueue\Mailer',
	'db' => 9,//设置redis使用库
	'key' => 'mails',//redis 列表名字
	'useFileTransport' => false,
	'transport' => [
		'class' => 'Swift_SmtpTransport',
		'host' => 'smtp.163.com',
		'username' => '[email protected]',
		'password' => 'xxxx',
		'port' => '465',
		'encryption' => 'ssl',
	],
],

//redis 操作组件配置
'redis' => [
	'class' => 'yii\redis\Connection',
	'hostname' => 'localhost',
	'port' => 6379,
	'database' => 9,
	'password'  => '123456',
],
4、业务代码中调用
//先发送到redis,异步发送
\Yii::$app->mailer->compose('reply', [
	'username'=>$username,
	'userpass'=>$userpass,
	'useremail'=>$this->useremail,
	'time'=>$time,
	'token'=>$token
])
->setSubject('电子邮箱注册激活')
->setFrom(['[email protected]'=>'lvfk'])
->setTo($this->useremail)
->queue();
5、异步发送,使用yii2的commands命令
5.1、由于yii2的command命令使用的是配置console.php而不是web.php,因此要把第3步中的三个配置移到console.php中
5.2、在commands编写文件MailerController.php
class MailerController extends Controller
{
    /**
     * 发送邮件
     */
    public function actionSend()
    {
        \Yii::$app->mailer->process();
        var_dump('发送完毕');
    }
}
5.3、发送
在项目更目录中执行:./yii mailer/send

6、利用crontab任务定时发送邮件
*/3 * * * * /var/www/yii2/yii mailer /send >> /var/log/mailer.log

7、插件提交composer
7.1、在github网站上新建一个新库yii2_mailerqueue
7.2、把新库克隆到本地
git clone https://github.com/Justshunjian/yii2_mailerqueue.git
7.3、把插件src复制到克隆到本地的yii2_mailerqueue
cp -r /var/www/yii2-shop/vendor/lvfk/mailerqueue/src/ yii2_mailerqueue/
7.4、编写composer.json
{
	"name": "lvfk/mailerqueue",
	"type": "yii2-extension",
	"description": " async mailer by swiftmailer and redis base on yii2",
	"keywords": ["yii2","redis","async","mailer"],
	"license": "MIT",
	"support": {
		"issues":"https://github.com/Justshunjian/yii2_mailerqueue/issues",
		"forum":"",
		"source":"https://github.com/Justshunjian/yii2_mailerqueue"
	},
	"authors":[
		{
			"name":"lvfk",
			"email":"[email protected]"
		}
	],
	"require":{
		"yiisoft/yii2":"*",
		"yiisoft/yii2-redis":"~2.0.0"
	},
	"autoload":{
		"psr-4":{
			"lvfk\\mailerqueue\\":"src/"
		}
	}
}
7.5、提交到github
7.6、进入composer官网https://packagist.org/,使用github帐号登录
7.7、登录成功之后,点击右上角submit
A、把待提交项目github的地址拷贝到网页文本框
https://github.com/Justshunjian/yii2_mailerqueue.git

B、经过A就已经提交成功,但是在页面上还需要根据提示设置当github更新之后,composer这步数据自动更新

curl -XPOST -H'content-type:application/json' 'https://packagist.org/api/update-package?username=Justshunjian&apiToken=TOKEN' -d'{"repository":{"url":"https://github.com/Justshunjian/yii2_mailerqueue.git"}}'
其中TOKEN在Profile中的Your API Token中隐藏的

8、下载安装并使用
8.1、下载安装
composer require lvfk/mailerqueue

8.2、配置有微调,业务代码使用无需调整
由于是下载安装的,因此配置文件中的3个配置中别名设置aliases不用设置了,因为是composer自动加载的,只需保留
以下两个在components数组中配置:
//自定义mailer组件
'mailer' => [
	'class' => 'lvfk\mailerqueue\Mailer',
	'db' => 9,//设置redis使用库
	'key' => 'mails',//redis 列表名字
	'useFileTransport' => false,
	'transport' => [
		'class' => 'Swift_SmtpTransport',
		'host' => 'smtp.163.com',
		'username' => '[email protected]',
		'password' => 'xxxx',
		'port' => '465',
		'encryption' => 'ssl',
	],
],

//redis 操作组件配置
'redis' => [
	'class' => 'yii\redis\Connection',
	'hostname' => 'localhost',
	'port' => 6379,
	'database' => 9,
	'password'  => '123456',
],
9、完成



你可能感兴趣的:(php,redis,composer,swiftmailer)