事件处理器,事件,回调

请帮忙解释一下上述3者之间的关系?

在源码的说明中:

事件处理器的签名:


* <pre>

 * function eventHandler($event) { ... }

 * </pre>

事件处理器的具体细节:


* <pre>

 * public function onClick($event)

 * {

 *     $this->raiseEvent('onClick',$event);

 * }

在我依照看到的raiseEvent方法中的理解,其raiseEvent(‘onClick’,$event)中的onClick就是一个函数,

文档说明中的这句话:

  • An event is defined by the presence of a method whose name starts with ‘on’.

  • The event name is the method name. When an event is raised, functions

  • (called event handlers) attached to the event will be invoked automatically.

导致我的理解矛盾:现在的event是一个on开头的函数,event触发是就会回调这个函数。

按照上面的示例,我们现在有了这样一个onClick的event,同时又应该有一个全局onClick()函数;那现在这个事件处理器的签名又是怎样的呢?是public function onClick($event)?

文档下面的这段注释是绑定事件处理器

  • To attach an event handler to an event, see {@link attachEventHandler}.

  • You can also use the following syntax:

  • <pre>

  • $component->onClick=$callback; // or $component->onClick->add($callback);

  • </pre>

那我们写自己的事件处理器还需要写这段代码去实现绑定吗?

因为这里出现了很多的onClick()导致我的理解出现问题。

恕我愚钝。

其实做这么多的工作,我是想完成一件事(犹如codeigniter中的钩子样):我想在onBeginRequest()也既还没有把请求分发到控制器和动作行为上去,但我又得到了request对象(应该包括路由信息)时,做一些其他的额外动作,比如根据请求信息来判断用户是否有权限操作(当然这在控制器中的accessRules中也可以做到),这时我可能就需要在onBeginRequest()中做一点点额外的工作了。当然有时我还想写一些自己的事件处理器,这时系统预设的事件处理器就不够用了。

我还貌似发现在生命周期的过程中,onBeginRequset事件处理器貌似什么工作也没有做呀?

希望各位前辈能帮我解决迷惑,谢谢!

如有没有理解我说的什么,但感觉能帮上忙的请回帖告诉我(我自己都感觉在这个问题的阐述上含糊不清);

首先,如果你只是想判断用户权限的话,你可以考虑在controller基类的init()里进行判断(所有的controller都从这个基类派生)。

如果你希望响应onbeginRequest事件,你可以在app config里加如下的代码:

‘onBeginRequest’=>‘myfunc’

这样,每次请求,你的myfunc都会被调用。你可以在myfunc里得到Yii::app()->request。

在app的生命周期里,onBeginRequest的唯一目的就是调用绑定的事件响应函数,所以它本身并不做什么工作。

这个回答对我很有帮助,让我知道怎样在生命周期的各个阶段添加自定义事件,从而有了对系统的更多精细控制,这是一直以来我在使用yii的很大的一个问题,非常感谢,谢谢!

而下面又是是我的其他的几个迷惑

1.正如你所说可以在controller基类的init里做权限控制,但是这样的一个问题便是:控制器以及被分发(也即是控制器已经被实例化)了,我们为何不在初始化应用程序时(没有把请求分发到控制器时)就做权限控制呢,这似乎会更高效一些吧?

2,在分发请求之前做控制,我们还能对控制器进行控制(控制器本身也是ACL的一部分嘛),但是在yii的rbac文档中,我似乎没有看到这样的特性(当然我的英语是很差劲的,也许没有理解到文档里面的意义)?在请求分发之前要对控制器进行权限控制就应该知道你所请求的控制器id,然而我在CHttpRequest这个对象中似乎并没有看到有得到控制器id的属性或方法;(当然也许我可以笨一点的使用$_GET[‘r’]);

  1. 基于角色的访问控制中,似乎在执行每个请求时我们都需要重新来建立这样一个访问控制系统(是这样吗?)。重新建立一个访问控制系统是很低效的一件重复性劳动。我们是不是可以在用户的第一次请求时便建立用户的访问控制系统,和在基于某种事件(比如登录成功)后来改变用户的权限,一旦建立起权限或更改之后,这便是一个可读的权限序列,以后用户发送请求,我们只需要读这个权限序列便好,而不用重新建立角色,任务和操作。

(也许在理解某些问题的时候,我的思想受到已有框架的束缚,也有可能是没明白yii甚者是php的工作机制,希望你们能帮我指正,谢谢。)

其实效率不是问题,因为你希望的是能正常访问的页面效率高,而不允许访问的页面的效率低点没关系(因为这是不正常状态)。事实上,这里的效率差别只是初始化一个控制器实例而已。

另外一个更主要的原因是,module/controller/action的解析是一个比较复杂的过程,单单靠CHttpRequest是不够的,还需要结合CUrlManager和具体的目录结构。比如一个请求r=a/b,它可能有四种解析结果:

  1. controller a, action b

  2. module a, controller b, default action

  3. directory a, controller b, default action

  4. module a, module b, default controller, default action

关于RBAC,建立其权限结构是一次性工作,一般在命令行里完成。如果你需要管理RBAC,那么需要额外的界面进行维护。正常的页面访问,你只需要调用checkAccess。