Skip to content

Commit 8c84ca2

Browse files
committed
initial commit
0 parents  commit 8c84ca2

File tree

6 files changed

+210
-0
lines changed

6 files changed

+210
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
vendor
2+
composer.lock

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# PHP Router
2+
3+
This composer library allows simple, quick routing configuration.
4+
5+
```php
6+
<?php
7+
use GuahanWeb\Http;
8+
9+
$router = Http\Router::instance();
10+
11+
$router->get('/', function ($req, $res) {
12+
$res->send('Hello, world!');
13+
});
14+
15+
$router->process();
16+
```

composer.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "guahanweb/php-router",
3+
"description": "A lightweight router for PHP projects",
4+
"type": "library",
5+
"license": "MIT",
6+
"authors": [
7+
{
8+
"name": "Garth Henson",
9+
"email": "[email protected]",
10+
"homepage": "http://www.guahanweb.com",
11+
"role": "Lead Developer"
12+
}
13+
],
14+
"minimum-stability": "dev",
15+
"require": {
16+
"php": ">=5.2.7"
17+
},
18+
"autoload": {
19+
"psr-0": {
20+
"GuahanWeb\\Http": "src/"
21+
}
22+
}
23+
}

src/GuahanWeb/Http/request.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
namespace GuahanWeb\Http;
3+
4+
class Request {
5+
protected $method;
6+
protected $uri;
7+
protected $query;
8+
protected $headers;
9+
10+
protected $params;
11+
12+
public function __construct() {
13+
$this->method = $_SERVER['REQUEST_METHOD'];
14+
if (stripos($this->method, 'HEAD')) {
15+
// HEAD requests must immediately return with no body
16+
exit;
17+
}
18+
19+
$this->uri = $_SERVER['REQUEST_URI'];
20+
$this->query = empty($_SERVER['QUERY_STRING']) ? array() : parse_str($_SERVER['QUERY_STRING']);
21+
$this->headers = $this->getAllHeaders();
22+
23+
$this->params = array();
24+
}
25+
26+
public function __get($k) {
27+
switch ($k) {
28+
case 'method':
29+
case 'headers':
30+
case 'query':
31+
case 'uri':
32+
return $this->$k;
33+
break;
34+
35+
default:
36+
return isset($this->params[$k]) ? $this->params[$k] : null;
37+
}
38+
}
39+
40+
// we only can write the params directly
41+
public function __set($k, $v) {
42+
$this->params[$k] = $v;
43+
}
44+
45+
protected function getAllHeaders() {
46+
$headers = array();
47+
foreach ($_SERVER as $name => $value) {
48+
if (substr($name, 0, 5) == 'HTTP_') {
49+
$headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
50+
}
51+
}
52+
return $headers;
53+
}
54+
}
55+

src/GuahanWeb/Http/response.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
namespace GuahanWeb\Http;
3+
4+
class Response {
5+
protected $headers;
6+
7+
public function __construct() {
8+
$this->headers = array();
9+
}
10+
11+
public function setHeader($k, $v) {
12+
$this->headers[$k] = $v;
13+
}
14+
15+
public function setHeaders($headers) {
16+
foreach ($headers as $k => $v) {
17+
$this->setHeader($k, $v);
18+
}
19+
}
20+
21+
public function send($body, $code = 200) {
22+
foreach ($this->headers as $k => $v) {
23+
header($k . ': ' . $v);
24+
}
25+
26+
http_response_code($code);
27+
echo $body;
28+
exit;
29+
}
30+
}
31+

src/GuahanWeb/Http/router.php

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php
2+
namespace GuahanWeb\Http;
3+
4+
class Router {
5+
protected $routes;
6+
7+
protected function __construct() {
8+
$this->routes = array(
9+
'GET' => array(),
10+
'POST' => array(),
11+
'PUT' => array(),
12+
'DELETE' => array()
13+
);
14+
}
15+
16+
static public function instance() {
17+
static $instance;
18+
19+
if (is_null($instance)) {
20+
$instance = new Router();
21+
}
22+
23+
return $instance;
24+
}
25+
26+
protected function match($method, $uri, &$params = null) {
27+
if (isset($this->routes[$method])) {
28+
foreach ($this->routes[$method] as $route => $handler) {
29+
if ($uri == $route) {
30+
// exact match
31+
return $handler;
32+
} elseif (false !== preg_match_all('/\{([^}]+)\}/', $route, $match, PREG_PATTERN_ORDER)) {
33+
$args = $match[1];
34+
if (count($args) > 0) {
35+
$keys = array();
36+
$replacements = array();
37+
38+
foreach ($args as $k => $arg) {
39+
$keys[] = rtrim($arg, '*');
40+
$replacements[] = (substr($arg, -1) == '*') ? '(.+?)' : '([^/]+)';
41+
}
42+
43+
$matcher = '/^' . str_replace('/', '\/', str_replace($match[0], $replacements, $route)) . '$/';
44+
if (preg_match($matcher, $uri, $placeholders)) {
45+
// update params and return
46+
array_shift($placeholders);
47+
$params = array();
48+
foreach ($keys as $k => $arg) {
49+
$params[$arg] = $placeholders[$k];
50+
}
51+
52+
return $handler;
53+
}
54+
}
55+
}
56+
}
57+
}
58+
return false;
59+
}
60+
61+
public function get($route, $handler) {
62+
$this->routes['GET'][$route] = $handler;
63+
}
64+
65+
public function process() {
66+
$request = new Request();
67+
$response = new Response();
68+
69+
if (false === ($handler = $this->match($request->method, $request->uri, $params))) {
70+
// Error case
71+
$response->send('Not found', 404);
72+
}
73+
74+
// route params applied to the request object
75+
if (null !== $params) {
76+
foreach ($params as $k => $v) {
77+
$request->$k = $v;
78+
}
79+
}
80+
81+
$handler($request, $response);
82+
}
83+
}

0 commit comments

Comments
 (0)