phalcon: eventManager事件管理(结合dispatcher调度控制器)制作简单的acl

时间:2021-12-12 03:34:13

制作简单的acl,

dispatcher(专门用来加载或调度或跳转到相应的url地址即XXXcontroller的调度器或控制器,能够在controller执行前对controller进行停止跳转等),控制器提供了一堆可以被调用的方法,即:action。action是控制器中用于处理请求的方法。默认情况下,全部 控制器public的方法都会映射到action并且可以通过URL访问。action负责解释请求和创建响应.

public/index.php

$di['aclResource'] = function()
{
return include_once '../app/config/Acl.php';
}; //security
$di['dispatcher'] = function(){
//events
$eventsManager = new \Phalcon\Events\Manager(); //读取acl权限的类
$security = new Security(); //lisent
$eventsManager->attach("dispatch", $security); //调度器通过事件侦听acl
$dispatch = new \Phalcon\Mvc\Dispatcher();
$dispatch->setEventsManager($eventsManager);
return $dispatch;
}

  

app/plugins/Security类
use \Phalcon\Mvc\User\Plugin,
\Phalcon\Events\Event,
\Phalcon\Mvc\Dispatcher; class Security extends Plugin { public function __construct(){} public function _getAcl()
{
$acl = new \Phalcon\Acl\Adapter\Memory();
//默认权限(禁止)
$acl->setDefaultAction(\Phalcon\Acl::DENY);
//
$aclResource = $this->_custAcl();
foreach($aclResource as $key=>$value)
{
//创建角色,将角色添加到acl
$acl->addRole($value['project_name']);
foreach($value['resource'] as $ky=>$vy)
{
foreach($vy as $k=>$v)
{
//添加资源
$acl->addResource(new \Phalcon\Acl\Resource(strtolower($ky)), $v);
//添加访问权限
$acl->allow($value['project_name'], strtolower($ky), $v);
}
}
}
return $acl;
} public function _custAcl()
{
if( $this->persistent->acl == null)
{
$aclResource = array();
$acl = $this->aclResource['Acl'];
$allResource = $this->aclResource['AllResource'];
foreach($acl as $key=>$value)
{
$tomer = array();
$tomer['project_name'] = $value;
foreach($allResource as $k=>$v)
{
if( strpos($k, strtolower($key) ) !== false )
{
$tomer['resource'] = $v;
}
}
$aclResource[$key] = $tomer;
}
$this->persistent->acl = $aclResource; }
return $this->persistent->acl; } public function beforeExecuteRoute(Event $event, Dispatcher $dispatcher )
{
$controller = $dispatcher->getControllerName();
$action = $dispatcher->getactionName();
$role = '';
if( $this->session->has('userInfo') )
{
$userInfo = $this->session->get('userInfo');
$role = $userInfo['role'];
}
if(empty($role))$role = 'Operator';
$acl = $this->_getAcl();
$isAllowed = $acl->isAllowed($role, strtolower($controller), strtolower($action));
if(!$isAllowed)
{
// echo "no access;";exit;
$dispatcher->forward(array(
'controller'=>'index',
'action'=>'error',
'params'=>array('msg'=>'no access')
));


       }

    }

}

  

那么,在indexController.php页面中,可以通过如下方法,获取params传过来的值:

public function errorAction()
{
//获取传过来的参数
$param = $this->dispatcher->getParams();
$msg = isset($param['msg'])? $param['msg'] : '' ; $this->view->web_title = '错误';
$this->view->pick('index/error');
}

  

循环调度事件(Dispatch Loop Events)

Phalcon\Mvc\Dispatcher 可以发送事件给当前的 EventsManager 。 事件会以“dispatch”类型被所触发。当返回false时有些事件可以终止当前激活的操作。已支持的事件如下:

事件名称 何时触发 此操作是否可终止? 触发于
beforeDispatchLoop 在进入循环调度前触发。此时,调度器不知道将要执行的控制器或者动作是否存在。调度器只知道路由传递过来的信息。 侦听者
beforeDispatch 在进入循环调度后触发。此时,调度器不知道将要执行的控制器或者动作是否存在。调度器只知道路由传递过来的信息。 侦听者
beforeExecuteRoute 在执行控制器/动作方法前触发。此时,调度器已经初始化了控制器并知道动作是否存在。 侦听者/控制器
initialize 允许在请求中全局初始化控制器。 控制器
afterExecuteRoute 在执行控制器/动作方法后触发。由于此操作不可终止,所以仅在执行动作后才使用此事件进行清理工作。 侦听者/控制器
beforeNotFoundAction 当控制器中的动作找不到时触发。 侦听者
beforeException 在调度器抛出任意异常前触发。 侦听者
afterDispatch 在执行控制器/动作方法后触发。由于此操作不可终止,所以仅在执行动作后才使用此事件进行清理工作。 侦听者
afterDispatchLoop 在退出循环调度后触发。 侦听者