2018-06-16 00:26:58 1621次浏览 1条回答 0 悬赏 10 金钱

事件在触发的时候能不能传值,即将事件触发时传某一个变量给 hander ?举个栗子:
我用curl请求时,我希望在curl请求前触发一个 发送前事件,并希望在 hander 里运行的时候打印出这个curl的链接。
我知道赋值给 sender 的属性可以在 hander 通过 $event->sender 获取到,另外也可以通过其他方法(非事件)做到这样的效果,只是想问有没有其他优雅些的方法
还有 Event::$data 这个属性设置来干嘛的,在注册事件的时候传值给 hander ?很鸡肋好么。。

  • 回答于 2018-11-15 13:49 举报

    Event::$data是在绑定事件handler的时候确定的,也就是后续事件触发执行handler时的函数参数。
    事件触发的时候,最关键的就是事件对象,这是你发挥的地方。

    public function on($name, $handler, $data = null, $append = true)
        {
            $this->ensureBehaviors();
    
            if (strpos($name, '*') !== false) {
                if ($append || empty($this->_eventWildcards[$name])) {
                    $this->_eventWildcards[$name][] = [$handler, $data];
                } else {
                    array_unshift($this->_eventWildcards[$name], [$handler, $data]);
                }
                return;
            }
    
            if ($append || empty($this->_events[$name])) {
                $this->_events[$name][] = [$handler, $data];
            } else {
                //$data就是handler的参数
                array_unshift($this->_events[$name], [$handler, $data]);
            }
        }
    

    事件触发时,trigger方法的第一个参数$name就是事件名称字符串而已,但是第二个参数$event可以自定义。

        public function trigger($name, Event $event = null)
        {
            $this->ensureBehaviors();
    
            $eventHandlers = [];
            foreach ($this->_eventWildcards as $wildcard => $handlers) {
                if (StringHelper::matchWildcard($wildcard, $name)) {
                    $eventHandlers = array_merge($eventHandlers, $handlers);
                }
            }
    
            if (!empty($this->_events[$name])) {
                $eventHandlers = array_merge($eventHandlers, $this->_events[$name]);
            }
    
            if (!empty($eventHandlers)) {
                if ($event === null) {
                    $event = new Event();
                }
                if ($event->sender === null) {
                    $event->sender = $this;
                }
                $event->handled = false;
                $event->name = $name;
                foreach ($eventHandlers as $handler) {
                    $event->data = $handler[1];
                    call_user_func($handler[0], $event);
                    // stop further handling if the event is handled
                    if ($event->handled) {
                        return;
                    }
                }
            }
    
            // invoke class-level attached handlers
            Event::trigger($this, $name, $event);
        }
    

    你想在发送请求前触发事件,明显应该是自定义的事件吧,所以事件对象你也可以自己定义哦,想要啥变量都传给这个自定义的事件对象就OK!
    咋样?这个问题半年了没人理会,今天大海捞针看了有点想法就说说。

您需要登录后才可以回答。登录 | 立即注册
被绑票的粽子
试用期

被绑票的粽子

注册时间:2017-04-18
最后登录:2018-07-13
在线时长:0小时46分
  • 粉丝0
  • 金钱20
  • 威望0
  • 积分20

热门问题