2015-06-28 23:22:07 3176次浏览 2条回答 0 悬赏 20 金钱

对于 YII的事件,我有一个疑问哈~ :在绑定的时候,如果是绑定一个系统函数,则直接传递一个函数名即可,但是在触发的时候,传递给函数的参数是$event,而$event是一个对象,但是对于PHP的系统函数,它们需要的参数是各种各样的,它怎么能正确处理呢?

最佳答案

  • jackz 发布于 2015-06-29 00:09 举报

    是这样的

    // this handler is a global function
    $foo->on(Foo::EVENT_HELLO, 'function_name');
    //全局函数不是系统函数的意思,就是你自己定义的函数,所以你调用的时候还是
    function function_name($event) {
        echo $event->data;
    }
    
    //你可以看看trigger是怎么调用callback function的
        public function trigger($name, Event $event = null)
        {
            $this->ensureBehaviors();
            if (!empty($this->_events[$name])) {
                if ($event === null) {
                    $event = new Event;
                }
                if ($event->sender === null) {
                    $event->sender = $this;
                }
                $event->handled = false;
                $event->name = $name;
                foreach ($this->_events[$name] as $handler) {
                    $event->data = $handler[1];  //on绑定传过来的数据
                    call_user_func($handler[0], $event);  //0是具体的函数,这里看出是没办法解决 系统函数参数的问题
                    // stop further handling if the event is handled
                    if ($event->handled) {
                        return;
                    }
                }
            }
            // invoke class-level attached handlers
            Event::trigger($this, $name, $event);
        }
    

    所以我的看法是应该不会直接绑定系统函数

    2 条回复
    回复于 2015-06-29 10:56 回复

    所以就是说,系统函数是不能直接绑定的,如果要绑定,也必须重新封装一下,变成这种形式的函数~ 我就是误会了那个全局函数,以为就是说的系统函数,非常感谢你的回答,现在非常明白了~

    回复于 2015-06-30 00:38 回复

    其实我也在想为什么他不想用call_user_func_array,这样子系统函数也能使用了

    , 觉得很赞
  • 回答于 2015-06-29 08:40 举报

    可以看一下on方法如下,第四个参数可以传递参数到$event里面。然后回调函数可以在$event里面获取想要的变量值。
    \yii\base\Event.php

    /**
     * Attaches an event handler to a class-level event.
     *
     * When a class-level event is triggered, event handlers attached
     * to that class and all parent classes will be invoked.
     *
     * For example, the following code attaches an event handler to `ActiveRecord`'s
     * `afterInsert` event:
     *
     * ~~~
     * Event::on(ActiveRecord::className(), ActiveRecord::EVENT_AFTER_INSERT, function ($event) {
     *     Yii::trace(get_class($event->sender) . ' is inserted.');
     * });
     * ~~~
     *
     * The handler will be invoked for EVERY successful ActiveRecord insertion.
     *
     * For more details about how to declare an event handler, please refer to [[Component::on()]].
     *
     * @param string $class the fully qualified class name to which the event handler needs to attach.
     * @param string $name the event name.
     * @param callable $handler the event handler.
     * @param mixed $data the data to be passed to the event handler when the event is triggered.
     * When the event handler is invoked, this data can be accessed via [[Event::data]].
     * @param boolean $append whether to append new event handler to the end of the existing
     * handler list. If false, the new handler will be inserted at the beginning of the existing
     * handler list.
     * @see off()
     */
    public static function on($class, $name, $handler, $data = null, $append = true)
    {
        $class = ltrim($class, '\\');
        if ($append || empty(self::$_events[$name][$class])) {
            self::$_events[$name][$class][] = [$handler, $data];
        } else {
            array_unshift(self::$_events[$name][$class], [$handler, $data]);
        }
    }
    
    1 条回复
    回复于 2015-06-29 10:54 回复

    谢谢,不过楼上的兄弟解释的更易懂一点,就采纳他的啦,不过还是非常感谢~

    觉得很赞
您需要登录后才可以回答。登录 | 立即注册
chjbo0
见习主管

chjbo0 diqiu

注册时间:2012-02-28
最后登录:2015-08-11
在线时长:2小时54分
  • 粉丝2
  • 金钱390
  • 威望0
  • 积分410

热门问题