title: Zend 2 router - optional unknown parameters
body: <p>We have standart route from sample</p>
  
  <pre><code>            array(
                  'type'    =&gt; 'Literal',
                  'options' =&gt; array(
                      'route'    =&gt; '/application',
                      'defaults' =&gt; array(
                          '__NAMESPACE__' =&gt; 'Application\Controller',
                          'controller'    =&gt; 'Index',
                          'action'        =&gt; 'index',
                      ),
                  ),
                  'may_terminate' =&gt; true,
                  'child_routes' =&gt; array(
                      'default' =&gt; array(
                          'type'    =&gt; 'Segment',
                          'options' =&gt; array(
                              'route'    =&gt; '/[:controller[/:action]]',
                              'constraints' =&gt; array(
                                  'controller' =&gt; '[a-zA-Z][a-zA-Z0-9_-]*',
                                  'action'     =&gt; '[a-zA-Z][a-zA-Z0-9_-]*',
                              ),
                              'defaults' =&gt; array(
                              ),
                          ),
                      ),
                  ),
                  'priority' =&gt; -1000,
              ),
  </code></pre>
  
  <p>It understands URLs like</p>
  
  <pre><code>/application
  /application/some
  /application/index/about
  </code></pre>
  
  <p>But it not understands URLs like</p>
  
  <pre><code>/application/index/about/param1/val1/param2/val2/...
  </code></pre>
  
  <p>In Zend1 was *, we could add it to route like this</p>
  
  <pre><code> 'route'    =&gt; '/:controller/:action/*',
  </code></pre>
  
  <p>And all parameters after * tried to split by slash. Question: is there way in zend 2 to create routes with unknown parameter-names? One solution is create own route type, but may be exists built-in solutions?</p>
  
  <p><strong>UPD</strong>:</p>
  
  <p>I have wrote myself Route class, that parses * on roure-end , and non-required parameters will parse in ZF1 style. </p>
  
  <pre><code>&lt;?php
  
  namespace Engine\Mvc\Router\Http;
  
  use Zend\I18n\Translator\TranslatorInterface as Translator;
  use Zend\Mvc\Router\Exception;
  use Zend\Stdlib\RequestInterface as Request;
  
  class Segment extends \Zend\Mvc\Router\Http\Segment
  {
      protected $unknownParameterParse = false;
      protected $route = null;
      public function __construct($route, array $constraints = [], array $defaults = [])
      {
          if ($route{mb_strlen($route)-1} == '*'){
              $route = mb_substr($route, 0, mb_strlen($route)-1);
              $this-&gt;unknownParameterParse = true;
          }
          $this-&gt;route = $route;
          parent::__construct($route, $constraints, $defaults);
      }
  
      public function assemble(array $params = [], array $options = []) {
          $path = parent::assemble($params, $options);
          if ($this-&gt;unknownParameterParse){
              $unknowns = [];
  
              foreach($params as $key=&gt;$value){
                  if (strpos($this-&gt;route, ':'.$key)===false ){
                      $unknowns[] = $this-&gt;encode($key) . '/'. $this-&gt;encode($value);
                  }
              }
              if ($unknowns){
                  $path = rtrim($path, '/').'/'.implode('/', $unknowns);
              }
          }
          return $path;
      }
  
      public function match(Request $request, $pathOffset = null, array $options = [])
      {
          if (!method_exists($request, 'getUri')) {
              return;
          }
  
          $uri  = $request-&gt;getUri();
          $path = $uri-&gt;getPath();
  
          $regex = $this-&gt;regex;
  
          if ($this-&gt;translationKeys) {
              if (!isset($options['translator']) || !$options['translator'] instanceof Translator) {
                  throw new Exception\RuntimeException('No translator provided');
              }
  
              $translator = $options['translator'];
              $textDomain = (isset($options['text_domain']) ? $options['text_domain'] : 'default');
              $locale     = (isset($options['locale']) ? $options['locale'] : null);
  
              foreach ($this-&gt;translationKeys as $key) {
                  $regex = str_replace('#' . $key . '#', $translator-&gt;translate($key, $textDomain, $locale), $regex);
              }
          }
  
          if ($pathOffset !== null) {
              $result = preg_match('(\G' . $regex . ')', $path, $matches, null, $pathOffset);
          } else {
              $result = preg_match('(^' . $regex . ($this-&gt;unknownParameterParse ? '' : '$') . ')', $path, $matches);
          }
  
  
          if (!$result) {
              return;
          }
          $matchedLength = strlen($matches[0]);
          $params        = [];
  
          foreach ($this-&gt;paramMap as $index =&gt; $name) {
              if (isset($matches[$index]) &amp;&amp; $matches[$index] !== '') {
                  $params[$this-&gt;decode($name)] = $this-&gt;decode($matches[$index]);
              }
          }
  
          /*ENGINE get not defined params*/
          if ($this-&gt;unknownParameterParse){
              $otherParams = explode("/", trim(substr($path, strlen($matches[0])), "/") );
              foreach($otherParams as $i=&gt;$param){
                  if ($i%2 == 0){
                      $pairKey = $param;
                  }else{
                      $params[$pairKey] = $param;
                  }
              }
          }
          /* endof get not defined params */
          return new \Zend\Mvc\Router\Http\RouteMatch(array_merge($this-&gt;defaults, $params), $matchedLength);
      }
  }
  </code></pre>
  
  <p>How said chaoss88 it perfectly does Wildcard route: we can make parent-route with Segment type, and child route with Wildcard type. But class above some more proger-friendly. Routes like this:</p>
  
  <pre><code>'route'    =&gt; '/core/:controller[/:action]*'
  </code></pre>
  
  <p>Working good. But Wildcard router has security issues if you are using ZF2 router as grant of request filtration - thats why it's deprecated. But I think router is for url parse/assemble, not for filtration: for filtration/validation ZF2 has much better solutions.</p>