2015-06-25 112 views
0

我試圖理解ZF2模塊路由,但我有一個問題。我想按期間列出產品,併爲每個期間(今天,本週,本月,全部)生成鏈接。例如:Zend Framework 2路由段錯誤

<a href="<?php echo $this->url('Application', array('action' => 'index', 'period' => 'this-week')); ?>">This week</a> 

輸出:本地主機/應用/這周/

當我點擊這個鏈接,會出現此錯誤:

A 404 error occurred 
Page not found. 
The requested controller was unable to dispatch the request. 

這是我module.config:

..................... 
     'router' => array(
      'routes' => array(
       'Application' => array(
        'type' => 'Segment', 
        'options' => array(
         'route' => '/application/[:action/][:period/]', 
         'constraints' => array(
          'action' => '[a-zA-Z][a-zA-Z0-9_-]*', 
          'period' => '(today|this-week|this-month|all)' 
         ), 
         'defaults' => array(
          'controller' => 'Application\Controller\ApplicationController', 
          'action' => 'index', 
          'period' => 'all' 
         ), 
        ), 
       ), 
      ), 
     ), ........................... 

我在哪裏做錯了?我試圖改變:

'period' => '(today|this-week|this-month|all)' 

'period' => '[a-zA-Z][a-zA-Z0-9_-]*' 

,但它不工作了。

我的控制器內,指數的行動實際上是空的:

public function indexAction(){ 

} 

index.phtml只包含回聲鏈接:

<a href="<?php echo $this->url('Application', array('action' => 'index', 'period' => 'this-week')); ?>">This week</a> 

新的編輯

我已經決定使用查詢字符串供我使用。它更容易實現,這是不優雅,但moooore簡單:d ...我想,像這樣,與「更高的剛性」開關:

public function indexAction(){ 
    ...getQuery method ... 

    switch($period){ 
     case'today': 
     ....... 
     break; 
     case'this-week': 
     ....... 
     break; 
     case'this-month': 
     ....... 
     break; 
     default: 
     // if query string is null or contains other characters, sets default case "all" 
     ... 
     break; 
    } 
} 

URL功能:

<a href="<?php echo $this->url('Application', array('action' => 'index'), array('query' => array('period' => 'this-week'); ?>">This week</a> 

輸出:

localhost/adopted/?period=this-week 

內部module.config:

..................... 
      'router' => array(
       'routes' => array(
        'Application' => array(
         'type' => 'Segment', 
         'options' => array(
          'route' => '/application/[:action/]', 
          'constraints' => array(
           'action' => '[a-zA-Z][a-zA-Z0-9_-]*', 
          ), 
          'defaults' => array(
           'controller' => 'Application\Controller\ApplicationController', 
           'action' => 'index', 
          ), 
         ), 
        ), 
       ), 
      ), ........................... 
+0

請問,如果你從你的路由配置移除操作的默認值,它的工作? –

+0

如果我刪除默認操作值,它的工作原理!但網址是: localhost/application/index/this-week/ –

回答

0

由於路徑類似於/application/this-week/,ZF無法知道this-week是一個操作還是句點,因爲兩者都是可選的,並且字符串與兩者的約束匹配。要解決這個問題,你需要消除這種模糊性。您有幾種選擇:

選項1:添加一些約束action,所以,它只會匹配有效的行動,是這樣的:

'constraints' => array(
    'action' => '(index|foo|bar)', 
    'period' => '(today|this-week|this-month|all)' 
), 

選項2:製作無論是動作還是期間所需,通過移除你的路由配置中的方括號。 (如果您需要索引,您的網址中將以'索引'結尾。)

方案3:添加一個單獨的路徑此URL不包括在路徑中的動作(因爲你不希望它出現),但在應用程序路徑區分它的一些其他的方式:

'router' => array(
    'routes' => array(
     'Application' => array(
      'type' => 'Segment', 
      'options' => array(
       'route' => '/application/[:action/]', 
       'constraints' => array(
        'action' => '[a-zA-Z][a-zA-Z0-9_-]*'' 
       ), 
       'defaults' => array(
        'controller' => 'Application\Controller\ApplicationController', 
        'action' => 'index' 
       ), 
      ), 
     ), 
     'period' => array(
      'type' => 'Segment', 
      'options' => array(
       'route' => '/application/period/[:period/]', 
       'constraints' => array(
        'period' => '(today|this-week|this-month|all)' 
       ), 
       'defaults' => array(
        'controller' => 'Application\Controller\ApplicationController', 
        'action' => 'index', 
        'period' => 'all' 
       ), 
      ), 
     ), 
    ), 
), 

