Zend Framework 2: get matched route in view

半世苍凉 提交于 2019-11-30 11:47:06
MarkusM

Another solution without a new match

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

echo $routeMatch->getMatchedRouteName();

There is a way to get service manager in layout:

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

and then you can access $sm->get('router') etc.

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.

When moving to ZF3, you should consider use this method... since getLocator isn't available anymore (and it's not correct inject it).

  1. Create the Helper

    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. Create a Factory for this helper

    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. Call your Factory on your Module.php and create an Alias for it.

    public function getViewHelperConfig()
    {
        return array(
            'factories' => array(
                RouteMatch::class => RouteMatchFactory::class,
            ),
            'aliases' => array(
                'routeMatch' => RouteMatch::class,
            )
        );
    }
    

That's it... you have a RouteMatch Helper using the new ZF3 standards.

Bye!

Decrypter

In view you can use:

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

or

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

I believe you can solve it by finding the action/controller names:

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

Once you know the action, you can have specific conditions to enable sections of the layout.

Tomasz

I view you can use

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

Additional information about "Rodrigo Boratto" post for integrating getRouteMatch in ZF3 (I can't comment because I have under 50 repo...)

In view helper file these line:

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

should be:

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

I don't know when they made that change but the files are in Zend\Router namespace.

P.S. I use composer if that matters.

My controller:

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

My Router:

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

At any view or layout, you are able to test route with this function:

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

    return $flag;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!