Zend Framework 2段路由所需的段

时间:2013-02-23 20:31:46

标签: php routing zend-framework2 zend-route zend-framework-routing

我正在尝试创建一个路径(或两个),让我可以使用以下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"'

manual states the following

  

如果某个细分是可选的,则应该用括号括起来。作为一个   例如,“/:foo [/:bar]”将匹配“/”后跟文本和赋值   它关键的“foo”;如果找到任何额外的“/”字符,任何   最后一个文本后面的文本将被分配给键“bar”。

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

我在这里缺少什么?提前谢谢。

5 个答案:

答案 0 :(得分:5)

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

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

'users' => array(
    'type' => 'segment',
    'options' => array(
        'route' => '/users[/:user_id]',
        'constraints' => array(
            'user_id' => '[0-9]*',
        ),
        'defaults' => array(
            'controller' => 'My\Controller\User',
            'user_id' => ""
        )
    ),

答案 1 :(得分:4)

我还在玩弄它。经过调试,我仍然无法弄明白。我试图在code参数中添加一个默认值,这似乎可以解决问题。为什么在地球上有效以及如何有意义,我不知道。对我而言,如果我在URL中为参数的URL提供了一个值,那么我是否有指定的默认值并不重要。然而,显然它确实很重要 - 或者至少在这种情况下确实如此。

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

'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,
                ),
            ),
        ),
    ),
),

答案 2 :(得分:1)

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

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

答案 3 :(得分: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(
    ...

答案 4 :(得分:0)

根据Bittarman的说法,有两个原因。他说,主要原因是:

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

我显然有较小的原因: 我在布局中使用了$ this-&gt; 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