aboutsummaryrefslogtreecommitdiffhomepage
path: root/WpfTest/Router.php
diff options
context:
space:
mode:
Diffstat (limited to 'WpfTest/Router.php')
-rw-r--r--WpfTest/Router.php98
1 files changed, 0 insertions, 98 deletions
diff --git a/WpfTest/Router.php b/WpfTest/Router.php
deleted file mode 100644
index c975723..0000000
--- a/WpfTest/Router.php
+++ /dev/null
@@ -1,98 +0,0 @@
-<?php
-namespace WpfTest;
-
-use WpfTest\HttpResponseStatus\InternalServerError;
-use WpfTest\HttpResponseStatus\NoHandlerFound;
-
-class Router extends Singleton {
-
- private readonly string $requestPath;
- private array $routes;
-
- protected function __construct() {
- $this->requestPath = $_GET['requestPath'] ?? $_SERVER['PATH_INFO'] ?? explode('?', $_SERVER['REQUEST_URI'], 2)[0] ?? '/';
- $this->routes = [];
- }
-
- /**
- * Processes and sends a response to the current request
- * @return void
- */
- public function processRequest() {
- try {
- $this->processRequestInner();
- } catch (HttpResponseStatus $e) {
- http_response_code($e->httpCode());
- echo '<h1>' . $e->httpReason() . '</h1><pre>' . $e->getMessage() . '</pre>';
- }
- }
-
- private function processRequestInner() {
- $context = null;
- try {
- $route = $this->matchPath($this->requestPath);
- if ($route == null) {
- throw new NoHandlerFound($this->requestPath);
- }
- $context = 'handler for /' . implode('/', $route[0]);
- $route[1]($route[2]); // call handler with args
- } catch (\Exception $e) {
- if (is_a($e, HttpResponseStatus::class)) {
- throw $e;
- }
- throw new InternalServerError($e, $context);
- } catch (\Error $e) {
- throw new InternalServerError($e, $context);
- }
- }
-
- public function mount(string $pathSpec, callable $handler) {
- $this->routes[] = [$this->explodePathPieces($pathSpec), $handler];
- }
-
- private function explodePathPieces(string $pathSpec): array {
- $pieces = explode('/', $pathSpec);
- if ($pieces[0] == '')
- array_shift($pieces);
- return $pieces;
- }
-
- private function matchPath(string $requestPath): ?array {
- // find matching candidates
- $pieces = $this->explodePathPieces($requestPath);
- $candidates = [];
- foreach ($this->routes as $route) {
- $routePieces = $route[0];
- if (count($routePieces) != count($pieces))
- continue;
- $args = [];
- $matches = true;
- for ($i = 0; $i < count($pieces); $i++) {
- if (str_starts_with($routePieces[$i], ':')) { // this is a parameter
- $args[substr($routePieces[$i], 1)] = $pieces[$i];
- } elseif ($routePieces[$i] != $pieces[$i]) {
- $matches = false;
- break;
- }
- }
- if ($matches) {
- $candidates[] = [$route[0], $route[1], $args];
- }
- }
-
- // select the best matching one (has the longest path, for now)
- $bestScore = 0;
- $bestItem = null;
- foreach ($candidates as $c) {
- $score = count($c[0]) - count(array_filter($c[0], function ($item) {
- return str_starts_with($item, ':');
- })) * 0.1;
- if ($score > $bestScore) {
- $bestItem = $c;
- $bestScore = $score;
- }
- }
- return $bestItem;
- }
-
-}