diff --git a/AltoRouter.php b/AltoRouter.php index d8ff998..5bd63b3 100644 --- a/AltoRouter.php +++ b/AltoRouter.php @@ -204,6 +204,8 @@ public function match($requestUrl = null, $requestMethod = null) $requestUrl = substr($requestUrl, 0, $strpos); } + $lastRequestUrlChar = $requestUrl[strlen($requestUrl)-1]; + // set Request Method if it isn't passed as a parameter if ($requestMethod === null) { $requestMethod = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'GET'; @@ -230,10 +232,12 @@ public function match($requestUrl = null, $requestMethod = null) // No params in url, do string comparison $match = strcmp($requestUrl, $route) === 0; } else { - // Compare longest non-param string with url - if (strncmp($requestUrl, $route, $position) !== 0) { + // Compare longest non-param string with url before moving on to regex + // Check if last character before param is a slash, because it could be optional if param is optional too (see https://github.com/dannyvankooten/AltoRouter/issues/241) + if (strncmp($requestUrl, $route, $position) !== 0 && ($lastRequestUrlChar === '/' || $route[$position-1] !== '/')) { continue; } + $regex = $this->compileRoute($route); $match = preg_match($regex, $requestUrl, $params) === 1; } @@ -254,6 +258,7 @@ public function match($requestUrl = null, $requestMethod = null) ]; } } + return false; } diff --git a/tests/AltoRouterTest.php b/tests/AltoRouterTest.php index fc4752b..4c125e3 100644 --- a/tests/AltoRouterTest.php +++ b/tests/AltoRouterTest.php @@ -371,7 +371,7 @@ public function testMatchWithPlainRoute() ->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. + // have any params in it $router->expects($this->never()) ->method('compileRoute'); @@ -384,8 +384,6 @@ public function testMatchWithPlainRoute() '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')); }