Skip to content

Instantly share code, notes, and snippets.

@flashwave
Created August 3, 2019 02:33
Show Gist options
  • Save flashwave/98b52e7fabc6acae2731d863349facd9 to your computer and use it in GitHub Desktop.
Save flashwave/98b52e7fabc6acae2731d863349facd9 to your computer and use it in GitHub Desktop.
shitty router which i wrote for a project but then i realised i didn't need to do router bullshit
<?php
namespace Index\Router;
class Route {
public const METHODS = ['GET', 'POST'];
private $methods = [];
private $path = '';
private $handler;
private $pathIsRegex = false;
public function __construct(array $methods, string $path, callable $handler) {
$this->methods = $methods;
$this->path = '#^' . $path . '$#';
$this->handler = $handler;
}
public static function __callStatic(string $name, array $args) {
if($name === 'new') { // Route::new looks neater than new Route with the other aliases
return new static(...$args);
}
$upperName = strtoupper($name);
if(in_array($upperName, self::METHODS)) {
return new static([$upperName], ...$args);
}
}
public function hasMethod(string $method): bool {
return in_array($method, $this->methods);
}
public function matchPath(string $path, &$matches = []): bool {
return preg_match($this->path, $path, $matches);
}
public function invoke(...$args): void {
call_user_func($this->handler, ...$args);
}
}
<?php
namespace Index\Router;
class Router {
private $routes = [];
private $errors = [];
public function __construct(Route ...$routes) {
$this->register(...$routes);
}
public function setError(int $code, callable $handler): void {
$this->errors[$code] = $handler;
}
public function error(int $code): void {
http_response_code($code);
if(array_key_exists($code, $this->errors)) {
call_user_func($this->errors[$code]);
return;
}
echo $code;
}
public function resolve(string $method, string $path): ?RouteResolve {
foreach($this->routes as $route) {
if(!$route->hasMethod($method) || !$route->matchPath($path, $matches))
continue;
return new RouteResolve($route, array_slice($matches, 1));
}
return null;
}
public function execute(string $method, string $path): void {
$resolve = $this->resolve($method, $path);
if($resolve === null) {
$this->error(404);
return;
}
$resolve->getRoute()->invoke(...$resolve->getArguments());
}
public function register(Route ...$routes): void {
$this->routes = array_merge($this->routes, $routes);
}
}
<?php
namespace Index\Router;
class RouteResolve {
private $route;
private $args;
public function __construct(Route $route, array $args) {
$this->route = $route;
$this->args = $args ?? [];
}
public function getRoute(): Route {
return $this->route;
}
public function getArguments(): array {
return $this->args;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment