Skip to content

Instantly share code, notes, and snippets.

@sebastiaanfranken
Created August 26, 2017 21:32
Show Gist options
  • Save sebastiaanfranken/9f6fe0e057def3ef76ec464320464ec8 to your computer and use it in GitHub Desktop.
Save sebastiaanfranken/9f6fe0e057def3ef76ec464320464ec8 to your computer and use it in GitHub Desktop.
Simple PHP router
<?php
namespace SebastiaanFranken;
use Exception;
class Router
{
/**
* @var array $routes The routing table
*/
protected $routes = [];
/**
* @var array $acceptedRequestMethods Accepted HTTP request methods
*/
protected $acceptedRequestMethods = ['OPTIONS', 'GET', 'HEAD', 'POST', 'PUT'];
/**
* Creates a new Router instance
*
* @return void
*/
public function __construct()
{
/*
* Add a GET and POST array
*/
$this->routes['GET'] = [];
$this->routes['POST'] = [];
}
/**
* Adds a route into the Routing table
*
* @param string $method The HTTP method. Can be 'POST' or 'GET'
* @param string $route The route to respond to
* @param callable $callback The callback to invoke
* @return SebastiaanFranken\Router
*/
protected function setRoute(string $method, string $route, callable $callback) : Router
{
$this->routes[$method][$route] = $callback;
return $this;
}
/**
* Add a HTTP GET route into the Routing table
*
* @param string $route The route to respond to
* @param callable $callback The callback to invoke
* @return SebastiaanFranken\Router
*/
public function get(string $route, callable $callback) : Router
{
return $this->setRoute('GET', $route, $callback);
}
/**
* Add a HTTP POST route into the Routing table
*
* @param string $route The route to respond to
* @param callable $callback The callback to invoke
* @return SebastiaanFranken\Router
*/
public function post(string $route, callable $callback) : Router
{
return $this->setRoute('POST', $route, $callback);
}
/**
* Parses the current HTTP method + URI and sees if
* there's a matching route. If there is, it'll execute.
*
* If not, it throws an error
*
* @return void
*/
public function parseRequest()
{
$requestMethod = $_SERVER['REQUEST_METHOD'];
$queryString = (strlen($_SERVER['QUERY_STRING']) > 0) ? $_SERVER['QUERY_STRING'] : '/';
if(array_key_exists($requestMethod, $this->routes))
{
$table = $this->routes[$requestMethod];
if(array_key_exists($queryString, $table) && is_callable($table[$queryString]))
{
return call_user_func($table[$queryString]);
}
else
{
throw new Exception(sprintf('There is no callback for %s in the %s routing table', $queryString, $requestMethod));
}
}
else
{
throw new Exception(sprintf('There is no %s table in the routing table.', $requestMethod));
}
}
/**
* Add a HTTP request method
*
* @param string $method The HTTP request method to add
* @return SebastiaanFranken\Router
*/
public function addMethod(string $method) : Router
{
$method = strtoupper($method);
if(in_array($method, $this->acceptedRequestMethods) === true)
{
$this->routes[$method] = [];
}
else
{
throw new Exception(sprintf('The HTTP method %s is not in the accepted request methods list.', $method));
}
return $this;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment