【问题标题】:ZF2 - Get controller name into layout/viewsZF2 - 将控制器名称放入布局/视图
【发布时间】:2012-02-09 05:09:37
【问题描述】:

我知道在 ZF1 中,您可以使用自定义 View Helpers 检索模块/控制器名称,这将获取单例 frontController 对象并在那里获取名称。

使用 ZF2,因为他们已经废除了框架的许多单例性质并引入了 DI,我在此模块中为我的所有控制器指定了别名...我可以想象我会通过访问 DI 或可能会将当前名称注入到布局中。

任何人都知道你会怎么做。我猜有一百种不同的方法,但在嗅探代码几个小时后,我真的无法弄清楚它现在是如何完成的。

我想要控制器名称的原因是将其作为特定控制器样式的类添加到主体中。

谢谢,多姆

【问题讨论】:

    标签: php zend-framework zend-framework-mvc zend-framework2


    【解决方案1】:

    在 Zend-3 框架中的控制器中获取控制器/动作名称

    private function getControllerActionName()
    {
        $currentController = $this->getEvent()->getRouteMatch()->getParam('controller', 'index');
        $explode_controller = explode('\\', $currentController);
        $currentController = strtolower(array_pop($explode_controller));
        $currentController = str_replace('controller', '', $currentController);
        $currentAction = strtolower($this->getEvent()->getRouteMatch()->getParam('action', 'index'));
        return array(
                'controller' => $currentController,
                'action' => $currentAction,
            );
    }
    

    它对我有用。我希望,这也会对你有所帮助。感谢您提出这个问题。

    【讨论】:

      【解决方案2】:
      $this->getHelperPluginManager()->getServiceLocator()->get('application')
           ->getMvcEvent()->getRouteMatch()->getParam('action', 'index');
      
      $controller = $this->getHelperPluginManager()->getServiceLocator()
                         ->get('application')->getMvcEvent()->getRouteMatch()
                         ->getParam('controller', 'index');
      
      
      $controller = explode('\\', $controller);
      
      print_r(array_pop($controller));
      

      【讨论】:

      • 你介意用一些 cmets 包裹你的 code-only-answer 吗?
      【解决方案3】:

      我为此创建了 CurrentRoute View Helper。

      安装它:

      composer require tasmaniski/zf2-current-route
      

      config/application.config.php中注册模块:

      'modules' => array(
          '...',
          'CurrentRoute'
      ),
      

      在任何视图/布局文件中使用它:

      $this->currentRoute()->getController();  // return current controller name
      $this->currentRoute()->getAction();      // return current action name
      $this->currentRoute()->getModule();      // return current module name
      $this->currentRoute()->getRoute();       // return current route name
      

      你可以看到完整的文档和代码https://github.com/tasmaniski/zf2-current-route

      【讨论】:

        【解决方案4】:

        我想在导航菜单部分访问当前模块/控制器/路由名称,没有办法,只能实现自定义视图助手并访问它,我想出了以下内容,我在这里发布。

        <?php
        namespace Application\View\Helper;
        
        use Zend\View\Helper\AbstractHelper;
        
        /**
         * View Helper to return current module, controller & action name.
         */
        class CurrentRequest extends AbstractHelper
        {
            /**
             * Current Request parameters
             *
             * @access protected
             * @var array
             */
            protected $params;
        
            /**
             * Current module name.
             *
             * @access protected
             * @var string
             */
            protected $moduleName;
        
            /**
             * Current controller name.
             *
             * @access protected
             * @var string
             */
            protected $controllerName;
        
            /**
             * Current action name.
             *
             * @access protected
             * @var string
             */
            protected $actionName;
        
            /**
             * Current route name.
             *
             * @access protected
             * @var string
             */
            protected $routeName;
        
            /**
             * Parse request and substitute values in corresponding properties.
             */
            public function __invoke()
            {
                $this->params = $this->initialize();
                return $this;
            }
        
            /**
             * Initialize and extract parameters from current request.
             *
             * @access protected
             * @return $params array
             */
            protected function initialize()
            {
                $sm = $this->getView()->getHelperPluginManager()->getServiceLocator();
                $router = $sm->get('router');
                $request = $sm->get('request');
                $matchedRoute = $router->match($request);
                $params = $matchedRoute->getParams();
                /**
                 * Controller are defined in two patterns.
                 * 1. With Namespace
                 * 2. Without Namespace.
                 * Concatenate Namespace for controller without it.
                 */
                $this->controllerName = !strpos($params['controller'], '\\') ?
                    $params['__NAMESPACE__'].'\\'.$params['controller'] :
                    $params['controller'];
                $this->actionName = $params['action'];
                /**
                 * Extract Module name from current controller name.
                 * First camel cased character are assumed to be module name.
                 */
                $this->moduleName = substr($this->controllerName, 0, strpos($this->controllerName, '\\'));
                $this->routeName = $matchedRoute->getMatchedRouteName();
                return $params;
            }
        
            /**
             * Return module, controller, action or route name.
             *
             * @access public
             * @return $result string.
             */
            public function get($type)
            {
                $type = strtolower($type);
                $result = false;
                switch ($type) {
                    case 'module':
                            $result = $this->moduleName;
                        break;
                    case 'controller':
                            $result = $this->controllerName;
                        break;
                    case 'action':
                            $result = $this->actionName;
                        break;
                    case 'route':
                            $result = $this->routeName;
                        break;
                }
                return $result;
            }
        }
        

        为了访问布局/视图中的值,我就是这样做的。

        1. $this->currentRequest()->get('module');
        2. $this->currentRequest()->get('controller');
        3. $this->currentRequest()->get('action');
        4. $this->currentRequest()->get('route');
        

        希望这对某人有所帮助。

        【讨论】:

        • $params 中没有 __NAMESPACE__。您使用的是哪个版本?
        【解决方案5】:

        这里有短代码:

        $this->getHelperPluginManager()->getServiceLocator()->get('application')->getMvcEvent()->getRouteMatch()->getParam('action', 'index');
        
        $controller = $this->getHelperPluginManager()->getServiceLocator()->get('application')->getMvcEvent()->getRouteMatch()->getParam('controller', 'index');
        
        $controller = array_pop(explode('\', $controller));
        

        【讨论】:

          【解决方案6】:

          ZF2 出局了,骨架也出局了。这是在骨架之上添加的,所以它应该是你最好的例子:

          Module.php 内部

          public function onBootstrap($e)
          {
              $e->getApplication()->getServiceManager()->get('translator');
              $e->getApplication()->getServiceManager()->get('viewhelpermanager')->setFactory('controllerName', function($sm) use ($e) {
                  $viewHelper = new View\Helper\ControllerName($e->getRouteMatch());
                  return $viewHelper;
              });
          
              $eventManager        = $e->getApplication()->getEventManager();
              $moduleRouteListener = new ModuleRouteListener();
              $moduleRouteListener->attach($eventManager);
          }
          

          实际的 ViewHelper:

          // Application/View/Helper/ControllerName.php
          
          namespace Application\View\Helper;
          
          use Zend\View\Helper\AbstractHelper;
          
          class ControllerName extends AbstractHelper
          {
          
          protected $routeMatch;
          
              public function __construct($routeMatch)
              {
                  $this->routeMatch = $routeMatch;
              }
          
              public function __invoke()
              {
                  if ($this->routeMatch) {
                      $controller = $this->routeMatch->getParam('controller', 'index');
                      return $controller;
                  }
              }
          }
          

          在您的任何视图/布局中

          echo $this->controllerName()
          

          【讨论】:

          • 另外,如果您在调用非对象上的 getParam() 时遇到错误,则可能值得检查资源是否被调用并存在......就像一个网站图标。当调用 favicon 并且不存在时,在没有任何参数的情况下调用和引导 ZF2,因此这是在抱怨/记录错误并使每个请求变得非常慢。
          • 嗨 Dominic Watson,我得到的是错误而不是 404 页面。我可以知道如何检查资源是否被调用或存在是 ZF2 的新手请帮助
          • 我在上面的代码中添加了 if ($this->routeMatch) 来检查它是否存在,所以你应该得到 404 而不是错误(因为缺少 favicon 或类似的东西没有 routeMatch )
          • 致命错误:在第 95 行的 C:\wamp\www\project\module\Application\Module.php 中找不到类 'Application\View\Helper\ControllerName' ...我的目录结构是模块>>应用>>查看>>帮助>>ControllerName.php....怎么了
          • 它需要在:module>>Application>>src>>Application>>View>>Helper>>ControllerName.php - 你已经把它放在你实际的 phtml 视图所在的地方
          【解决方案7】:

          您可以使用getViewHelperConfig()(也可以在Module.php 中),而不是在Module.php 中扩展onBootStrap()。实际的 helper 没有改变,但您会得到以下代码来创建它:

          public function getViewHelperConfig()
          {
             return array(
                   'factories' => array(
                      'ControllerName' => function ($sm) {
                         $match = $sm->getServiceLocator()->get('application')->getMvcEvent()->getRouteMatch();
                         $viewHelper = new \Application\View\Helper\ControllerName($match);
                         return $viewHelper;
                      },
                   ),
             );
          }
          

          【讨论】:

            【解决方案8】:

            这将是我必须使用 zf2 beta5 的解决方案

            模块/MyModule/Module.php

            namespace MyModule;
            
            use Zend\Mvc\ModuleRouteListener;
            use MyModule\View\Helper as MyViewHelper;
            
            class Module
            {
                public function onBootstrap($e)
                {
                    $app = $e->getApplication();
                    $serviceManager = $app->getServiceManager();
            
                    $serviceManager->get('viewhelpermanager')->setFactory('myviewalias', function($sm) use ($e) {
                        return new MyViewHelper($e->getRouteMatch());
                    });
                }
                ...
            }
            

            模块/MyModule/src/MyModule/View/Helper.php

            namespace MyModule\View;
            
            use Zend\View\Helper\AbstractHelper;
            
            class Helper extends AbstractHelper
            {
            
                protected $route;
            
                public function __construct($route)
                {
                    $this->route = $route;
                }
            
                public function echoController()
                {
                    $controller = $this->route->getParam('controller', 'index');
                    echo $controller;
                }
            }
            

            在任何视图文件中

            $this->myviewalias()->echoController();
            

            【讨论】:

            • 我相信您可以将 echoController() 更改为 __invoke() 并更改 echo $controller;返回 $controller
            • 这个解决方案甚至比公认的更好(更苗条的onBootstrap)!出于逻辑原因,我建议将其放在Application 模块上,而不是您自己的模块之一,因为您可以在任何模块视图中调用$this-&gt;myviewalias()。正如多米尼克所建议的,如果你使用__invoke()并返回字符串,你不需要-&gt;echoController(),但是如果你想使用myviewalias更多的目的,不要使用__invoke(),并在助手中添加更多的功能(例如:另一个返回操作-&gt;getParam('action', 'index') 的函数)。希望对您有所帮助!
            • 实际上接受的答案编辑了 Application\Module.php 中的onBootstrap 函数......所以事实上,它们几乎是相同的答案。真正的区别在于每个人如何使用视图函数(通过__invoke() 或独立函数)。
            • 如果我今天这样做了,我会在 Module::getViewHelperConfig() 方法中注册视图帮助工厂,而不是在引导程序中设置它。请参阅下面的 dstj 示例。如果助手只需要回显控制器,则 __invoke() 方法会导致视图文件看起来更苗条。如果您希望同一个助手能够输出动作等其他内容,那么上述解决方案可能更可取。
            【解决方案9】:

            在 zf2 beta4 中是这样制作的:

            public function init(ModuleManager $moduleManager)
            {
            
                $sharedEvents = $moduleManager->events()->getSharedManager();
                $sharedEvents->attach('bootstrap', 'bootstrap', array($this, 'onBootstrap'));
            }
            
            public function onBootstrap($e)
            {
                $app     = $e->getParam('application');
                // some your code here
                $app->events()->attach('route', array($this, 'onRouteFinish'), -100);
            }
            
            public function onRouteFinish($e)
            {
                 $matches    = $e->getRouteMatch();
                 $controller = $matches->getParam('controller');
                 var_dump($controller);die();
            }
            

            【讨论】:

            猜你喜欢
            • 2015-04-29
            • 1970-01-01
            • 1970-01-01
            • 2013-07-16
            • 2016-09-30
            • 2011-02-07
            • 2015-02-06
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多