109 lines
3.0 KiB
PHP
109 lines
3.0 KiB
PHP
<?php
|
|
|
|
namespace App\Core;
|
|
|
|
class Router
|
|
{
|
|
private static ?Router $instance = null;
|
|
private array $routes = [];
|
|
private array $groups = [];
|
|
|
|
public static function getInstance(): Router
|
|
{
|
|
if (self::$instance === null) {
|
|
self::$instance = new self();
|
|
}
|
|
return self::$instance;
|
|
}
|
|
|
|
public function get(string $path, array $handler, array $options = []): void
|
|
{
|
|
$this->addRoute('GET', $path, $handler, $options);
|
|
}
|
|
|
|
public function post(string $path, array $handler, array $options = []): void
|
|
{
|
|
$this->addRoute('POST', $path, $handler, $options);
|
|
}
|
|
|
|
public function put(string $path, array $handler, array $options = []): void
|
|
{
|
|
$this->addRoute('PUT', $path, $handler, $options);
|
|
}
|
|
|
|
public function delete(string $path, array $handler, array $options = []): void
|
|
{
|
|
$this->addRoute('DELETE', $path, $handler, $options);
|
|
}
|
|
|
|
public function group(array $attributes, callable $callback): void
|
|
{
|
|
$this->groups[] = $attributes;
|
|
$callback($this);
|
|
array_pop($this->groups);
|
|
}
|
|
|
|
private function addRoute(string $method, string $path, array $handler, array $options = []): void
|
|
{
|
|
// Apply group middleware
|
|
$middleware = $options['middleware'] ?? [];
|
|
foreach ($this->groups as $group) {
|
|
if (isset($group['middleware'])) {
|
|
$middleware = array_merge($middleware, (array)$group['middleware']);
|
|
}
|
|
}
|
|
|
|
$route = [
|
|
'method' => $method,
|
|
'path' => $path,
|
|
'controller' => $handler[0],
|
|
'method' => $handler[1],
|
|
'middleware' => $middleware,
|
|
'pattern' => $this->buildPattern($path),
|
|
];
|
|
|
|
$this->routes[] = $route;
|
|
}
|
|
|
|
public function match(string $method, string $path): ?array
|
|
{
|
|
foreach ($this->routes as $route) {
|
|
if ($route['method'] !== $method) {
|
|
continue;
|
|
}
|
|
|
|
if (preg_match($route['pattern'], $path, $matches)) {
|
|
// Extract parameters
|
|
$params = [];
|
|
preg_match_all('/\{([^}]+)\}/', $route['path'], $paramNames);
|
|
|
|
for ($i = 0; $i < count($paramNames[1]); $i++) {
|
|
$paramName = $paramNames[1][$i];
|
|
$params[$paramName] = $matches[$i + 1] ?? null;
|
|
}
|
|
|
|
return [
|
|
'controller' => $route['controller'],
|
|
'method' => $route['method'],
|
|
'middleware' => $route['middleware'],
|
|
'params' => $params,
|
|
];
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private function buildPattern(string $path): string
|
|
{
|
|
// Convert route parameters to regex pattern
|
|
$pattern = preg_replace('/\{([^}]+)\}/', '([^/]+)', $path);
|
|
return '#^' . $pattern . '$#';
|
|
}
|
|
|
|
public function getRoutes(): array
|
|
{
|
|
return $this->routes;
|
|
}
|
|
}
|