Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 6a915cf

Browse files
Improve routing using regular expressions
1 parent d83254a commit 6a915cf

File tree

8 files changed

+103
-129
lines changed

8 files changed

+103
-129
lines changed

‎config/utilities.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
<?php
22
/**
33
* Get URI path.
4-
* Return a string.
4+
* Returns a string.
55
*/
6-
function getUri()
6+
function getUri() : string
77
{
88
$uri = trim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), '/');
99
$uri = explode('/', $uri);
10+
array_shift($uri);
11+
$uri = implode('/', $uri);
1012

1113
return $uri;
1214
}
13-
/** Get request method.
14-
* Return a string.
15+
/**
16+
* Get request method.
17+
* Returns a string.
1518
*/
1619
function getMethod()
1720
{

‎public/index.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
<?php
22
require_once dirname(__DIR__) . '/vendor/autoload.php';
33

4-
Router::load(APPROOT . '/src/app/routes.php')->direct(getUri(), getMethod());
4+
App\Router::load(APPROOT . '/src/app/routes.php')->redirectTo();

‎src/app/Router.php

Lines changed: 75 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
<?php
2+
namespace App;
3+
24
/**
35
* Router Class
46
* Set initial routes
57
* Take URI and call desired method
68
*/
79
class Router
810
{
9-
private $routes = [
10-
'GET' => [],
11-
'POST' => []
12-
];
11+
private $routes = [];
12+
private $params = [];
1313

1414
/**
15-
* Load routes.php file
15+
* Method used to load routes.php file
1616
* @param string $file Path to file
17-
* @return object Instance of router in order to use the other methods
17+
* @return Router Instance of router in order to use the other methods
1818
*/
19-
public static function load(string $file)
19+
public static function load(string $file) : Router
2020
{
2121
$router = new static;
2222

@@ -26,65 +26,94 @@ public static function load(string $file)
2626
}
2727

2828
/**
29-
* Register a GET route
30-
* @param string $uri Full route like 'task/add-task'
31-
* @param string $controller Controller and action, e.g: Task@add-task
29+
* Register a route
30+
* Process to convert the route (string) to a regular expression in order to have a more flexible router
31+
* @param string $route Route string, either full route or regular expression
32+
* @param array $params This array stores 'controller' and 'action of each route (if passed)
3233
* @return void
3334
*/
34-
public function get(string $uri, string$controller) : void
35+
public function addRoute(string $route, array$params = []) : void
3536
{
36-
$this->routes['GET'][$uri] = $controller;
37+
// Escape forward slashes
38+
$route = preg_replace('/\//', '\\/', $route);
39+
40+
// Convert variables e.g. {controller}
41+
$route = preg_replace('/\{([a-z]+)\}/', '(?P<1円>[a-z-]+)', $route);
42+
43+
// Convert variables with custom regular expressions e.g. {id:\d+} for numbers
44+
$route = preg_replace('/\{([a-z]+):([^\}]+)\}/', '(?P<1円>2円)', $route);
45+
46+
// Add start and end delimeter
47+
$route = '/^' . $route . '$/i';
48+
49+
$this->routes[$route] = $params;
3750
}
3851

3952
/**
40-
* Register a POST route
53+
* This is where you set the controller and action taken from the URI (like 'posts/add')
54+
* ... and save those into $this->params
55+
* This method is called in routes.php
4156
* @param string $uri Full route like 'task/add-task'
42-
* @param string $controller Controller and action, e.g: Task@add-task
4357
* @return void
4458
*/
45-
public function post($uri, $controller) : void
59+
public function setParams(string$uri) : void
4660
{
47-
$this->routes['POST'][$uri] = $controller;
61+
// Store parameters for current 'controller' and 'action'
62+
foreach ($this->routes as $route => $params)
63+
{
64+
if (preg_match($route, $uri, $matches))
65+
{
66+
67+
foreach ($matches as $key => $match)
68+
{
69+
if (is_string($key))
70+
{
71+
if ($key === 'controller')
72+
{
73+
$match = ucwords($match);
74+
}
75+
76+
$params[$key] = $match;
77+
}
78+
}
79+
80+
$this->params = $params;
81+
}
82+
}
4883
}
4984

5085
/**
51-
* Load requested URI's associated controller method
52-
* @param string $uri Full route like 'task/add-task'
53-
* @param string $method GET or POST
54-
* @return void
86+
* Call requested controller->action()
87+
* At this point $this->params is = ['controller' => 'MyController', 'action' => 'desiredMethod', 'id' => 1]
88+
* So first check if such 'controller' exists and 'action' is a callable method
89+
* If so, then unset 'controller' and 'action', which leaves $this->params = ['id' => 1]
90+
* And last, the desired function is called with all the parameters (array) like 'id'...
91+
* ... and this can be used or not if the method doesn't receive any arguments
5592
*/
56-
public function direct($uri, $method)
93+
public function redirectTo() : void
5794
{
58-
// Remove first part of URI which is 'php-basic-mvc'
59-
// Then, the string for the desired controller will be at 0 index
60-
array_shift($uri);
61-
62-
if (empty($uri))
95+
$controller = '\\Controllers\\' . $this->params['controller'];
96+
$action = $this->params['action'];
97+
98+
if (class_exists($controller))
6399
{
64-
return$this->callAction('Index', 'get');
65-
}
100+
$controller = new$controller;
101+
unset($this->params['controller']);
66102

67-
if (array_key_exists($uri[0], $this->routes[$method]))
68-
{
69-
return $this->callAction(
70-
...explode('@', $this->routes[$method][$uri[0]])
71-
);
72-
}
103+
if (is_callable([$controller, $action]))
104+
{
105+
unset($this->params['action']);
106+
}
107+
else
108+
{
109+
die('Page not found.');
110+
}
111+
}
73112
else
74113
{
75-
return $this->callAction(
76-
...explode('@', $this->routes[$method]['404'])
77-
);
114+
header('location: ' . URLROOT);
78115
}
79-
80-
throw new Exception('No route defined for this URI.');
81-
}
82-
83-
private function callAction($controller, $action)
84-
{
85-
$controller = "Controllers\\{$controller}";
86-
$controller = new $controller;
87116

88-
return$controller->$action();
117+
call_user_func_array([$controller, $action], [$this->params]);
89118
}
90119
}

