Zend route regex, optional parameters

跟風遠走 提交于 2020-01-06 03:27:11

问题


I need some help about my routes in Zend (Zend1) ...

I need that I can use my route like that :

http://mywebsite.com/myfolder/region/job/   
http://mywebsite.com/myfolder/region/job/add  
http://mywebsite.com/myfolder/region/job/add/page  
http://mywebsite.com/myfolder/region/job/page   

Parameters add and page are optional ...

This is what I did

$route = new Zend_Controller_Router_Route_Regex(
          'myfolder/([^/]+)/([^/]+)/?([^/]+)?/?([0-9]+)?',
          array('controller'    => 'myfolder','action'  => 'search'), 
          array(1 => 'region',2 => 'job', 3 => 'add', 4 => 'page'), 
          'myfolder/%s/%s/%s/%s'
         ); 

Obviously, it doesn't work ... What I want? I want that last the two parameters (add and page) are optional ...

Can you help me? what's wrong with my regex?

EDIT 1:

Ok, so I tried it, but isn't ok ...
I need that parameters add and page are optional ...

    $route = new Zend_Controller_Router_Route(
'myfolder/:region/:job/:add/:page',
array(
    'controller'    => 'myfolder',
    'action'        => 'search',
    'region'        => 'XX',
    'job'        => '',
    'add'    => '',
    'page'      => 1
),
array(
    'region' => '[a-zA-Z-_0-9-]+',
    'job' => '[a-zA-Z-_0-9-]+',
    'add' => '[a-zA-Z-_]+',
    'page' => '\d+'
)
);  

With that, this one http://mywebsite.com/myfolder/region/job/page doesn't work ...

EDIT 2:

I also tried with 'myfolder/:region/:job/*', but the result is same, doesn't work as I want ...
I really wonder if it is possible ...

EDIT 3:##

$route = new Zend_Controller_Router_Route_Regex('myfolder/([^/]+)/([^/]+)(?:/|$)(?:(?!\d+(?:/|$))([^/]+)(?:/|$))?(?:(\d+)(?:/|$))?$',
      array('controller'    => 'myfolder', 'action' => 'recherche', 'presta' => ''), 
      array(1 => 'region',2 => 'job', 3 => 'presta', 4 => 'page'), 
      'myfolder/%s/%s/%s/%s');

回答1:


Prepare yourself.

The RegEx

myfolder/([^/]+)/([^/]+)(?:/|$)(?:(?!\d+(?:/|$))([^/]+)(?:/|$))?(?:(\d+)(?:/|$))?$

See it working on RegExr (on RegExr, I had to add \n\r to one of the negated classes so it didn't match all my line breaks, in practice you probably won't be dealing with line breaks though.)

The important thing to note on RegExr is that in the 4th case, the page number is in the 4th capture group, with nothing in the 3rd group.

Explanation

myfolder/([^/]+)/([^/]+) All looking good up to here, no changes yet.

(?:/|$) Match a / or end of input.

Next, overall we have a non-capturing group that is optional. This would be the add section.

(?:(?!\d+(?:\|$))([^/]+)(?:/|$))?

Now lets break it down further:

(?!\d+(?:/|$)) Make sure its not a page number - digits only followed by / or end of input. (Negative lookahead)

([^/]+) Our capture group - add in the example.

(?:/|$) Match a / or end of input.

Now for our page number group, again it's optional and non-capturing:

(?:(\d+)(?:/|$))? Captures the numbers, then matches / or end of input again.

$ And just in case it tries to match substrings of actual matches, I threw in another end of input anchor (since you can match as many in a row as you like), although the regex functions without it.


Generating The Path

What you basically want is a way of doing this:

At the moment the 2nd and 3rd parameters are:

array(1 => 'region',2 => 'job', 3 => 'add', 4 => 'page'), 
'myfolder/%s/%s/%s/%s'

You want them to be something like:

array(1 => 'region',2 => 'job', 3 => '/'+'add', 4 => '/'+'page'), 
'myfolder/%s/%s%s%s'

Where you only add the / if the optional group is present. The code above won't work but perhaps there is some way you could implement that.



来源:https://stackoverflow.com/questions/20189436/zend-route-regex-optional-parameters

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!