Zend Framework 2:在视图中获得匹配的路由

时间:2012-08-22 07:56:51

标签: model-view-controller routes zend-framework2

我目前正在通过大致基于骨架应用程序开发一个小型MVC应用程序来学习ZF2。现在我试图隐藏一些基于匹配路由的固定HTML元素:举个例子,我不想在登录阶段显示主菜单。

我可以通过将切换参数作为控制器动作的返回值传递来轻松实现,但感觉不对,所以我想从布局中检查匹配的路径并相应地构建布局。

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

经过一番优秀的科学怪人工作后,

编辑,我能够找到解决方案。我喜欢使用帮助器的想法,所以我只是尝试从主模块中的boostrap函数传递Application对象:

$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();
    }
}

也许有更清洁,更ZF2ish的方式来做到这一点......

10 个答案:

答案 0 :(得分:30)

没有新匹配的另一种解决方案

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

echo $routeMatch->getMatchedRouteName();

答案 1 :(得分:12)

有一种方法可以在布局中获得服务管理器:

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

然后您就可以访问$sm->get('router')等。

答案 2 :(得分:9)

您可以创建一个实现ServiceManagerAwareInterface的View帮助程序。然后在View帮助程序中使用ServiceManager实例检索路由器和请求对象,然后重新构建路由匹配。

$services = $this->getServiceManager();

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

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

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

答案 3 :(得分:5)

当转移到ZF3时,你应该考虑使用这种方法...因为getLocator不再可用(并且它不正确注入它)。

  1. 创建助手

    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);
        }
    }
    
  2. 为此助手创建工厂

    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);
        }
    
    }
    
  3. Module.php上致电您的工厂并为其创建别名。

    public function getViewHelperConfig()
    {
        return array(
            'factories' => array(
                RouteMatch::class => RouteMatchFactory::class,
            ),
            'aliases' => array(
                'routeMatch' => RouteMatch::class,
            )
        );
    }
    
  4. 那就是......你有一个使用新的ZF3标准的RouteMatch Helper。

    再见!

答案 4 :(得分:2)

在视图中,您可以使用:

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

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

答案 5 :(得分:1)

我相信你可以通过找到动作/控制器名称来解决它:

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

了解操作后,您可以使用特定条件启用布局的各个部分。

答案 6 :(得分:1)

我认为你可以使用

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

答案 7 :(得分:1)

关于在ZF3中集成getRouteMatch的“Rodrigo Boratto”帖子的其他信息(我无法发表评论,因为我有50回购...)

在视图助手文件中这些行:

somemodule -env dev

应该是:

use Zend\Mvc\Router\RouteMatch as MvcRouteMatch;
use Zend\Mvc\Router\RouteStackInterface;

我不知道他们何时进行了更改,但文件位于Zend \ Router名称空间中。

P.S。如果重要,我会使用作曲家。

答案 8 :(得分:0)

我的控制器:

    <?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,
            ));
        }
    }

我的路由器:

    <?php
    return array(
        'controllers' => array(
            'invokables' => array(
                'SomeName\Controller\Some' => 'SomeName\Controller\SomeController',
            ),
        ),

        'router' => array(
            'routes' => array(
                'testId' => array(
                    'type'    => 'segment',
                    'options' => array(
                        'route'    => '/[:id]',
                        'constraints' => array(
                            'id' => '\d*',
                        ),
                        'defaults' => array(
                            'controller' => 'SomeName\Controller\Some',
                            'action'     => 'getId',
                        ),
                    ),
                ),
            ),
        ),

        'view_manager' => array(
            'template_path_stack' => array(
                'album' => __DIR__ . '/../view',
            ),
        ),
    );

答案 9 :(得分:0)

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

<?php function itsRoute($routeName){
    $flag = false;
    if($this->serverUrl(true) == $this->url($route,[],['force_canonical'=>true]))){
        $flag = true;
    }

    return $flag;
}