Lumen/laravel Event Demo

最近在学习lumen,想用它来编写接口,学习过程中做点记录;

首先,按照官方介绍,创建 lumen project:

composer create-project --prefer-dist laravel/lumen lumenEventDemo

  

项目创建完成,下面进入正题;

事件,通常来讲事件就是某种行为,laravel给我们定义了一个简单的模型,事件包含事件本身,订阅、监听器以及事件的发起;

按照上面的概念,我们来所以下定义:

事件本身(事件名称):一边来讲是以某个动作发生为名词,比如:OnClieck,OnCliecked,OnUserCreated,OnDbError等, 这里举例为:ExampleEvent;

事件监听器:就是一个简单事件用来,可用来做一些代码处理,这里我们叫:ExampleListener;

好的,基础工作确定好了,那么就开始编程呗;

首先定义好事件,在“AppEvents"下,创建文件"ExampleEvent.php",并编写如下代码:

<?php

namespace AppEvents;

class ExampleEvent extends Event
{
    public $data;
    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct($data)
    {
        //
        $this->data=$data;
    }
}

  

这样,我们就编写好一个事件原型;

然后,我们需要能够发起事件,我这里就直接在Controller发起,在”AppHttpControllers” 下创建名为 "ExamplerController",并编写一个方法叫 message,代码如下:

<?php

namespace AppHttpControllers;

use AppEventsExampleEvent;
 
class ExampleController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    public function message(){
        //TODO SOMETHING;

        $data = array(
            "hi"=>'Lingfeng',
            "world"=>"Chen"
        );

        event(new ExampleEvent($data));  //这里发起事件
    }

    //
}

  

好的,现在从代码角度来看,事件也有了,message function也触发了事件,那么事件发起后,谁监听、谁来用呢?

这时候得从启动项中找到点东东:

编辑/bootstrap/app.php,去掉register EventServiceProvider的注释;

$app->register(AppProvidersEventServiceProvider::class);

  

这样,EventServiceProvider 就能够使用了,但ExampleEvent依然没有谁来监听;

好的,在”AppListeners"下创建 "ExampleListener",并编写如下代码:

<?php

namespace AppListeners;

use AppEventsExampleEvent;
use IlluminateQueueInteractsWithQueue;
use IlluminateContractsQueueShouldQueue;
use IlluminateQueueListener;

class ExampleListener extends Listener
{
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  ExampleEvent  $event
     * @return void
     */
    public function handle(ExampleEvent $event)
    {
        //
        info("example listener");
var_dump($event);
}
}

  

在Handle中可以对event做各种操作了;

但事情没有结束,因为看起来代码都有了,可是依然没有任何一个地方讲 Event和Listener做关联;这个关联就在EventServiceProvider中

修改Provider代码如下:

<?php

namespace AppProviders;

use LaravelLumenProvidersEventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
    /**
     * The event listener mappings for the application.
     *
     * @var array
     */
    protected $listen = [
        'AppEventsExampleEvent' => [
            'AppListenersExampleListener',
        ],
    ];
}
EventServiceProvider

至此,大功告成;

配置好域名后,访问地址Http://localhost/example/message 

页面输出:

object(AppEventsExampleEvent)[22]
  public 'data' => 
    array (size=2)
      'hi' => string 'Lingfeng' (length=8)
      'world' => string 'Chen' (length=4)
ExampleEvent

同时检查log(storagelogslumen.log)

[2016-03-31 15:12:08] lumen.INFO: example listener
log


至此event 实现;再梳理下event相关流程:

HttpRequest ->

bootstarp/app.app  :   register/EventServiceProvider  map Event <-->Listener  ->

ExamplerController:  message  -> event(new ExampleEvent))->

ExamplerListener: handler->todo something;

如果希望同时注册多个方法做解析,可以采用订阅的方式:这时候需要做一些改造

<?php

namespace AppEvents;

use IlluminateContractsBroadcastingShouldBroadcast;
use IlluminateQueueSerializesModels;

class ExampleEvent extends Event implements ShouldBroadcast
{
    public $data;
    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct($data)
    {
        //
        $this->data=$data;
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return array
     */
    public function broadcastOn()
    {
        // TODO: Implement broadcastOn() method.
        return ['Example.message']; //广播,同时会携带上当前事件中的所有属性,这里是 $this->data;
    }
}
ExampleEvent
<?php

namespace AppListeners;

use AppEventsExampleEvent;
use IlluminateQueueInteractsWithQueue;
use IlluminateContractsQueueShouldQueue;
use IlluminateQueueListener;

class ExampleListener
{
    public function onMessage($event){
        echo "onMessage "."<br />";
        var_dump($event);
    }
    public function onMessage1($event){
        echo "onMessage1 "."<br />";
        var_dump($event);
    }
    /**
     * 为订阅者注册监听器
     *
     * @param IlluminateContractsEventsDispatcher $events
     * @return array
     */
    public function subscribe($events)
    {

        $events->listen(
            'AppEventsExampleEvent',
            'AppListenersExampleListener@onMessage'
        );
        $events->listen(
            'AppEventsExampleEvent',
            'AppListenersExampleListener@onMessage1'
        );
    }
}
ExampleListener
<?php

namespace AppProviders;

use AppListenersExampleListener;
use LaravelLumenProvidersEventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
    ///**
    // * The event listener mappings for the application.
    // *
    // * @var array
    // */
    //protected $listen = [
    //    'AppEventsExampleEvent' => [
    //        'AppListenersExampleListener',
    //    ],
    //];
    protected $subscribe =[
        ExampleListener::class
    ];
}
EventServiceProvider

这时候需要配置.env 复制.env.example 为 .env

需要给APP生成一个key

php artisan key:generate

填入db信息,填入QUEUE_DRIVER

APP_ENV=local
APP_DEBUG=true
APP_KEY=FPg9LRkHTj5j15ig7ETzQhG29r1sEWNR

B_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=lum
DB_USERNAME=root
DB_PASSWORD=
DB_PREFIX=LUM_  #表前缀

#CACHE_DRIVER=memcached
QUEUE_DRIVER=database

如果我们使用了数据库做QUERY,还需要配置上jobs 表:(上例就是用数据库做的)

Migrate Jobs

访问:

http://lumeventdemo.lingfengchen.com/example/message

返回内容:

onMessage 

object(AppEventsExampleEvent)[22]
  public 'data' => 
    array (size=2)
      'hi' => string 'Lingfeng' (length=8)
      'world' => string 'Chen' (length=4)

onMessage1 

object(AppEventsExampleEvent)[22]
  public 'data' => 
    array (size=2)
      'hi' => string 'Lingfeng' (length=8)
      'world' => string 'Chen' (length=4)
原文地址:https://www.cnblogs.com/lingfengchencn/p/5343390.html