制作簡單的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 | 在退出循環調度后觸發。 | 否 | 偵聽者 |
