Zend Framework 3 - 基于查询字符串的路由

问题描述 投票:4回答:3

在Zend Framework 3中,是否可以根据URL是否包含查询字符串来路由到控制器?

例如,我有这两个网址:

/users
/users?name=Bob

我想第一条路线叫UsersController,第二条路线叫NameController

这可能吗?

php routes zend-framework3
3个回答
6
投票

我的评论变成了答案。那么,你走了。

下次,请务必遵循How to Ask


请读一下ZF3 docs on Router和可能的RFC 3986 Chapter 3 - Syntax Components,它显示了什么是路径和什么是查询。

来自RFC 3986 Chapter 3 - Syntax Components

以下是两个示例URI及其组成部分:

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

ZF3路由配置通常是路径上的配置。 (几乎所有常见框架都是如此。)是的,变量可以是路径的一部分。因此,它们在路由配置中配置。框架路由的高级配置通常还允许方案和权限中的更改/要求。

不是路由配置的一部分是'查询'和'片段'部分。

如果你想做某事,例如捕获一个“名称”键/值对并相应地进行路由,你将不得不在路径上创建一个“捕手”(或其名称),并自己确定重定向。

例如,你可以做像this answer这样的事情。如果您的控制器实例扩展了默认的Zend Framework AbstractActionController类,那么您应该可以使用forward plugin。来自文档:

Forward返回调度请求的控制器的结果;由开发人员决定如何处理这些结果。一个建议是将它们聚合在来自调用控制器的任何返回值中。

举个例子:

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

当然,你可以立即归还它。

另一种选择是redirect plugin(相同的链接)。

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

有了这一切,你可以做一些事情:

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

if ($name) {
    // dispatch

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

// redirect

您重定向到路由名称的位置(即配置的路径)


-1
投票

作为rkeet mentioned,查询字符串不是路线的一部分。因此,我们只是在路由配置数组中添加了一个三元组:

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

它是自解释的,但基本上调度的控制器取决于是否在查询字符串中设置了值。

我们决定不使用forward()插件,因为我们不想多余地实例化额外的控制器。


-1
投票

即使rkeet的answer在技术上是正确的,我也会避免使用该解决方案,因为它将单个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)
© www.soinside.com 2019 - 2024. All rights reserved.