【问题标题】:phalconphp Access controllerName that triggered a eventphalconphp 访问触发事件的控制器名称
【发布时间】:2014-04-25 13:42:28
【问题描述】:

如何从事件本身引用触发 beforeExecuteRoute 的 controllerName 和 actionName?

<?php
use Phalcon\Events\Manager as EventsManager;

//Create a events manager
$eventManager = new EventsManager();

//Listen all the application events
$eventManager->attach('micro', function($event, $app) {

    if ($event->getType() == 'beforeExecuteRoute') {
        //how to get controller name to handle acl stuff
    }
});

【问题讨论】:

    标签: php events phalcon


    【解决方案1】:

    来自文档 - http://docs.phalconphp.com/en/latest/api/Phalcon_Mvc_Dispatcher.html

    getModuleName () - Gets the module where the controller class is
    getControllerName () - Gets last dispatched controller name
    getActionName () - Gets the lastest dispatched action name
    

    例子:

    <?php
    use Phalcon\Events\Manager as EventsManager;
    
    //Create a events manager
    $eventManager = new EventsManager();
    
    //Listen all the application events
    $eventManager->attach('micro', function($event, $app) { 
        if ($event->getType() == 'beforeExecuteRoute') {            
            $controllerName = $app->getControllerName();
            $moduleName = $app->getModuleName();
            $actionName = $app->getActionName();          
        }
    });
    

    【讨论】:

    【解决方案2】:

    这样你就可以得到字符串格式的路由来解析它:

    $router->getMatchedRoute()->getPattern();
    

    希望对您有所帮助。我发现没有其他方法可以做到这一点。

    【讨论】:

      【解决方案3】:

      如果您没有调度程序,您必须从路由器获取这些值。我对微应用的细节不是很熟悉,但是看文档应该是这样的。

      <?php
      use Phalcon\Events\Manager as EventsManager;
      
      //Create a events manager
      $eventManager = new EventsManager();
      
      //Listen all the application events
      $eventManager->attach('micro', function($event, $app) {
      
          if ($event->getType() == 'beforeExecuteRoute') {
              //how to get controller name to handle acl stuff
      
              DI::getDefault()->get('router')->getControllerName();
              DI::getDefault()->get('router')->getActionName();
      
              // or
      
              $app->getRouter()->getControllerName();
              $app->getRouter()->getActionName();
          }
      });
      

      这行得通吗?

      【讨论】:

        【解决方案4】:

        我实际上遇到了类似的困惑,但是其他答案没有帮助,并且 Phalcon 的官方文档没有找到正确的方法,所以如果您使用的是 Micro,很难找到有效的答案在网上。所以我之前用自己的反思来了解Phalcon的,最后得出以下答案,希望对你有所帮助。祝你好运!

        <?php
        
        $eventsManager = new \Phalcon\Events\Manager();
        $eventsManager->attach(
            'micro:beforeExecuteRoute',
            function (\Phalcon\Events\Event $event, $app) {
                $controllerName = $event->getSource()->getActiveHandler()[0]->getDefinition();
                $actionName = $event->getSource()->getActiveHandler()[1];
            }
        );
        
        $app = new \Phalcon\Mvc\Micro($di);
        $app->setEventsManager($eventsManager);
        

        如果你想用 before 事件实现 ACL,下面的 AclAnnotation 代码可能会有所帮助:

        <?php
        
        class AclAnnotation
        {
            protected $private = true;
            protected $roles = [];
            protected $component = [];
            protected $access = [];
        
            public function __construct($event, $app)
            {
                $controllerName = $event->getSource()->getActiveHandler()[0]->getDefinition();
                $actionName = $event->getSource()->getActiveHandler()[1];
        
                $reflector   = $app->annotations->get($controllerName);
                $annotations = $reflector->getClassAnnotations();
                if (!$annotations) {
                    throw new ErrorException('The permission configuration is abnormal. Please check the resource permission comments.');
                    return;
                }
        
                if (
                    $annotations->has('Private')
                    && ($annotation = $annotations->get('Private'))->numberArguments() > 0
                ) {
                    $this->private = $annotation->getArguments('Private')[0];
                }
        
                if (
                    $annotations->has('Roles')
                    && ($annotation = $annotations->get('Roles'))->numberArguments() > 0
                ) {
                    $this->roles = $annotation->getArguments('Roles');
                }
        
                if (
                    $annotations->has('Components')
                    && ($annotation = $annotations->get('Components'))->numberArguments() > 0
                ) {
                    $this->components = $annotation->getArguments('Components');
                }
        
                $annotations = $app->annotations->getMethod($controllerName, $actionName);
                if (
                    $annotations->has('Access')
                    && ($annotation = $annotations->get('Access'))->numberArguments() > 0
                ) {
                    $this->access = $annotation->getArguments('Access');
                }
            }
        
            public function isPrivate()
            {
                return $this->private;
            }
        
            public function getRoles()
            {
                return $this->roles;
            }
        
            public function getComponents()
            {
                return $this->components;
            }
        
            public function getAccess()
            {
                return $this->access;
            }
        }
        

        在 index.php 中创建事件监听器:

        <?php
        
            $eventsManager = new \Phalcon\Events\Manager();
            $eventsManager->attach(
                'micro:beforeExecuteRoute',
                function (\Phalcon\Events\Event $event, $app) {
                    $aclAnnotation = new AclAnnotation($event, $app);
                    if (!$aclAnnotation->isPrivate()) {
                        return true;
                    }
        
                    $acl = $app->currentACL;
                    // Verify that you have access permission for the interface
                    if (!$acl->isAllowed($aclAnnotation->getRoles(), $aclAnnotation->getComponents(), $aclAnnotation->getAccess())) {
                        throw new \ErrorException('You do not have access to the resource', 40001);
                        return false;
                    }
        
                    return true;
                }
            );
        
            $app = new \Phalcon\Mvc\Micro($di);
            $app->setEventsManager($eventsManager);
        

        关于注解的使用,可以参考这里:

        https://docs.phalcon.io/5.0/en/annotations

        【讨论】:

        • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
        猜你喜欢
        • 1970-01-01
        • 2014-04-20
        • 2019-06-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多