你也想改變URL助手呼籲:

<a href="<?php echo $this->url('period', array('period' => 'this-week')); ?>">This week</a> 

這將使你喜歡/application/period/this-week/的URL。

+0

由於已有'action'(提供請求爲'application/index/this-week')的默認值,因此不確定您的理由。我認爲它是控制器名稱,Application \ Controller \ ApplicationController應該是Application \ Controller \ Application。 – AlexP

+0

謝謝你的解決方案,我決定使用查詢字符串,更簡單,它不會讓頭痛:D。看第一篇文章。您對新解決方案有何看法? –

0

你的想法總的來說還不錯,你只是想調整你的路線。我推薦幾件事情:

  • 不要調用你的路線應用程序,給它一個有意義的名字。看起來像一個持續時間?
  • 請記住,在ZF2路線是後進先出法,所以堅持在頂部附近這一塊,這樣更有意義的路線可以中斷它

考慮到這些小東西,這條線路的工作原理:

'catchall_with_period' => array(
    'type' => 'Segment', 
    'options' => array(
     'route' => '/application[/:action[/][:period[/]]]', 
     'constraints' => array(
      'action' => '[a-zA-Z][a-zA-Z0-9_-]*', 
      'period' => '(today|this-week|this-month|all)' 
     ), 
     'defaults' => array(
      'controller' => 'Application\Controller\ApplicationController', 
      'action' => 'test', 
      'period' => 'all' 
     ), 
    ), 
), 

我在本地進行了測試,它具有預期的效果。

以我個人的經驗來看,這些路線讓你從現在的嘿嘿兩年開始撓頭。爲什麼這樣做?抓住所有路線,當心!

+0

我決定使用查詢字符串供我使用。它更簡單的實現,它不是優雅的,但moooore簡單:D ...我認爲是這樣,與「更高的剛性」開關: '公共功能indexAction(){ ... getQuery方法。 .. switch($ period){ case'today': ....... break; case'this-week': ....... break; case'this-month': ....... break; 默認值: //如果查詢字符串爲空或包含其他字符,則設置默認情況「全部」 ... break; } }' –

+0

對不起,但我不知道如何改進評論內的格式O_O –

+0

我已經編輯過第一篇文章,更具可讀性! –

0

最大的可能是你的控制器的配置是錯誤的:

'defaults' => array(
    // 'controller' => 'controller service name' 
    'controller' => 'Application\Controller\ApplicationController', 
    'action' => 'index', 
    'period' => 'all' 
), 

ZF2會懇請控制器經理名爲Application\Controller\ApplicationController服務。如果沒有使用該名稱註冊此類服務(控制器),則將拋出錯誤「無法分派」。

通常在控制器管理控制器通過模塊的config配置這樣:

'controllers' => array(
    'invokables' => array(
     // service name => service FQCN 
     'Application\Controller\Application' => 'Application\Controller\ApplicationController' 
    ) 
) 

綜上所述,你的路線應該是這樣,我相信:

'defaults' => array(
    'controller' => 'Application\Controller\Application', 
    'action' => 'index', 
    'period' => 'all' 
), 

我可能是錯的當然,因爲你沒有提供你的控制器的配置。

以供將來參考,請仔細閱讀有關default Service Managers configured in the framework,如何進行配置,有什麼invokables,工廠等

順便說一句,

'constraints' => array(
    'action' => '[a-zA-Z][a-zA-Z0-9_-]*', 
    'period' => '(today|this-week|this-month|all)' 
), 

period正則表達式是無效的爲好,因爲它會接受短語,如xxxtodayyyygralltttthis-monthhhh,所以更改'(today|this-week|this-month|all)'模式'^(today|this-week|this-month|all)$'

1

你好你已經在左邊和右邊的支架(今天|本週|本月|全部)。如果你刪除這個支架,你的路線將起作用。還有一件事「應用程序\控制器\ ApplicationController中」,在這裏你需要寫「申請\控制器\應用程序」

..................... 
    'router' => array(
     'routes' => array(
      'Application' => array(
       'type' => 'Segment', 
       'options' => array(
        'route' => '/application/[:action/][:period/]', 
        'constraints' => array(
         'action' => '[a-zA-Z][a-zA-Z0-9_-]*', 
         'period' => 'today|this-week|this-month|all' 
        ), 
        'defaults' => array(
         'controller' => 'Application\Controller\Application', 
         'action' => 'index', 
         'period' => 'all' 
        ), 
       ), 
      ), 
     ), 
    ), ...........................