段 class 上带有子路由的 ZF3 可选参数不想匹配
ZF3 optional parameter with child routes on Segment class doesn't want to match
我想创建带有可选 [lang] 参数的路由,该参数将用于设置应用程序语言,如下所示:
带有默认语言参数的示例(例如 EN)
domain.tld/
domain.tld/users
domain.tld/contacts
etc.
新语言参数示例(DE for examle)
domain.tld/de
domain.tld/de/users
domain.tld/de/contacts
etc.
这是我的路线配置:
'router' => [
'routes' => [
'site' => [
'type' => Segment::class,
'options' => [
'route' => '[/:lang]',
'constraints' => [
'lang' => '[a-z]{2}',
],
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index',
'lang' => 'en',
],
],
'may_terminate' => true,
'child_routes' => [
'home' => [
'type' => Literal::class,
'options' => [
'route' => '/',
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index',
],
],
'may_terminate' => true,
],
'application' => [
'type' => Segment::class,
'options' => [
'route' => '/application[/:action]',
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index',
],
],
'may_terminate' => true,
],
],
],
],
]
当我在 url 中有 lang 参数时,一切都很好。但是当我尝试打开 "default" lang 而不在路径中指定它时(例如。tld/application/test)它给我 404 错误。
我发现从Segmentclass转换后的最终正则表达式是(\G(?:/(?P<param1>([a-z]{2})))?)
,路径是/application/test
。当 preg_match
在 Segment.php:385 上执行时,它 return 匹配以下值:
[
'0' => '/ad',
'param1' => 'ad',
'1' => 'ad',
],
这显然是错误的行为。我的语言设置为 "ad" 而不是打开 application/test 操作。我测试了大约 10 个正则表达式但没有成功......(例如 ^[a-z]{2}$
)。
我做错了什么?
你得到 404 因为 URL 不匹配 site
路由,所以 site
的子路由被跳过。
试试这个:
'home' => [
'type' => Segment::class,
'options' => [
'route' => '/[:lang/]',
'constraints' => [
'lang' => '(en|de)?',
],
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index',
'lang' => 'en',
],
],
'may_terminate' => true,
'child_routes' => [
'application' => [
'type' => Segment::class,
'options' => [
'route' => 'application[/:action]',
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index',
],
],
],
],
]
如果您不提供 lang 参数,那么它将使用默认值(在我的示例中为 en
)参数。
示例:
example.tld/application/test
lang
是 en
controller
是 IndexController
action
是 test
(testAction()
)
example.tld/de/application/test
lang
是 de
controller
是 IndexController
action
是 test
(testAction()
)
我想创建带有可选 [lang] 参数的路由,该参数将用于设置应用程序语言,如下所示:
带有默认语言参数的示例(例如 EN)
domain.tld/
domain.tld/users
domain.tld/contacts
etc.
新语言参数示例(DE for examle)
domain.tld/de
domain.tld/de/users
domain.tld/de/contacts
etc.
这是我的路线配置:
'router' => [
'routes' => [
'site' => [
'type' => Segment::class,
'options' => [
'route' => '[/:lang]',
'constraints' => [
'lang' => '[a-z]{2}',
],
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index',
'lang' => 'en',
],
],
'may_terminate' => true,
'child_routes' => [
'home' => [
'type' => Literal::class,
'options' => [
'route' => '/',
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index',
],
],
'may_terminate' => true,
],
'application' => [
'type' => Segment::class,
'options' => [
'route' => '/application[/:action]',
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index',
],
],
'may_terminate' => true,
],
],
],
],
]
当我在 url 中有 lang 参数时,一切都很好。但是当我尝试打开 "default" lang 而不在路径中指定它时(例如。tld/application/test)它给我 404 错误。
我发现从Segmentclass转换后的最终正则表达式是(\G(?:/(?P<param1>([a-z]{2})))?)
,路径是/application/test
。当 preg_match
在 Segment.php:385 上执行时,它 return 匹配以下值:
[
'0' => '/ad',
'param1' => 'ad',
'1' => 'ad',
],
这显然是错误的行为。我的语言设置为 "ad" 而不是打开 application/test 操作。我测试了大约 10 个正则表达式但没有成功......(例如 ^[a-z]{2}$
)。
我做错了什么?
你得到 404 因为 URL 不匹配 site
路由,所以 site
的子路由被跳过。
试试这个:
'home' => [
'type' => Segment::class,
'options' => [
'route' => '/[:lang/]',
'constraints' => [
'lang' => '(en|de)?',
],
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index',
'lang' => 'en',
],
],
'may_terminate' => true,
'child_routes' => [
'application' => [
'type' => Segment::class,
'options' => [
'route' => 'application[/:action]',
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index',
],
],
],
],
]
如果您不提供 lang 参数,那么它将使用默认值(在我的示例中为 en
)参数。
示例:
example.tld/application/test
lang
是en
controller
是IndexController
action
是test
(testAction()
)
example.tld/de/application/test
lang
是de
controller
是IndexController
action
是test
(testAction()
)