2014-09-26 11 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

相關問題