4

我正在尝试制作一条(或两条)路线,让我使用以下 URL 格式调用两个不同的操作。

mydomain.com/profile
mydomain.com/profile/1234/something

对于第二种格式,1234应该是必需的整数值,而something应该是可选字符串。第一种格式很简单,使用文字路由。我以为我可以为第二种格式添加一个分段子路由,但我无法让它工作。我试图省略第一种格式,只使用分段路线做第二种格式,但我也没有成功。

这是我尝试过的:

'profile' => array(
    'type' => 'Zend\Mvc\Router\Http\Literal',
    'options' => array(
        'route' => '/profile',
        'defaults' => array(
            'controller' => 'User\Controller\User',
            'action' => 'profile'
        )
    ),
    'child_routes' => array(
        'profile_view' => array(
            'type' => 'Zend\Mvc\Router\Http\Segment',
            'options' => array(
                'route' => '/:code[/:username]',
                'constraints' => array(
                    'code' => '[0-9]*',
                    'username' => '[a-zA-Z0-9_-]*'
                ),
                'defaults' => array(
                    'controller' => 'User\Controller\User',
                    'action' => 'view_profile'
                )
            )
        )
    )
)

对于mydomain.com/profile,我得到以下错误:

Fatal error: Uncaught exception 'Zend\View\Exception\RuntimeException' with message 'No RouteMatch instance provided'

对于mydomain.com/1234/something,我收到以下错误:

Fatal error: Uncaught exception 'Zend\Mvc\Router\Exception\InvalidArgumentException' with message 'Missing parameter "code"'

手册指出以下内容

如果一个段是可选的,它应该用括号括起来。例如,“/:foo[/:bar]”将匹配“/”后跟文本并将其分配给键“foo”;如果发现任何额外的“/”字符,则最后一个字符之后的任何文本都将分配给键“bar”。

这不正是我正在做的吗?如果我注释掉约束,上述错误保持不变。

我在这里想念什么?提前致谢。

4

5 回答 5

5

我的解决方案:将可选参数的默认值设置为空字符串

我遇到了类似的问题,我通过设置可选参数的默认值来解决它(在你的情况下,“用户名”为空字符串“”;我的解决方案:

'users' => array(
    'type' => 'segment',
    'options' => array(
        'route' => '/users[/:user_id]',
        'constraints' => array(
            'user_id' => '[0-9]*',
        ),
        'defaults' => array(
            'controller' => 'My\Controller\User',
            'user_id' => ""
        )
    ),
于 2013-09-17T12:20:20.630 回答
4

我又玩了一些。经过调试,我仍然无法弄清楚。我试图为code参数添加一个默认值,这似乎起到了作用。为什么在地球上有效,以及它是如何有意义的,我不知道。对我来说,如果我在 URL 中为 URL 中的参数提供了一个值,是否指定了默认值并不重要。尽管如此,显然它确实很重要 - 或者至少在这种情况下它确实重要。

这是工作代码。我还更新了 code 参数的正则表达式。

'profile' => array(
    'type' => 'Zend\Mvc\Router\Http\Literal',
    'options' => array(
        'route' => '/profile',
        'defaults' => array(
            'controller' => 'User\Controller\User',
            'action'     => 'profile',
        ),
    ),
    'may_terminate' => true,
    'child_routes' => array(
        'view' => array(
            'type' => 'Zend\Mvc\Router\Http\Segment',
            'options' => array(
                'route' => '/:code[/:username]',
                'constraints' => array(
                    'code' => '\d+',
                    'username' => '[a-zA-Z0-9_-]*',
                ),
                'defaults' => array(
                    'controller' => 'User\Controller\User',
                    'action' => 'viewProfile',
                    'code' => 0,
                ),
            ),
        ),
    ),
),
于 2013-02-25T20:12:17.287 回答
1

您得到的第二个例外Missing parameter "code"来自组装,而不是匹配。这意味着您在组装路线时没有提供代码profile/profile_view

顺便说一句,您不必在 child_routes 前面加上父路由的名称。只需将子路由称为“视图”,并将其组装为profile/view.

于 2013-02-25T04:38:31.930 回答
0

我相信您缺少该may_terminate选项,如下所示:

'profile' => array(
    'type' => 'Zend\Mvc\Router\Http\Literal',
    'options' => array(
        'route' => '/profile',
        'defaults' => array(
            'controller' => 'User\Controller\User',
            'action' => 'profile'
        )
    ),
    'may_terminate' => true,
    'child_routes' => array(
    ...
于 2013-02-23T22:33:26.697 回答
0

根据 Bittarman,发生这种情况的原因有两个。他说,主要原因是:

<Bittarman> ezio, that looks like what happens when you make a new phprenderer rather than using the configured one

我显然有较小的原因:我在我的布局中使用了 $this->url() 。因为没有路由匹配——一个 404 错误——它在所有 404 错误上都被炸毁了。

<Bittarman> for all of those things, stop doing if (!$this->url() == $this->url('home') etc
<ezio> ummm when it's home my business partner wants the whole order changed so google can hit on a bunch of keyords
<Bittarman> instead, in the VIEW for home, set what you need.
<ezio> how would i set the second example where i'm trying to highlight the currently-being-used menu item
<Bittarman> so, in your layout, you just want echo $this->headTitle()->setSeparator(' - ')->setAutoEscape(false)
<Bittarman> ezio, use the placeholder view helper
<ezio> okay
<ezio> thanks Bittarman ... tearing my hair out is not fun when you're already losing so much of it :p
<Bittarman> <?= $this->placeholder('currently-being-used') ?>
<Bittarman> and in your view, <?php $this->placeholder('currently-being-used')->append('foo') ?>
<ezio> sense making a lot you are
于 2013-09-14T23:08:26.320 回答