Phalcon学习笔记(6)分发器和事件管理器
2015-06-19 12:43
357 查看
Phalcon启动之后,会通过router路由器将URL解析,然后传递给dispatcher分发器,分发器会找到对应的Module/Controller/Action并执行,执行中会输出到view视图发送给客户端。
简单情况下分发器不需要特殊的配置,router的解析已经足够,一般来讲,只有在判断用户权限的时候才需要特殊处理
$di->set('dispatcher', function () {
$dispatcher = new \Phalcon\Mvc\Dispatcher();
//Attach a event listener to the dispatcher
$eventManager = new \Phalcon\Events\Manager();
$eventManager->attach('dispatch:beforeDispatch', new \SecurityPlugin(__CLASS__));
$dispatcher->setEventsManager($eventManager);
$dispatcher->setDefaultNamespace('Multiple\Entrance\Controllers\\');
return $dispatcher;
});
实际上Phalcon内建有事件机制,在Phalcon的很多类中都有事件接口,通过对事件接口的重新定义并挂载事件管理器,可以让个各类针对不同的情况在程序执行的特殊阶段做出不同的反映,比如跳转回主页之类。
\Phalcon\Events\Manager类通过attach函数的第一个参数定义流程控制类的某个特殊事件,通过第二个参数定义对应的行为,然后在流程控制对象中使用setEventsManager函数挂上这个事件控制器类,就可以在特定的事件发生时,调用事件控制器定义的行为,如果行为执行正常会返回程序主线,如果行为执行之后跳出了流程,就不会返回了。
常见的被视为跳出流程的标志有:1)返回false;2)重定向;3)强行中止;4)抛出异常
如果返回null或者true则会返回主线继续执行。
也就是说attach函数的第2个参数其实才是主要问题。实际上笔者的习惯是把用户权限判定放在那里。
对于分发器而言,内建有一些事件定义。对于其他的类,也有事件定义,可以参考各个类的官方手册。
来看一个稍微复杂点的事件管理器,它可以在找不到对应的Controller/Action时,做出合适的处理,不让用户看到难看的404错误
$di->setShared('dispatcher', function() {
//Create/Get an EventManager
$eventsManager = new Phalcon\Events\Manager();
//Attach a listener
$eventsManager->attach("dispatch", function($event, $dispatcher, $exception) {
//The controller exists but the action not
if ($event->getType() == 'beforeNotFoundAction') {
$dispatcher->forward(array(
'controller' => 'index',
'action' => 'show404'
));
return false;
}
//Alternative way, controller or action doesn't exist
if ($event->getType() == 'beforeException') {
switch ($exception->getCode()) {
case Phalcon\Dispatcher::EXCEPTION_HANDLER_NOT_FOUND:
case Phalcon\Dispatcher::EXCEPTION_ACTION_NOT_FOUND:
$dispatcher->forward(array(
'controller' => 'index',
'action' => 'show404'
));
return false;
}
}
});
$dispatcher = new Phalcon\Mvc\Dispatcher();
//Bind the EventsManager to the dispatcher
$dispatcher->setEventsManager($eventsManager);
return $dispatcher;
});
分发器的另外一个用途是让我们从一个Controller/Action跳转到另一个Controller/Action
<?php
class PostsController extends \Phalcon\Mvc\Controller
{
public function indexAction()
{
}
public function saveAction($year, $postTitle)
{
// .. store some product and forward the user
// Forward flow to the index action
$this->dispatcher->forward(array(
"controller" => "post",
"action" => "index"
));
}
}
请记住,forward和HTTP重定向不一样,虽然他们显示了相同的结果。forward不刷新当前页面,所有的重定向都发生在一个单一的请求中,而HTTP重定向则需要完成两个请求。
另外在多Module程序中,forward不能跳到另一个Module,而HTTP重定向可以。这个时候使用下面的代码实现跳转
$this->response->redirect('entrance/index/login');
forward还有一些用法
// Forward flow to another action in the current controller
$this->dispatcher->forward(array(
"action" => "search"
));
// Forward flow to another action in the current controller
// passing parameters
$this->dispatcher->forward(array(
"action" => "search",
"params" => array(1, 2, 3)
));
// Forward flow to another action in the current controller
// passing parameters
$this->dispatcher->forward(array(
"action" => "search",
"params" => array(1, 2, 3)
));
另外还可以通过getParam函数获取一些URL的信息
// Get the post's title passed in the URL as parameter
$title = $this->dispatcher->getParam("title");
// Get the post's year passed in the URL as parameter
// also filtering it
$year = $this->dispatcher->getParam("year", "int");
这些信息可以让程序做出针对性的反应
简单情况下分发器不需要特殊的配置,router的解析已经足够,一般来讲,只有在判断用户权限的时候才需要特殊处理
$di->set('dispatcher', function () {
$dispatcher = new \Phalcon\Mvc\Dispatcher();
//Attach a event listener to the dispatcher
$eventManager = new \Phalcon\Events\Manager();
$eventManager->attach('dispatch:beforeDispatch', new \SecurityPlugin(__CLASS__));
$dispatcher->setEventsManager($eventManager);
$dispatcher->setDefaultNamespace('Multiple\Entrance\Controllers\\');
return $dispatcher;
});
实际上Phalcon内建有事件机制,在Phalcon的很多类中都有事件接口,通过对事件接口的重新定义并挂载事件管理器,可以让个各类针对不同的情况在程序执行的特殊阶段做出不同的反映,比如跳转回主页之类。
\Phalcon\Events\Manager类通过attach函数的第一个参数定义流程控制类的某个特殊事件,通过第二个参数定义对应的行为,然后在流程控制对象中使用setEventsManager函数挂上这个事件控制器类,就可以在特定的事件发生时,调用事件控制器定义的行为,如果行为执行正常会返回程序主线,如果行为执行之后跳出了流程,就不会返回了。
常见的被视为跳出流程的标志有:1)返回false;2)重定向;3)强行中止;4)抛出异常
如果返回null或者true则会返回主线继续执行。
也就是说attach函数的第2个参数其实才是主要问题。实际上笔者的习惯是把用户权限判定放在那里。
对于分发器而言,内建有一些事件定义。对于其他的类,也有事件定义,可以参考各个类的官方手册。
Event Name | Triggered | Can stop operation? |
---|---|---|
beforeDispatchLoop | Triggered before enter in the dispatch loop. At this point the dispatcher don’t know if the controller or the actions to be executed exist. The Dispatcher only knows the information passed by the Router. | Yes |
beforeDispatch | Triggered after enter in the dispatch loop. At this point the dispatcher don’t know if the controller or the actions to be executed exist. The Dispatcher only knows the information passed by the Router. | Yes |
beforeExecuteRoute | Triggered before execute the controller/action method. At this point the dispatcher has been initialized the controller and know if the action exist. | Yes |
afterExecuteRoute | Triggered after execute the controller/action method. As operation cannot be stopped, only use this event to make clean up after execute the action | No |
beforeNotFoundAction | Triggered when the action was not found in the controller | Yes |
beforeException | Triggered before the dispatcher throws any exception | Yes |
afterDispatch | Triggered after execute the controller/action method. As operation cannot be stopped, only use this event to make clean up after execute the action | Yes |
afterDispatchLoop | Triggered after exit the dispatch loop | No |
$di->setShared('dispatcher', function() {
//Create/Get an EventManager
$eventsManager = new Phalcon\Events\Manager();
//Attach a listener
$eventsManager->attach("dispatch", function($event, $dispatcher, $exception) {
//The controller exists but the action not
if ($event->getType() == 'beforeNotFoundAction') {
$dispatcher->forward(array(
'controller' => 'index',
'action' => 'show404'
));
return false;
}
//Alternative way, controller or action doesn't exist
if ($event->getType() == 'beforeException') {
switch ($exception->getCode()) {
case Phalcon\Dispatcher::EXCEPTION_HANDLER_NOT_FOUND:
case Phalcon\Dispatcher::EXCEPTION_ACTION_NOT_FOUND:
$dispatcher->forward(array(
'controller' => 'index',
'action' => 'show404'
));
return false;
}
}
});
$dispatcher = new Phalcon\Mvc\Dispatcher();
//Bind the EventsManager to the dispatcher
$dispatcher->setEventsManager($eventsManager);
return $dispatcher;
});
分发器的另外一个用途是让我们从一个Controller/Action跳转到另一个Controller/Action
<?php
class PostsController extends \Phalcon\Mvc\Controller
{
public function indexAction()
{
}
public function saveAction($year, $postTitle)
{
// .. store some product and forward the user
// Forward flow to the index action
$this->dispatcher->forward(array(
"controller" => "post",
"action" => "index"
));
}
}
请记住,forward和HTTP重定向不一样,虽然他们显示了相同的结果。forward不刷新当前页面,所有的重定向都发生在一个单一的请求中,而HTTP重定向则需要完成两个请求。
另外在多Module程序中,forward不能跳到另一个Module,而HTTP重定向可以。这个时候使用下面的代码实现跳转
$this->response->redirect('entrance/index/login');
forward还有一些用法
// Forward flow to another action in the current controller
$this->dispatcher->forward(array(
"action" => "search"
));
// Forward flow to another action in the current controller
// passing parameters
$this->dispatcher->forward(array(
"action" => "search",
"params" => array(1, 2, 3)
));
// Forward flow to another action in the current controller
// passing parameters
$this->dispatcher->forward(array(
"action" => "search",
"params" => array(1, 2, 3)
));
另外还可以通过getParam函数获取一些URL的信息
// Get the post's title passed in the URL as parameter
$title = $this->dispatcher->getParam("title");
// Get the post's year passed in the URL as parameter
// also filtering it
$year = $this->dispatcher->getParam("year", "int");
这些信息可以让程序做出针对性的反应
相关文章推荐
- LAMP下安装phalcon
- Phalcon学习笔记(4)视图入门
- Phalcon学习笔记(3)目录结构与命名约定
- Phalcon学习笔记(2)DI依赖注入器和加载器
- Phalcon 扩展安装,测试
- Phalcon 常用函数 方法
- PHP调用google translate中解决中文返回乱码
- Phalcon框架在读取和写入数据库时产生中文乱码
- Phalcon笔记学习笔记
- phalcon学习笔记
- phalcon使用经验杂谈
- phalcon 一些开发注意事项和redis配置
- centos linux phalcon扩展
- [Phalcon]请求volt与请求json的性能压测对比
- 【Phalcon】路由拆分
- 【Phalcon】Hello Phalcon!
- php常用框架压力测试
- 欢迎使用CSDN-markdown编辑器
- Phalcon 学习笔记
- 【Phalcon】Phalcon多平台的安装配置