views:

192

answers:

3

I am working with Urls in the following format: "controller/action" where the slash is required.

I need to create a PCRE regex to match the controller and action names unless the controller name has the value of "home." For example:

  • "member/update" should produce "member", "update"
  • "admin/index" should produce "admin", "index"
  • "home/index" should produce <nomatch>

I've been playing around with look ahead, behind, and around and I have parts of it working but no totally correct solution. Any help appreciated.

** EDIT
Here's a little more background. I want to set up Zend routing so that

  • an url with just one part '/foo' dispatches to HomeController, i.e. '/home/foo'
  • any url with two parts '/controller/action' dispatches to that controller: e.g., '/member/update' dispatches to MemberController, '/member/update';   '/home/index' dispatches to HomeController, etc.

Right now I have routes set up as:

$router->addRoute('homeRoute', 
    new Zend_Controller_Router_Route(
        ':action',
        array('controller' => 'home', 'action' => 'index')
    )
);
$router->addRoute('memberRoute', 
    new Zend_Controller_Router_Route(
        'member/:action',
        array('controller' => 'member', 'action' => 'index')
    )
);
// and so on, a route for each non-Home controller: adminRoute, etc

This is working the way I want but it's ugly and a maintenance problem. I'm want to replace all of the routes 'memberRoute', 'adminRoute', etc, with a single Regex route:

$router->addRoute('siteRoute',
    new Zend_Controller_Router_Route_Regex(
        '????/:action',
        array('action' => 'index'),
        array(?? => 'controller')
    )
);

I have been running my regex experiments with a little php script like:

<?php
    preg_match('/????/', 'home/index', $output);
    echo '0=>'.$output[0].';';
    echo '1=>'.$output[1].';';
?>
A: 

(?:home.*)|([^/]*)(?:/(.*))?

hsz
<?php preg_match('/(?:home.*)|([^/]*)(?:/(.*))?/', 'c/a', $output);?> chokes with "Unknown modifier ']'"
Keith Morgan
It's necessary to escape `/` so try: `(?:home.*)|([^\/]*)(?:\/(.*))?`
hsz
Yeah, I escaped one but missed the other one. I haven't gotten the route to work yet but your regex is correct. Thanks.
Keith Morgan
A: 

I don't think regular expressions are the solution here. I've never worked with the zend framework before but in PHP it would be probably something like this

$string = "controller/action";
$pieces = explode('/', $string);
if ($pieces[0] == 'home') {
  // special code here
} else {
  // other code here
}
jonchang
A: 

When I hear, "..match everything but something", I think maybe it should be flipped around: how about matching just the something, or in this case, the 'home' controller?

// added last to be checked first
$router->addRoute(
  'home',
  new Zend_Controller_Router_Route(
    'home/:action',
    array('controller'  => 'home')
  )
);
Derek Illchuk
See edit above.
Keith Morgan