Model view controller Zend Framework 2:在视图中获取匹配的路由

Model view controller Zend Framework 2:在视图中获取匹配的路由,model-view-controller,routes,zend-framework2,Model View Controller,Routes,Zend Framework2,我目前正在学习ZF2,大致基于skeleton应用程序开发一个小型MVC应用程序。现在,我正试图根据匹配的路由隐藏一些固定的HTML元素:例如,我不希望在登录阶段显示主菜单 通过将切换参数作为控制器操作的返回值传递,我可以轻松地做到这一点,但感觉不对,因此我只想从布局中检查匹配的路由,并相应地组合布局 问题是,我不知道如何在模板中获得匹配的路由。这可能吗?是否有其他解决方案可以避免在控制器中添加布局逻辑 编辑经过一些弗兰肯斯坦式的研究,我找到了解决这个问题的方法。我喜欢使用助手的想法,所以我只是

我目前正在学习ZF2,大致基于skeleton应用程序开发一个小型MVC应用程序。现在,我正试图根据匹配的路由隐藏一些固定的HTML元素:例如,我不希望在登录阶段显示主菜单

通过将切换参数作为控制器操作的返回值传递,我可以轻松地做到这一点,但感觉不对,因此我只想从布局中检查匹配的路由,并相应地组合布局

问题是,我不知道如何在模板中获得匹配的路由。这可能吗?是否有其他解决方案可以避免在控制器中添加布局逻辑

编辑经过一些弗兰肯斯坦式的研究,我找到了解决这个问题的方法。我喜欢使用助手的想法,所以我只是尝试从主模块中的boostrap函数将应用程序对象传递给它:

$app = $e->getApplication();
$serviceManager = $app->getServiceManager();
....
$serviceManager->get('viewhelpermanager')->setFactory('getRoute', function($sm) use ($app) {
    return new Helper\GetRoute($app);
});
和助手函数:

use Zend\View\Helper\AbstractHelper;

class GetRoute extends AbstractHelper {
    private $sm;

    public function __construct($app) {
        $this->sm = $app->getServiceManager();
    }

    public function echoRoute() {
        $router = $this->sm->get('router');
        $request = $this->sm->get('request');

        $routeMatch = $router->match($request);
        if (!is_null($routeMatch))
            echo $routeMatch->getMatchedRouteName();
    }
}
<?php function itsRoute($routeName){
    $flag = false;
    if($this->serverUrl(true) == $this->url($route,[],['force_canonical'=>true]))){
        $flag = true;
    }

    return $flag;
}

也许有一种更干净、更像ZF2ish的方法可以做到这一点……

我相信您可以通过查找操作/控制器名称来解决这个问题:

$controller = $this->getRequest()->getControllerName();
$action = $this->getRequest()->getActionName();

一旦知道操作,就可以有特定的条件来启用布局的各个部分。

您可以创建一个实现ServiceManagerWareInterface的视图帮助器。然后在视图帮助器内部,使用ServiceManager实例检索路由器和请求对象,然后重建路由匹配

$services = $this->getServiceManager();

$router = $services->get('router');
$request = $services->get('request');

$routeMatch = $router->match($request);
echo $routeMatch->getMatchedRouteName();

我还建议编写视图帮助程序,以便代码在每个请求中只触发一次。

有一种方法可以让service manager进入布局:

$sm = $this->getHelperPluginManager()->getServiceLocator();

然后,您可以访问
$sm->get('router')
等另一个解决方案,而无需新的匹配项

$routeMatch = $serviceLocator->get('Application')->getMvcEvent()->getRouteMatch();

echo $routeMatch->getMatchedRouteName();
我的控制器:

    <?PHP
    namespace SomeName\Controller;

    use Zend\Mvc\Controller\AbstractActionController;
    use Zend\View\Model\ViewModel;

    class SomeController extends AbstractActionController
    {
        public function getIdAction()
        {
            $id = $this->params()->fromRoute('id', 0);
            return new ViewModel(array(
                'id' => $id,
            ));
        }
    }
在视图中,您可以使用:

$this->getHelperPluginManager()->getServiceLocator()->get('request')->getUri()->getPath();


当移动到ZF3时,你应该考虑使用这个方法…因为getLocator不再可用(并且它不正确)

  • 创建辅助对象

    namespace Application\View\Helper;
    
    use Zend\Http\Request;
    use Zend\Router\RouteStackInterface;
    use Zend\View\Helper\AbstractHelper;
    
    /**
     * Helper to get the RouteMatch
     */
    class RouteMatch extends AbstractHelper
    {
        /**
         * RouteStackInterface instance.
         *
         * @var RouteStackInterface
         */
        protected $router;
    
        /**
         * @var Request
         */
        protected $request;
    
        /**
         * RouteMatch constructor.
         * @param RouteStackInterface $router
         * @param Request $request
         */
        public function __construct(RouteStackInterface $router, Request $request)
        {
            $this->router = $router;
            $this->request = $request;
        }
    
        /**
         * @return \Zend\Router\RouteMatch
         */
        public function __invoke()
        {
            return $this->router->match($this->request);
        }
    }
    
  • 为此帮助程序创建工厂

    namespace Application\View\Helper;
    
    use Interop\Container\ContainerInterface;
    use Zend\ServiceManager\Factory\FactoryInterface;
    
    class RouteMatchFactory implements FactoryInterface
    {
        public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
        {
            $router = $container->get('router');
            $request = $container->get('request');
    
            return new RouteMatch($router, $request);
        }
    
    }
    
  • Module.php
    上调用您的工厂,并为其创建别名

    public function getViewHelperConfig()
    {
        return array(
            'factories' => array(
                RouteMatch::class => RouteMatchFactory::class,
            ),
            'aliases' => array(
                'routeMatch' => RouteMatch::class,
            )
        );
    }
    
  • 就这样。。。您有一个使用新ZF3标准的RouteMatch助手

    再见

    我认为您可以使用

    $this->getHelperPluginManager()->getServiceLocator()->get('Application')->getMvcEvent()->getRouteMatch()->getMatchedRouteName();
    

    关于在ZF3中集成getRouteMatch的“Rodrigo Boratto”帖子的更多信息(我不能发表评论,因为我有不到50份回购…)

    在视图帮助文件中,这些行:

    use Zend\Mvc\Router\RouteMatch as MvcRouteMatch;
    use Zend\Mvc\Router\RouteStackInterface;
    
    应该是:

    use Zend\Router\RouteMatch as MvcRouteMatch;
    use Zend\Router\RouteStackInterface;
    
    我不知道他们是什么时候做的更改,但这些文件位于Zend\Router名称空间中


    注意:如果有必要,我使用composer。

    在任何视图或布局中,您都可以使用此功能测试路线:

    use Zend\View\Helper\AbstractHelper;
    
    class GetRoute extends AbstractHelper {
        private $sm;
    
        public function __construct($app) {
            $this->sm = $app->getServiceManager();
        }
    
        public function echoRoute() {
            $router = $this->sm->get('router');
            $request = $this->sm->get('request');
    
            $routeMatch = $router->match($request);
            if (!is_null($routeMatch))
                echo $routeMatch->getMatchedRouteName();
        }
    }
    
    <?php function itsRoute($routeName){
        $flag = false;
        if($this->serverUrl(true) == $this->url($route,[],['force_canonical'=>true]))){
            $flag = true;
        }
    
        return $flag;
    }
    

    也许这个话题会对你有所帮助。在ZF2中,长时间以来没有什么感觉是对的链接实际上帮助了我,ArmandI尝试了这个,但服务经理不知道路由器和请求。。。尽管如此,它还是给了我第一个解决方案的正确想法。我在一个部分中使用了这个解决方案。谢谢开箱即用。如@Rodrigo Boratto所述-这只适用于ZF2,但不适用于ZF3。您应该创建一个自定义视图辅助对象。