Zend Framework 2:使用RegEx的嵌套子路由与可选分段?如何处理错误的路径



在Zend Framework 2中,我希望能够创建这样的路由结构:

/list -> literal, will always be "list"
/list/industry -> segment, can be stuff like "private", "non-profit", "governmental "
/list/industry/type -> segment, can be stuff like "plumbing", "medical", "food"…
/list/industry/type/company -> segment, can be stuff like "Joe's plumbig", "Sally's Bakery"…

路线可以在每个部分之后结束,这意味着上面解释中的每一行都应该代表一条有效的路线。

为了解决这个问题,我想出了两个可能的解决方案:

1.使用一个带有4个递归嵌套子路由的文字路由(/list)。我的意思是:

'list' => array(
'type' => 'literal',
'options' => array(
'route' => '/list',
'defaults' => array(
'action' => 'list'
),
),
'may_terminate' => true,
'child_routes' => array(
'industry' => array(
'type' => 'segment',
'options' => array(
'route' => '/:industry',
'defaults' => array(
'action' => 'industry'
),
),
'may_terminate' => true,
'child_routes' => array(
'company-type' => array(
'type' => 'segment',
'options' => array(
'route' => '/:type',
'defaults' => array(
'action' => 'industry'
),
),
'may_terminate' => true,
'child_routes' => array(
'company' => array(
'type' => 'segment',
'options' => array(
'route' => '/:company',
'defaults' => array(
'action' => 'industry'
),
),
),
),
),
),
),
),
)

我真的不确定这是否是一种正确的方法。我希望这种方法可以使用不同的操作。

2.仅使用一个子路由,但可选择分段:

'list' => array(
'type' => 'literal',
'options' => array(
'route' => '/list'
),
'may_terminate' => true,
'child_routes' => array(
'my-child-route' => array(
'type' => 'segment',
'options' => array(
'route' => '[/:industry[/:type[/:company]]]',
),
),
),
)

虽然第二个想法的配置看起来更易于维护,但我怀疑控制器/操作结构会很混乱,因为如果我没有错的话,一个操作需要处理具有该结构的所有分段部分,所以我可以使用'defaults'来指定该操作,也可以这样做:

'options' => array(
'route' => '[/:action[/:type[/:company]]]',
'constraints' => array(
'artist' => '[industry]+'
),
),

industryAction()中,我需要做这样的事情(伪代码):

if ($this->params['company']) {
// …
} elseif ($this->params['type']) {
// …
}

在这种情况下,我不知道如何处理像/list/private/plumbing/sallys-bakery这样的错误URL——如果Sally’s Bakery存在,但显然不在"管道"下,该怎么办。

所以你看,我有一些想法,如何建立这样的路线结构,但我不确定它们是否有任何好处,也不确定如何进一步解决这个问题。

在Zend Framework 2中构建这样一个路由结构的推荐方法是什么?

我认为您的第一种方法没有任何问题:

  • 三条可能的路线指向显示的不同数据(根据数据类型)
  • 正如您已经说过的,您可以(也应该)使用不同的操作或事件控制器(我会这样做),使您的操作不受路由逻辑的影响(if/else)
  • 控制器/动作独立于路线,仅专注于一项任务(例如显示公司详细信息)
  • 事实上,我不同意第二个更容易维护的论点。例如,您不能在路由上添加不同的分支(例如industry/location/company)

在写作时,我突然想到了一些问题:

  • 显然,每家公司只能位于一个路线分支上。但是,如果一家公司在两个不同的行业或类型上市,会发生什么?两者都可以访问吗?这可能会很快导致不同URI上的重复内容(这与Unique标识符部分相矛盾,对搜索引擎排名非常不利)
  • 也许最好实现稍微不同的方式,只使用两条路线:一条用于列出公司(根据搜索条件,可以作为查询参数或可选路线片段),另一条用于列明公司的详细信息。这将产生两个非常干净的控制器,一个用于列出(包括过滤),另一个用于详细信息

这当然不知道你的要求和进一步的计划,可能也是一个偏好问题。

最新更新