2014-09-26 40 views
0

我有以下代码来匹配路由与主机名;ZF2主机名匹配汇编url​​和404

'router' => [ 
    'router_class' => 'Zend\Mvc\Router\Http\TranslatorAwareTreeRouteStack', 
    'routes' => [ 
     'website' => [ 
      'type' => 'hostname', 
      'may_terminate' => true, 
      'options' => [ 
       'route' => ':locale.domain.:tld', 
       'constraints' => [ 
        'language' => '(nl|en)', 
        'tld' => '(dev|org)', 
       ], 
      ], 
     ] 
    ], 
], 

和一些路线来匹配uri。

所以在开发我可以有像en.domain.devnl.domain.dev路线。该航线的翻译也用得好好的,但随后我的“问题”出现

1.组装网址

对于每一个网址我现在需要的localetld变量。要做到这一点,我做<?= $this->url('website/languages', [], true); ?>,但这使它变得一团糟。因为我只想使用当前路线的TLD和区域设置。

所以我提出了解决方案来扩展URL视图助手。当没有设置路径匹配时,设置参数localetld。这工作1'小'的问题,请参阅2.但想知道是否有一个解决这个问题的解决方案。

2. 404帕加

在1我使用当前路由匹配,以获得locale/tld组装URL的这一切工作,除了404页。显然,因为没有路线匹配。

我开始挖周围,当我发现路由器(从service locator)。我试图得到website的路线,它只返回Zend\Mvc\Router\Http\Partprotected $route是无法访问的Zend\Mvc\Router\Http\Hostname。所以没有这样的运气。

我得到主机名路由的唯一方法是通过构建它我自己,我真的不想这样做。

所以问题是你如何轻松地重用主机名参数,并获得404页上的主机名参数?

我知道,例如test.domain.test将不匹配主机名,并会提供一个破损的主机名,但这是Nginx的问题。所以Nginx会确保主机名永远是正确的

+0

不知道如果我理解正确的你。你可以写一个视图助手,在其中注入参数。你可以在404视图脚本中使用助手。 – Ronnie 2014-09-26 14:57:45

+0

我可以但参数是基于主机名,在场景1中,我每次都需要它们在我的url viewhelper中。在第二种情况下,问题是没有路线匹配 – MKroeders 2014-09-26 15:46:17

回答

1

那么我继续搜索和思考,并带着'解决方案'来。

要处理2.我创建了一个侦听器,在MvcEvent::EVENT_DISPATCH_ERROR上侦听。

代码;

// use are above the class declaration 
use Zend\Mvc\Router\Http\TranslatorAwareTreeRouteStack; 
use Zend\EventManager\AbstractListenerAggregate; 
use Zend\EventManager\EventManagerInterface; 
use Zend\Http\PhpEnvironment\Request; 
use Zend\Mvc\Router\Http\RouteMatch; 
use Zend\Mvc\MvcEvent; 

public function onDispatchError(MvcEvent $event) 
{ 
    if (is_null($event->getRouteMatch())) { 
     $router = $event->getRouter(); 
     $request = $event->getRequest(); 

     if ($router instanceof TranslatorAwareTreeRouteStack && $request instanceof Request) { 
      $match = $router->getRoute('website')->match($request, strlen($request->getUri()->getPath()), array(
       'translator' => $router->getTranslator(), 
      )); 
      if ($match instanceof RouteMatch) { 
       $match->setMatchedRouteName('website'); 
       $event->setRouteMatch($match); 
      } 
     } 

    } 
} 

它做什么;

  1. 检查是否有路由匹配,如果不是它是一个404

  2. 检查$routerTranslatorAwareTreeRouteStack$requestHttpRequest

  3. 得到website路线(这是主机名的路由'

  4. 然后它匹配它(技巧是偏移量被设置,所以只有主机名被选中)

  5. 设置

  6. 那么routematch事件

被注入到现在解决我的路线一致的姓名(如果没有设置,这将导致问题为空)一直使用route match,所以我可以做一些自己的魔法。我扩展了url viewhelper

public function __invoke(
    $name = null, 
    $params = array(), 
    $options = array(), 
    $reuseMatchedParams = false 
) { 
    if ($this->routeMatch instanceof RouteMatch) { 
     foreach(['locale', 'tld'] as $key) { 
      if (!array_key_exists($key, $params)) { 
       $params[$key] = $this->routeMatch->getParam($key); 
      } 
     } 
    } 

    // This is needed for the magic that can happen when `reuseMatchedParams` is used at the third position 
    if (is_bool($options)) { 
     $reuseMatchedParams = $options; 
     $options = array(); 
    } 

    return parent::__invoke(
     $name, 
     $params, 
     $options, 
     $reuseMatchedParams 
    ); 
} 

不是最优雅的方法,但它的工作原理现在

+0

对我来说,它看起来是一个很好的解决方案。 – Ronnie 2014-09-27 17:30:01

相关问题