‎src/app/routes.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?php
22

3-
$router->get('', 'Index@get');
4-
$router->post('add-task', 'Task@add');
5-
$router->get('add-task', 'Task@get');
6-
$router->post('delete-task', 'Task@delete');
7-
$router->post('mark-task', 'Task@markTask');
8-
$router->get('404', 'Index@error404');
3+
$router->addRoute('', ['controller' => 'Index', 'action' => 'home']);
4+
$router->addRoute('about', ['controller' => 'Index', 'action' => 'about']);
5+
$router->addRoute('{controller}/{action}');
6+
$router->addRoute('{controller}/{action}/{id:\d+}');
7+
$router->addRoute('{controller}/{id:\d+}/{action}');
8+
$router->setParams(getUri());

‎src/controllers/Controller.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<?php
22
namespace Controllers;
3+
34
/**
45
* Base Controller
5-
* Loads the models and views
6+
* Loads models and views
67
*/
7-
8-
class Controller
8+
abstract class Controller
99
{
1010
/**
1111
* Instantiate a model

‎src/controllers/Index.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,18 @@
33

44
class Index extends Controller
55
{
6-
public function get()
6+
public function home()
77
{
8-
echo "Homepage";
8+
echo "<h1> Homepage </h1>";
9+
}
10+
11+
public function about()
12+
{
13+
echo "<h1> About </h1>";
914
}
1015

1116
public function error404()
1217
{
13-
echo "Not found.";
18+
echo "<h1> Not found </h1>";
1419
}
1520
}

‎src/controllers/Task.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33

44
class Task
55
{
6-
public function get()
6+
public function get($data)
77
{
8-
echo"Task->get";
8+
var_dump($data);
99
}
1010

1111
public function add()
1212
{
13-
echo "Task->add";
13+
echo "Task->add <br>";
1414
}
1515
}

‎src/libraries/Core.php

Lines changed: 0 additions & 63 deletions
This file was deleted.

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /