routes; foreach ($segments as $segment) $node = &$node[$segment]; // Add the handler to the last node $node[$method] = $handler; return $this; } public function lookup(string $method, string $uri): int|array { // Expand the URI into segments $uriSegments = explode('/', trim($uri, '/')); $node = $this->routes; $params = []; // Traverse the routes array to find the handler foreach ($uriSegments as $segment) { // Check if the segment exists in the node, or if there's a dynamic segment if (!isset($node[$segment])) { $dynamicSegment = $this->matchDynamicSegment($node, $segment); if ($dynamicSegment) { $params[] = $segment; $node = $node[$dynamicSegment]; } else { return 404; } } else { $node = $node[$segment]; } } // If the HTTP method is not supported, return 405 if (!isset($node[$method])) return 405; // Return the handler return [$node[$method], $params]; } // Look through a node to find a dynamic segment private function matchDynamicSegment(array $node, string $segment): string|false { foreach (array_keys($node) as $key) { // If the key starts with a :, it's a dynamic segment if (strpos($key, ':') === 0) return $key; } return false; } public function clear(): Router { $this->routes = []; return $this; } }