在Zend Framework 3中,是否可以根据URL是否包含查询字符串来路由到控制器?
例如,我有以下两个URL:
/users
/users?name=Bob
我希望第一条路线呼叫UsersController
,第二条路线呼叫NameController
。
这可能吗?
答案 0 :(得分: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 :(得分:-1)
作为密钥mentioned,查询字符串不是路由的一部分。因此,我们只需在路由配置数组中添加三元组即可:
'users' => [
'type' => Literal::class,
'options' => [
'route' => '/users',
'defaults' => [
'controller' => isset($_GET['name'])
? NameController::class
: UsersController::class,
'action' => 'index',
],
],
'may_terminate' => true,
],
这是不言自明的,但调度的控制器基本上取决于是否在查询字符串中设置了值。
我们决定不使用forward()
插件,因为我们不想多余地实例化一个额外的控制器。
答案 2 :(得分:-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)