Hi,阿金 ...

Laravel事件

发表: 2019-03-16 分类:

Laravel 事件使用.

常用于与主流程无关的功能,如注册短信,下单通知等功能.

分为同步和异步功能.lumen的事件和队列与laravel一至,由于lumen缺少自动命令.可以使用laravel命令创建完成再复制到lumen下.

同步事件

1.打开app事件注册的配置

1
2
3
4
5
6
// 文件 /bootstrap/app.php
$app->register(App\Providers\EventServiceProvider::class);

// 应需要序列化model,需要修改.env 的APP_KEY 为类似base64:59KCzr0MWDGz0fHhOJXeN+yurJw5SBWTXiqJjul7xlE=
// 可以使用 laravel命令生成.
php artisan key:generate

2.新建事件

由于lumen没有命令直接创建事件,只能手动创建.

如订单事件

在/app/Events 目录下创建OrderEvent.php类.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php

namespace App\Events;

use App\Events\Event;
use Illuminate\Queue\SerializesModels;//序列化类

class OrderEvent extends Event
{
use SerializesModels;

public $orderModel;

/**
* Create a new event instance.
*
* @param Order $orderModel
* @return void
*/
public function __construct(Order $orderModel)//事件传参
{
$this->orderModel = $orderModel;//初始化事件类
}
}

3. 编写事件监听器

在/App/Listenters下,创建事件监听类.加后缀Listener

如:OrderListenter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php

namespace App\Listeners;

use App\Events\OrderEvent;
class TestListener
{

// 处理事件方法
public function handle(OrderEvent $event)
{
echo "TestListener";
$orderModel= event->OrderModel;
// 开始处理事件,如发送短信
}
}

4. 绑定事件和监听器

在 /app/Providers 目录下,新建EventServiceProvider.php类

在listen数组下,新建 鍵:事件名 值:监听者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php

namespace App\Providers;

use Laravel\Lumen\Providers\EventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
/**
* 事件监听者
*
* @var array
*/
protected $listen = [
// 订单变更事件
'App\Events\OrderEvent' => [
'App\Listeners\OrderListener',//监听器,可以有多个
]
];

/**
* 事件订阅者
*
* @var array
*/
protected $subscribe = [

];
}

4. 触发事件

可以在控制器中或model中使用.

使用event(new OrderEvent())或Event::fire(new OrderEvent());

如我OrderModel中使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php

namespace App\Http\Model;

use Illuminate\Database\Eloquent\Model;
use App\Library;
use App\Events\OrderEvent; //引用事件
/**
* 订购单
* Class Order
* @package App\Http\Model
*/
class Order extends Model
{
...


protected static function boot()
{
parent::boot();

// 订单创建完
static::created(function ($model) {
event(new OrderEvent($model));// 触发事件
//Event::fire(new OrderEvent());
});

// 订单更新
static::updated(function ($model) {
event(new OrderEvent($model));// 触发事件
});
}

...

异步队列

以上是使用同步方式调用事件,但有些耗时的工作需要在后台异步执行.比如短信,邮件通知等,把事件放到队列执行.需要配置异步队列.下面使用redis快速配置异步队列.

1.配置队列

复制文件/vendor/laravel/lumen-framework/config/queue.php到/app/config/queue.php 下.

修改.env 加 QUEUE_DRIVER=redis

2. 修改事件监听器类型

把Listenter改成队列模式.

如OrderLisnter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
namespace App\Listeners;


use App\Events\TestEvent;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
class OrderListener implements ShouldQueue
{
use InteractsWithQueue;

public function handle(OrderEvent $event)
{
echo "TestListener";
}

3. 调用

和普通 事件一样.

4. 配置队列消费

后台监听命令

1
2
# --daemon=不重启框架 --sleep=无任务睡眠时间秒 --tries=失败重试
php artisan queue:work connection --daemon --sleep=3 --tries=3

5. 使用supervisor后台监控

使用后台监控程序

  • 安装supervisor,linux 环境
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 安装
yum install supervisor
# mac 安装
brew install supervisor

# 配置文件
/etc/supervisor/
或在mac /usr/local/etc/supervisord.ini

#脚本配置文件
cd /usr/local/etc/supervisor.d/

#新建laravel 脚本配置 laravel-worker.conf && laravel-worker.ini

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
⌘=php /Users/arkin/PhpstormProjects/cisscool/cisscool-api/artisan queue:work --sleep=3 --tries=3 --daemon
autostart=true
autorestart=true
user=arkin
numprocs=8
redirect_stderr=true
stdout_logfile=/data/logs/ciss/work.log

# 运行
sudo supervisord -c /etc/supervisor/supervisord.conf
sudo supervisorctl -c /etc/supervisor/supervisord.conf

# CI发布完成后执行:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start laravel-worker:*

6.建立失败数据库

1
2
3
4
5
6
7
8
9
CREATE TABLE `failed_jobs` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`connection` text COLLATE utf8_unicode_ci NOT NULL,
`queue` text COLLATE utf8_unicode_ci NOT NULL,
`payload` longtext COLLATE utf8_unicode_ci NOT NULL,
`exception` longtext COLLATE utf8_unicode_ci NOT NULL,
`failed_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=COMPACT

到此基于队列的事件监听可以正常使用了.

队列的详细使用,事件的分发广播.参考下一篇.

本文作者:阿金

本文链接:http://www.hi-arkin.com/2019/03/16/PHP/laravel-event/

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!

扫描二维码,分享此文章