Issues

ZF2-437: Router HTTP Segment does not handle defaults correctly when matching

Issue Type: Bug Created: 2012-08-01T10:32:49.000+0000 Last Updated: 2012-08-01T11:46:27.000+0000 Status: Resolved Fix version(s): Reporter: Russell Brown (fokeyjoe) Assignee: Ben Scholzen (dasprid) Tags: - Zend\Mvc\Router

  • defaults
  • routing
  • segment
  • url

Related issues: - ZF2-408

Attachments:

Description

This might be same problem as (ZF2-408), but didn't want to piggyback in case it isn't.

When reassembling a URL from a routematch that contains defaults, it does not reconstruct the URL properly. My router config:

<pre class="literal">
'media' => array (
    'type' => 'Zend\Mvc\Router\Http\Segment',
    'options' => array (
        'route' => '/media[/:title][/:mediatype][/:item][/]',
        'constraints' => array (
            'mediatype' => ('videos|screenshots'),
            'title' => ('shakespeare|pinter')
        ),
        'defaults' => array (
            'mediatype' => '',
            'action' => 'index',
            'controller' => 'MyModule\Controller\MediaController',
        ),
    ),
),

If I enter a url of /media/videos/, my RouteMatch looks like this:

<pre class="literal">
object(Zend\Mvc\Router\Http\RouteMatch)[190]
  protected 'length' => int 25
  protected 'params' => 
    array
      'subpage' => string 'videos' (length=11)
      'action' => string 'index' (length=5)
      'controller' => string 'MyModule\Controller\MediaController' (length=35)
      'title' => string '' (length=0)
  protected 'matchedRouteName' => null

This URL works and is accessible. However, if I am assembling this URL using this RouteMatch object, i.e. for a redirect, e.g.:

<pre class="literal">
$router = $event->getRouter();
$params = $routeMatch->getParams();
$redirectUrl = $router->assemble($params, array(
   'name' => $routeMatch->getMatchedRouteName()
));

$redirectUrl ends up looking like: /media//videos/. This is because title is present as an empty string instead of being null or not present at all. I have tried setting title => null in the defaults config, but this doesn't do anything. Nor do I want to be explicit in the redirector because it serves as a sitewide redirector.

Having looked at the source, it looks to me like the problem lies with the array_merge in match() when it's building the RouteMatch object (see https://github.com/zendframework/zf2/… line 337). The regexp returns this:

<pre class="literal">
array
  0 => string '/media/videos/' (length=15)
  'param1' => string '' (length=0)
  1 => string '' (length=0)
  'param2' => string 'videos' (length=6)
  2 => string 'videos' (length=6)

So you get empty strings for the optional parameters when they're not found. These are then combined with the defaults and unfortunately override the defaults, so in the case above the "title" parameter will be empty string. To give the arguments that "optional" feel, if the regexp returns an empty string it should unset or return null in the RouteMatch that it builds.

Comments

Posted by Ben Scholzen (dasprid) on 2012-08-01T11:46:27.000+0000

It is in fact the same issue.

Have you found an issue?

See the Overview section for more details.

Copyright

© 2006-2016 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.

Contacts