diff --git a/flight/net/Router.php b/flight/net/Router.php index d6e7519..26f8e84 100644 --- a/flight/net/Router.php +++ b/flight/net/Router.php @@ -71,7 +71,7 @@ class Router { } /** - * Tries to match a requst to a route. Also parses named parameters in the url. + * Tries to match a request to a route. Also parses named parameters in the url. * * @param string $pattern URL pattern * @param string $url Requested URL @@ -81,27 +81,36 @@ class Router { $ids = array(); // Build the regex for matching - $regex = '/^'.implode('\/', array_map( - function($str) use (&$ids){ - if ($str == '*') { - $str = '(.*)'; + $regex = preg_replace_callback( + '#@([\w]+)(:([^/\(\)]*))?#', + function($matches) use (&$ids) { + $ids[$matches[1]] = null; + if (isset($matches[3])) { + return '(?P<'.$matches[1].'>'.$matches[3].')'; } - else if ($str != null && $str{0} == '@') { - if (preg_match('/@(\w+)(\:([^\/|\(]*))?([\(|\)]+)?/', $str, $matches)) { - $ids[$matches[1]] = null; - return '(?P<'.$matches[1].'>' - .(!empty($matches[3]) ? $matches[3] : '[^(\/|\?)]+') - .')' - .(!empty($matches[4]) ? str_replace(')',')?',$matches[4]) : ''); - } - } - return $str; + return '(?P<'.$matches[1].'>[^/\?]+)'; }, - explode('/', $pattern) - )).'\/?(?:\?.*)?$/i'; + $pattern + ); + + // Allow trailing slash + if (substr($pattern, -1) === '/') { + $regex .= '?'; + } + else { + $regex .= '/?'; + } + + // Replace wildcard + if (substr($pattern, -1) === '*') { + $regex = str_replace('*', '.+?', $pattern); + } + + // Convert optional parameters + $regex = str_replace(')', ')?', $regex); // Attempt to match route and named parameters - if (preg_match($regex, $url, $matches)) { + if (preg_match('#^'.$regex.'(?:\?.*)?$#i', $url, $matches)) { foreach ($ids as $k => $v) { $this->params[$k] = (array_key_exists($k, $matches)) ? urldecode($matches[$k]) : null; }