Zend Framework 3 - маршрут на основе строки запроса - PullRequest
4 голосов
/ 09 апреля 2019

В Zend Framework 3 можно ли маршрутизировать на контроллер в зависимости от того, содержит ли URL строку запроса?

Например, у меня есть два следующих URL:

/users
/users?name=Bob

Я хотел бы, чтобы первый маршрут вызывал UsersController, а второй - NameController.

Возможно ли это?

Ответы [ 3 ]

6 голосов
/ 10 апреля 2019

Мой комментарий превращался в ответ.Итак, поехали.

В следующий раз, пожалуйста, следуйте инструкциям Как спросить .


Пожалуйста, ознакомьтесь с документами ZF3 на маршрутизаторе и, возможно, RFC 3986 Глава 3 - Синтаксические компоненты , в которых показано, что такое путь и что такое запрос,

С RFC 3986 Глава 3 - Синтаксические компоненты

Ниже приведены два примера URI и их составные части:

     foo://example.com:8042/over/there?name=ferret#nose
     \_/   \______________/\_________/ \_________/ \__/
      |           |            |            |        |
   scheme     authority       path        query   fragment
      |   _____________________|__
     / \ /                        \
     urn:example:animal:ferret:nose

Конфигурация маршрута ZF3 обычно является конфигурацией на пути. (Это также справедливо для почти всех распространенных сред.) Да, переменные могут быть частью пути.Таким образом, они настроены в конфигурации маршрута.Усовершенствованная конфигурация структуры маршрутизации часто также учитывает изменения / требования в схемах и полномочиях.

Не являются частью конфигураций маршрутизации части «запрос» и «фрагмент».

Если вы хотите что-то сделать, например, поймать пару ключ / значение «имя» и соответственно выполнить маршрутизацию, вам нужно будет создать «ловец» (или любое другое имя для этого).на пути и определить перенаправление самостоятельно.

Например, вы можете сделать что-то вроде этого ответа .Если ваш экземпляр контроллера расширяет класс Zend Framework по умолчанию AbstractActionController, то у вас должен быть в наличии плагин forward .Из документов:

Forward возвращает результаты диспетчеризации запрашиваемого контроллера;разработчик должен определить, что делать с этими результатами.Одной из рекомендаций является агрегирование их в любое возвращаемое значение из вызывающего контроллера.

Например:

 $foo = $this->forward()->dispatch('foo', ['action' => 'process']);
 return [
     'somekey' => $somevalue,
     'foo'     => $foo,
 ];

Конечно, вы можете сразу же вернуть его.

Другой вариант - плагин redirect (та же ссылка).

return $this->redirect()->toRoute('login-success');

Со всем этим вы можете сделать что-то вроде:

$name = $this->params()->fromQuery('name', null);

if ($name) {
    // dispatch

    if ($dispatchResult) {
        // return special
    }
} 

// redirect

Где вы перенаправляете на имя маршрута (т.е. настроенный путь)

0 голосов
/ 16 апреля 2019

Даже если ответ rkeet технически верен, я бы избегал этого решения, потому что он преобразует один HTTP-запрос в два (начальный GET и перенаправление / перенаправление).

Я бы настроил маршруты маршрутов, чтобы иметь два разных маршрута:

'router' => [
    'routes' => [
        'users' => [
            'type' => Literal::class,
            'options' => [
                'route' => '/users',
                'defaults' => [
                    'controller' => UsersController::class,
                    'action' => 'index'
                ],
                'may_terminate' => true,
                'child_routes' => [
                    'name' => [ // This is the subroute name
                        'type' => Segment::class,
                        'options' => [
                            'route' => '/:name', // Option 1
                            // 'route' => '/name/:name', // Option 2
                            'defaults' => [
                                'controller' => NameController::class,
                                'action' => 'index'
                            ],
                            'constraints' => [
                                'name' => '[a-zA-Z]+',
                            ]
                        ]
                    ]
                ]
            ]
        ]
    ]
]

С этой конфигурацией вы можете получить доступ к следующим URL

/users
/users/Bob (option 1)
/users/name/Bob (option 2)
0 голосов
/ 10 апреля 2019

Как отметил в строке , строка запроса не является частью маршрута.Поэтому мы просто добавили троичный в массив конфигурации маршрута:

'users' => [ 
    'type'    => Literal::class,
    'options' => [ 
        'route'    => '/users',
        'defaults' => [
            'controller' => isset($_GET['name'])
                          ? NameController::class
                          : UsersController::class,
            'action'     => 'index',
        ],   
    ],   
    'may_terminate' => true,
],

Это само за себя, но в основном отправляемый контроллер зависит от того, установлено ли значение в строке запроса.

Мы решили не использовать плагин forward(), потому что мы не хотим создавать избыточный экземпляр дополнительного контроллера.

...