2015-06-25 2 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

Если я удаляю значение действия по умолчанию, оно работает! но URL-адрес: 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: Сделайте либо действие или период требуется, путем удаления квадратные скобки от них в конфигурации маршрутизации. (Если вы укажете требуемый индекс, вы получите «индекс» в своих URL-адресах.)

Вариант 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> 

Это даст вам URL, как /application/period/this-week/.

+0

Не уверен по этой причине здесь, поскольку для 'action' уже есть значение по умолчанию (при условии, что запрос является' application/index/this-week'). Я думаю, что это имя контроллера, 'Application \ Controller \ ApplicationController', которое должно быть' Application \ Controller \ Application'. – AlexP

+0

Спасибо за ваше решение, я решил использовать строку запроса, проще и не вызывает головную боль: D. Посмотрите первое сообщение. Что вы думаете о новом решении? –

0

Ваше мнение в целом в порядке, вы просто хотите немного настроить свой маршрут. Я бы порекомендовал несколько вещей:

  • Не называйте свой маршрут Приложением, придайте ему значащее имя. Похоже на уловку с длительностью?
  • Помните, что маршруты в ZF2 являются LIFO, так что придерживайтесь этого около вершины так, что более значимых маршруты могут прервать его

С этими маленькими вещами в виде, этот маршрут работает:

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

Я тестировал локально, и он имеет предполагаемый эффект.

В моем личном опыте, это те маршруты, которые вы почесываете голову через 2 года. Почему это делается? Поймайте все маршруты, остерегайтесь!

+0

Я решил использовать строку запроса для моего использования. Это проще, но это не изящно, но очень просто: D ... Я так думал, с переключателем для «более высокой жесткости»: 'public function indexAction() { ... метод getQuery. .. переключатель ($ период) { case'today ': ....... break; case'this-week ': ....... break; case'this-month ': ....... break; default: // если строка запроса имеет значение null или содержит другие символы, устанавливает значение по умолчанию «all» ... break; } } ' –

+0

Извините, но я не понял, как улучшить форматирование внутри комментария O_O –

+0

Я отредактировал первое сообщение, более читаем! –

0

Скорее всего, ваш контроллер конфигурации неправильно:

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

ZF2 любезно попросить диспетчера контроллер для службы с именем Application\Controller\ApplicationController. Если такой сервис (контроллер) не зарегистрирован под этим именем, будет выбрана ошибка «Невозможно отправить».

Обычно контроллеры в Controller Manager, которые настраиваются с помощью конфигурации Модуля таким образом:

'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 является недействительным, а также, потому что она будет принимать фразы, как xxxtodayyyy, grall, tttthis-monthhhh, поэтому изменить '(today|this-week|this-month|all)' шаблон для '^(today|this-week|this-month|all)$'

1

Привет, вы сделали скобки слева и справа здесь (сегодня | на этой неделе | в этом месяце | все). если вы удалите этот кронштейн, ваш маршрут будет работать.и еще одна вещь «Application \ Controller \ ApplicationController», здесь вам нужно написать «Application \ Controller \ Application»

..................... 
    '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' 
        ), 
       ), 
      ), 
     ), 
    ), ...........................