aboutsummaryrefslogtreecommitdiffstats
path: root/src/app/Router.php
diff options
context:
space:
mode:
authorThomas Vanbesien <tvanbesi@proton.me>2026-03-21 20:50:43 +0100
committerThomas Vanbesien <tvanbesi@proton.me>2026-03-21 20:50:43 +0100
commitd1ef15fa39935bfa0420c5ac2b8c269e294c9a6d (patch)
tree618158449863123f6b9527b9db6183f8c3ce5c91 /src/app/Router.php
downloadcamagru-d1ef15fa39935bfa0420c5ac2b8c269e294c9a6d.tar.gz
camagru-d1ef15fa39935bfa0420c5ac2b8c269e294c9a6d.zip
Initial project scaffold
Set up MVC architecture with front controller, router, autoloader, database singleton, and Docker Compose stack (Nginx + PHP-FPM + MariaDB). Includes DB schema, responsive layout, dev tooling (php-cs-fixer, parallel-lint), and documentation.
Diffstat (limited to 'src/app/Router.php')
-rw-r--r--src/app/Router.php56
1 files changed, 56 insertions, 0 deletions
diff --git a/src/app/Router.php b/src/app/Router.php
new file mode 100644
index 0000000..9bfe09d
--- /dev/null
+++ b/src/app/Router.php
@@ -0,0 +1,56 @@
+<?php
+
+declare(strict_types=1);
+// Regex-based HTTP router that dispatches requests to controller methods.
+
+namespace App;
+
+class Router
+{
+ private array $routes = [];
+
+ public function get(string $path, string $controller, string $method): void
+ {
+ $this->routes[] = ['GET', $path, $controller, $method];
+ }
+
+ public function post(string $path, string $controller, string $method): void
+ {
+ $this->routes[] = ['POST', $path, $controller, $method];
+ }
+
+ public function dispatch(): void
+ {
+ $requestMethod = $_SERVER['REQUEST_METHOD'];
+ $uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
+ $uri = rtrim($uri, '/') ?: '/';
+
+ foreach ($this->routes as [$method, $path, $controller, $action]) {
+ if ($method !== $requestMethod) {
+ continue;
+ }
+
+ // Convert route placeholders to named regex capture groups.
+ // Example with route '/post/{id}' and request '/post/42':
+ // 1. preg_replace turns '{id}' into '(?P<id>[^/]+)'
+ // result: '#^/post/(?P<id>[^/]+)$#'
+ // 2. preg_match against '/post/42' produces:
+ // [0 => '/post/42', 'id' => '42', 1 => '42']
+ // 3. array_filter keeps only string keys: ['id' => '42']
+ // 4. PostController->show('42') is called
+ $pattern = preg_replace('#\{(\w+)\}#', '(?P<$1>[^/]+)', $path);
+ $pattern = '#^' . $pattern . '$#';
+
+ if (preg_match($pattern, $uri, $matches)) {
+ $params = array_filter($matches, 'is_string', ARRAY_FILTER_USE_KEY);
+ $controllerClass = "App\\Controllers\\$controller";
+ $instance = new $controllerClass();
+ $instance->$action(...array_values($params));
+ return;
+ }
+ }
+
+ http_response_code(404);
+ echo '404 Not Found';
+ }
+}