mirror of
https://github.com/dannyvankooten/AltoRouter.git
synced 2025-08-04 15:37:45 +02:00
simplify loop for non-param substring (#131)
optimize comparison using strcmp functions
This commit is contained in:
@@ -189,50 +189,33 @@ class AltoRouter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach($this->routes as $handler) {
|
foreach($this->routes as $handler) {
|
||||||
list($methods, $_route, $target, $name) = $handler;
|
list($methods, $route, $target, $name) = $handler;
|
||||||
|
|
||||||
$method_match = (stripos($methods, $requestMethod) !== false);
|
$method_match = (stripos($methods, $requestMethod) !== false);
|
||||||
|
|
||||||
// Method did not match, continue to next route.
|
// Method did not match, continue to next route.
|
||||||
if (!$method_match) continue;
|
if (!$method_match) continue;
|
||||||
|
|
||||||
// Check for a wildcard (matches all)
|
if ($route === '*') {
|
||||||
if ($_route === '*') {
|
// * wildcard (matches all)
|
||||||
$match = true;
|
$match = true;
|
||||||
} elseif (isset($_route[0]) && $_route[0] === '@') {
|
} elseif (isset($route[0]) && $route[0] === '@') {
|
||||||
$pattern = '`' . substr($_route, 1) . '`u';
|
// @ regex delimiter
|
||||||
$match = preg_match($pattern, $requestUrl, $params);
|
$pattern = '`' . substr($route, 1) . '`u';
|
||||||
|
$match = preg_match($pattern, $requestUrl, $params) === 1;
|
||||||
|
} elseif (($position = strpos($route, '[')) === false) {
|
||||||
|
// No params in url, do string comparison
|
||||||
|
$match = strcmp($requestUrl, $route) === 0;
|
||||||
} else {
|
} else {
|
||||||
$route = null;
|
// Compare longest non-param string with url
|
||||||
$regex = false;
|
if (strncmp($requestUrl, $route, $position) !== 0) {
|
||||||
$j = 0;
|
continue;
|
||||||
$n = isset($_route[0]) ? $_route[0] : null;
|
|
||||||
$i = 0;
|
|
||||||
|
|
||||||
// Find the longest non-regex substring and match it against the URI
|
|
||||||
while (true) {
|
|
||||||
if (!isset($_route[$i])) {
|
|
||||||
break;
|
|
||||||
} elseif (false === $regex) {
|
|
||||||
$c = $n;
|
|
||||||
$regex = $c === '[' || $c === '(' || $c === '.';
|
|
||||||
if (false === $regex && false !== isset($_route[$i+1])) {
|
|
||||||
$n = $_route[$i + 1];
|
|
||||||
$regex = $n === '?' || $n === '+' || $n === '*' || $n === '{';
|
|
||||||
}
|
}
|
||||||
if (false === $regex && $c !== '/' && (!isset($requestUrl[$j]) || $c !== $requestUrl[$j])) {
|
|
||||||
continue 2;
|
|
||||||
}
|
|
||||||
$j++;
|
|
||||||
}
|
|
||||||
$route .= $_route[$i++];
|
|
||||||
}
|
|
||||||
|
|
||||||
$regex = $this->compileRoute($route);
|
$regex = $this->compileRoute($route);
|
||||||
$match = preg_match($regex, $requestUrl, $params);
|
$match = preg_match($regex, $requestUrl, $params) === 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(($match == true || $match > 0)) {
|
if ($match) {
|
||||||
|
|
||||||
if ($params) {
|
if ($params) {
|
||||||
foreach($params as $key => $value) {
|
foreach($params as $key => $value) {
|
||||||
|
@@ -306,6 +306,33 @@ class AltoRouterTest extends PHPUnit_Framework_TestCase
|
|||||||
$this->assertFalse($this->router->match('/users/1/create', 'GET'));
|
$this->assertFalse($this->router->match('/users/1/create', 'GET'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testMatchWithPlainRoute()
|
||||||
|
{
|
||||||
|
$router = $this->getMockBuilder('AltoRouterDebug')
|
||||||
|
->setMethods(array('compileRoute'))
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
// this should prove that compileRoute is not called when the route doesn't
|
||||||
|
// have any params in it, but this doesn't work because compileRoute is private.
|
||||||
|
$router->expects($this->never())
|
||||||
|
->method('compileRoute');
|
||||||
|
|
||||||
|
$router->map('GET', '/contact', 'website#contact', 'contact');
|
||||||
|
|
||||||
|
// exact match, so no regex compilation necessary
|
||||||
|
$this->assertEquals(array(
|
||||||
|
'target' => 'website#contact',
|
||||||
|
'params' => array(),
|
||||||
|
'name' => 'contact'
|
||||||
|
), $router->match('/contact', 'GET'));
|
||||||
|
|
||||||
|
$router->map('GET', '/page/[:id]', 'pages#show', 'page');
|
||||||
|
|
||||||
|
// no prefix match, so no regex compilation necessary
|
||||||
|
$this->assertFalse($router->match('/page1', 'GET'));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public function testMatchWithServerVars()
|
public function testMatchWithServerVars()
|
||||||
{
|
{
|
||||||
$this->router->map('GET', '/foo/[:controller]/[:action]', 'foo_action', 'foo_route');
|
$this->router->map('GET', '/foo/[:controller]/[:action]', 'foo_action', 'foo_route');
|
||||||
|
Reference in New Issue
Block a user