Zend Framework 2 segment route required segment

php, routes, zend-framework-routing, zend-framework2, zend-route

Solution

I played around with it some more. After debugging, I still couldn't figure it out. I tried to add a default value to the `code` parameter and that seemed to do the trick. Why on Earth that works and how it makes sense, I have no idea. To me it shouldn't matter if I have a default value specified or not if I have provided a value in the URL for the parameter in the URL. Nevertheless, apparently it does matter - or at least in this case it did.

Here is the working code. I also updated the regular expression for the code parameter.

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

Problem

I am trying to make a route (or two) that will let me invoke two different actions with the below URL formats. ``` mydomain.com/profile mydomain.com/profile/1234/something ``` For the second format, the `1234` should be a required integer value, while `something` should be an optional string. The first format is simple by using a literal route. I thought I could add a segment child route for the second format, but I cannot get it to work. I tried to leave out the first format and only do the second one with a segment route, but I wasn't successful in that either. Here is what I tried: ``` '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' ) ) ) ) ) ``` For `mydomain.com/profile`, I get the following errror: ``` Fatal error: Uncaught exception 'Zend\View\Exception\RuntimeException' with message 'No RouteMatch instance provided' ``` For `mydomain.com/1234/something`, I get the following error: ``` Fatal error: Uncaught exception 'Zend\Mvc\Router\Exception\InvalidArgumentException' with message 'Missing parameter "code"' ``` The manual states the following: If a segment is optional, it should be surrounded by brackets. As an example, “/:foo[/:bar]” would match a “/” followed by text and assign it to the key “foo”; if any additional “/” characters are found, any text following the last one will be assigned to the key “bar”. Is that not exactly what I am doing? The above errors remain the same if I comment out the constraints. What am I missing here? Thanks in advance.

Original source