laravel Model 事件阻止listen

1. Laravel 的事件如果走Listener类,则Handler方法返回false 会阻止事件继续下发;

Illuminate\Events\Dispatcher;
public function dispatch($event, $payload = [], $halt = false)
{
    // When the given "event" is actually an object we will assume it is an event
    // object and use the class as the event name and this event itself as the
    // payload to the handler, which makes object based events quite simple.
    list($event, $payload) = $this->parseEventAndPayload(
        $event, $payload
    );

    if ($this->shouldBroadcast($payload)) {
        $this->broadcastEvent($payload[0]);
    }

    $responses = [];

    foreach ($this->getListeners($event) as $listener) {
        $response = $listener($event, $payload);

        // If a response is returned from the listener and event halting is enabled
        // we will just return this response, and not call the rest of the event
        // listeners. Otherwise we will add the response on the response list.
        if ($halt && ! is_null($response)) {
            return $response;
        }

        // If a boolean false is returned from a listener, we will stop propagating
        // the event to any further listeners down in the chain, else we keep on
        // looping through the listeners and firing every one in our sequence.
        if ($response === false) {
            break;
        }

        $responses[] = $response;
    }

2.如果是Model的内置事件,则return false 不会阻止已注册事件的处理;但是通过Model的 

/**
 * The event map for the model.
 *
 * Allows for object-based events for native Eloquent events.
 *
 * @var array
 */
protected $dispatchesEvents = [];

此属性算为自定义事件列表,在触发处理后返回false 会打断事件的下发处理,见:

/**
 * Fire the given event for the model.
 *
 * @param  string  $event
 * @param  bool  $halt
 * @return mixed
 */
protected function fireModelEvent($event, $halt = true)
{
    if (! isset(static::$dispatcher)) {
        return true;
    }

    // First, we will get the proper method to call on the event dispatcher, and then we
    // will attempt to fire a custom, object based event for the given event. If that
    // returns a result we can return that result, or we'll call the string events.
    $method = $halt ? 'until' : 'fire';

    $result = $this->filterModelEventResults(
        $this->fireCustomModelEvent($event, $method)
    );

    if ($result === false) {
        return false;
    }

    return ! empty($result) ? $result : static::$dispatcher->{$method}(
        "eloquent.{$event}: ".static::class, $this
    );
}

 

对于Model内置事件:

比如某个Model的Updated事件,里面做了一个又会触发该model的update事件,会死循环直到最大执行时间。

如果一般认为return false;可以起到作用,但是不可以,只有自定义的事件可以起作用,内置的不可行。

方案一:

stackoverflow上

           //updated listener里面 


            //禁止事件分发器
            $dispatcher = $model->getEventDispatcher();
            $model->unsetEventDispatcher();
            //此处为可触发updated事件的业务code
            $model->update();
            //完事恢复现场
            $model->setEventDispatcher($dispatcher);
            

          

类似的:

方案二:
$event = 'eloquent.updated: '. get_class($model);//注意冒号后有一个空格
$listener = $model->getEventDispatcher()->getListeners($event);
$model->getEventDispatcher()->forget($event);

//此处为可触发updated事件的业务code
$model->update();
//此处为可触发updated事件的业务code end

$model->getEventDispatcher()->listen($event, $listener);

 

转载于:https://my.oschina.net/u/3659172/blog/3033529

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值