Zf2 view helper URL child route with same params

2019-08-07 05:21发布

I cannot create a proper url using the URL view-helper when parent and child route have common/same params.

my url config:

'contact' => array(
    'type' => 'Segment',
    'options' => array(
        'route' => '/contact[/:contact][/action/:action]',
        'constraints' => array(
            'contact' => '[0-9]+',
            'action'  => '[a-zA-Z_-]+',
        ),
        'defaults' => array(
            'controller' => 'CrmContact',
            'action'     => 'index',
        ),
    ),
    'may_terminate' => true,
    'child_routes' => array(
        'task' => array(
            'type' => 'Segment',
            'options' => array(
                'route' => '/task[/:task][/action/:action]',
                'constraints' => array(
                    'task' => '[0-9]+',
                    'action'  => '[a-zA-Z_-]+',
                ),
                'defaults' => array(
                    'controller' => 'CrmTask',
                    'action'     => 'index',
                ),
            ),
        ),
    )
)

As it is obvious both parent and child routes contain the param "action", this route works perfectly fine when called upon directly meaning if you hit the browser with '/contact/1/task/1/action/edit' all is god. The problems arise when trying to construct this url using the viewhelper Url

$this->url('contact/task', array('contact' => $contact->id,'task' => $task->id, 'action' => 'edit'))

This produces the wrong url though, namely

/contact/1/action/edit/task/1    instead of 
/contact/1/task/1/action/edit

the helper basically hijacks the action param from the child route and uses it for the parent route... I cannot stop using the param 'action' since it is part of the frameworks way of routing request across the controllers methods....

2条回答
家丑人穷心不美
2楼-- · 2019-08-07 05:35

Your route contact and your child route task are associated with different controllers. So you can separate them like this.

 'contact' => array(
    'type' => 'Segment',
    'options' => array(
        'route' => '/contact[/:contact][/action/:action]',
        'constraints' => array(
            'contact' => '[0-9]+',
            'action' => '[a-zA-Z_-]+',
        ),
        'defaults' => array(
            'controller' => 'crm-contact',
            'action' => 'index',
        ),
    ),
),
'task' => array(
    'type' => 'Segment',
    'options' => array(
        'route' => '/task[/:task][/action/:action]',
        'constraints' => array(
            'task' => '[0-9]+',
            'action' => '[a-zA-Z_-]+',
        ),
        'defaults' => array(
            'controller' => 'crm-task',
            'action' => 'index',
        ),
    ),
),

Also the default routes are controller/action. So separate controllers are usually in separate routes. If you need to have your contact id in your task route you can change the route to
'route' => 'contact/:contact/task[/:task][/action/:action]', Also you can rename task and contact constraints as task_id and contact_id for clarity.

查看更多
该账号已被封号
3楼-- · 2019-08-07 05:53

The reason I want to keep "task" as child route of "contact" is because task makes sense only under contact, it's basically a many-to-one relation. I resolved it by breaking it in more child routes:

'contact' => array(
    'type' => 'Segment',
    'options' => array(
        'route' => '/contact[/:contact]',
        'constraints' => array(
            'contact' => '[0-9]+',
        ),
        'defaults' => array(
            'controller' => 'CrmContact',
            'action'     => 'index',
        ),
    ),
    'may_terminate' => true,
    'child_routes' => array(
        'contact_action' => array(
            'type' => 'Segment',
            'options' => array(
                'route' => '/action/:action',
                'constraints' => array(
                    'contact' => '[0-9]+',
                    'action'  => '[a-zA-Z_-]+',
                ),
                'defaults' => array(
                    'controller' => 'CrmContact',
                    'action'     => 'index',
                ),
            ),
        ),
        'task' => array(
            'type' => 'Segment',
            'options' => array(
                'route' => '/task[/:task]/action/:action',
                'constraints' => array(
                    'task' => '[0-9]+',
                    'action'  => '[a-zA-Z_-]+',
                ),
                'defaults' => array(
                    'controller' => 'CrmTask',
                    'action'     => 'index',
                ),
            ),
        ),
    )
),
查看更多
登录 后发表回答