12

我目前正在通过大致基于骨架应用程序开发一个小型 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 的方式来做到这一点......

4

10 回答 10

31

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

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

echo $routeMatch->getMatchedRouteName();
于 2013-01-11T09:59:19.543 回答
12

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

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

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

于 2012-11-16T20:06:11.797 回答
9

You could create a View helper that implements ServiceManagerAwareInterface. Then inside the View helper using the ServiceManager instance to retrieve both the router and request objects then reconstruct the route match.

$services = $this->getServiceManager();

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

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

I'd also recommend writing the View helper so that code only triggers once per request.

于 2012-08-24T09:27:04.243 回答
6

迁移到 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,
            )
        );
    }
    

就是这样...您有一个使用新 ZF3 标准的 RouteMatch 助手。

再见!

于 2016-03-31T15:16:38.783 回答
2

鉴于您可以使用:

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

或者

$this->getHelperPluginManager()->getServiceLocator()->get('request')->getUri()->toString();
于 2013-12-24T10:44:38.613 回答
1

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

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

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

于 2012-08-22T09:08:46.727 回答
1

有关在 ZF3 中集成 getRouteMatch 的“Rodrigo Boratto”帖子的其他信息(我无法发表评论,因为我的 repo 不到 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 命名空间中。

PS如果这很重要,我会使用作曲家。

于 2016-11-09T14:01:18.817 回答
1

我认为你可以使用

$this->getHelperPluginManager()->getServiceLocator()->get('Application')->getMvcEvent()->getRouteMatch()->getMatchedRouteName();
于 2016-06-11T18:10:00.747 回答
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',
            ),
        ),
    );
于 2013-01-30T21:33:23.850 回答
0

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

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

    return $flag;
}
于 2018-04-26T19:35:26.570 回答