refactored routing to handle any number of parameters

This commit is contained in:
tracer 2022-10-22 12:43:57 +02:00
parent 2a8fa3f397
commit 1ad567f337
1 changed files with 28 additions and 35 deletions

View File

@ -3,51 +3,44 @@
namespace App\Service;
use App\Entity\Route;
use Closure;
class Router
{
private array $uri;
private array $routes;
public function __construct()
/*
* This method takes a route like /admin/users/{user} and create a regex to match on call
*/
function addRoute(string $name, string $route, Closure $callback): void
{
$uri = parse_url(url: $_SERVER['REQUEST_URI'], component: PHP_URL_PATH);
$this->uri = explode(separator: '/', string: $uri);
}
// check for parameters
preg_match_all(pattern: "/(?<={).+?(?=})/", subject: $route, matches: $matches);
$parameters = $matches[0];
public function registerRoute(string $route, \Closure $callback): void
{
$this->routes[$route] = $callback;
}
// create regex for route:
$regex = preg_replace(pattern: '/(?<={).+?(?=})/', replacement: '(.*?)', subject: $route);
$regex = str_replace(search: '{', replace: '', subject: $regex);
$regex = str_replace(search: '}', replace: '', subject: $regex);
$regex = '/^' . str_replace(search: "/", replace: '\\/', subject: $regex) . '$/i';
$route = new Route(name: $name, route: $route, regEx: $regex, parameters: $parameters, callback: $callback);
private function matchRoute($url = '/users/tracer/posts/tracer', $method = 'GET')
{
$reqUrl = $url;
$reqUrl = rtrim(string: $reqUrl, characters: "/");
foreach ($this->routes as $route => $closure) {
// convert urls like '/users/:uid/posts/:pid' to regular expression
// $pattern = "@^" . preg_replace('/\\\:[a-zA-Z0-9\_\-]+/', '([a-zA-Z0-9\-\_]+)', preg_quote($route['url'])) . "$@D";
$pattern = "@^" . preg_replace('\\/users/:[a-zA-Z0-9\_\-]+/', '([a-zA-Z0-9\-\_]+)', $route) . "$@D";
// echo $pattern."\n";
$params = [];
// check if the current request params the expression
$match = preg_match($pattern, $reqUrl, $params);
if ($match) {
// remove the first match
array_shift($params);
// call the callback with the matched positions as params
// return call_user_func_array($route['callback'], $params);
return [$route, $params];
}
}
return [];
$this->routes[] = $route;
}
public function handleRouting(): void
{
$foo = $this->matchRoute();
var_dump($foo);
$requestUri = $_SERVER['REQUEST_URI'];
foreach ($this->routes as $route) {
if (preg_match(pattern: $route->getRegex(), subject: $requestUri, matches: $matches)) {
$parameters = [];
foreach ($route->getParameters() as $id => $parameter) {
$parameters[$parameter] = $matches[$id +1];
}
call_user_func(callback: $route->getCallback(), args: $parameters);
}
}
}
}