шаг 4 завершен
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Core;
|
||||
|
||||
final class Router
|
||||
{
|
||||
/**
|
||||
* @var array<int, array{method: string, pattern: string, handler: callable}>
|
||||
*/
|
||||
private array $routes = [];
|
||||
|
||||
public function get(string $pattern, callable $handler): void
|
||||
{
|
||||
$this->routes[] = ['method' => 'GET', 'pattern' => $pattern, 'handler' => $handler];
|
||||
}
|
||||
|
||||
public function dispatch(string $method, string $uri): void
|
||||
{
|
||||
$path = parse_url($uri, PHP_URL_PATH) ?: '/';
|
||||
$path = rtrim($path, '/') ?: '/';
|
||||
|
||||
foreach ($this->routes as $route) {
|
||||
if ($route['method'] !== $method) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$params = $this->match($route['pattern'], $path);
|
||||
|
||||
if ($params === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
($route['handler'])(...$params);
|
||||
return;
|
||||
}
|
||||
|
||||
http_response_code(404);
|
||||
view('pages/404', [
|
||||
'title' => 'Страница не найдена - Рыбсток',
|
||||
'breadcrumbs' => [
|
||||
['title' => 'Главная', 'url' => '/'],
|
||||
['title' => 'Страница не найдена'],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, string>|null
|
||||
*/
|
||||
private function match(string $pattern, string $path): ?array
|
||||
{
|
||||
$regex = preg_replace('#\{([a-zA-Z_][a-zA-Z0-9_]*)\}#', '([^/]+)', $pattern);
|
||||
$regex = '#^' . rtrim((string) $regex, '/') . '$#u';
|
||||
|
||||
if ($pattern === '/') {
|
||||
$regex = '#^/$#u';
|
||||
}
|
||||
|
||||
if (!preg_match($regex, $path, $matches)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
array_shift($matches);
|
||||
|
||||
return array_map('urldecode', $matches);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user