-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathRouter.php
More file actions
182 lines (143 loc) · 4.83 KB
/
Router.php
File metadata and controls
182 lines (143 loc) · 4.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
<?php
/**
* A simple url router
*
* This file contains a small url router, which is intended to
* be used in very small projects, where no real MVC framework
* fits the needs of the project.
*
* To create a route, you just have to call the "Router::add"
* function and provide the intended url and the name of the
* function which is supposed to be called if the route matches.
*
* The function name can contain a regular expression. Every
* matching argument, that can be extracted will be stored in
* the $args array.
*
* Every function, that is supposed to be the endpoint of an
* url has to accept a single variable, which will contain the
* array of extracted arguments.
*
* If you want to use class methods as your endpoints, just
* add the class's name in front of the method's name and add
* a dot after the class's name.
*
* For the bar method of this class:
* class Foo {
* function bar($args) {...}
* }
*
* the endpoint has to be "Foo.bar". See example usage in the
* example file (index.php).
*
* The Router has only static methods, because that makes the api
* super nice (at least IMHO).
*
*
* Usage:
*
* ---- snipp ----
*
* require_once('Router.php');
*
* Router::add('/example', 'example_function');
*
* function example_function($args) {
*
* echo "Hello!<br />";
* print_r($args);
*
* }
*
* ---- snipp ----
*
*
* Made 2009 Florian Herlings (florianherlings.de)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Version: 0.1
* Date: 29.01.2009
*/
class Router {
/**
* This static array, holds the defined urls,
* which were added by the static function "add".
*/
protected static $routes = array();
/**
* This static method adds a new route to the router.
* The first argument is expected to be a string containing
* the route (can be declared as a regex) while the second
* string is expected to be the endpoint.
* An endpoint is the string name of a function, which will
* be called if the route matches.
*/
public static function add($route, $endpoint) {
self::$routes[] = array('route' => '@' . $route . '@i', 'endpoint' => $endpoint);
}//add()
/**
* This static method runs the routing process.
* Currently the method will iterate through all the
* routes to find the one matching route. If no route
* matches the current url arguments, the default route
* "/" will be triggered (if it was added to the router).
*/
public static function run() {
$args = self::get_args();
//Sort routes by string length to check the long ones first
//(otherwise a shorter route might already match, while the
//longer route has not yet been checked).
usort(self::$routes, create_function('$a,$b', 'return strlen($a["route"]) < strlen($b["route"]);'));
foreach(self::$routes as $route) {
$route_matches_args = preg_match($route['route'], $args, $regs);
if ($route_matches_args)
{
//The first argument contains the original string that matched.
//This first argument will be removed.
$regs = array_slice($regs, 1);
self::execute_matched_route($route['endpoint'], $regs);
break;
}
}//foreach
}//route()
/**
* This static method executes a given endpoint with the provided
* arguments. If the string containing the endpoint's name contains a
* point (".") the method expects it to be a class's method. If this
* case is detected, the method instantiates the class of the object
* and calls the method on the new object.
*/
protected static function execute_matched_route($endpoint, $arguments) {
if (strpos($endpoint, '.') === false) {
$endpoint($arguments);
} else {
list($class, $function) = explode('.', $endpoint);
$instance = new $class();
$instance->$function($arguments);
}
}//execute_matched_route()
/**
* This method tries to extract the interesting part from the
* request url.
*/
protected static function get_args() {
$prefix_str = str_replace('index.php', '', $_SERVER['SCRIPT_NAME']);
if ($prefix_str !== '/')
$args = '/'.str_replace($prefix_str, '', $_SERVER['REQUEST_URI']);
else
$args = '/'.$_SERVER['REQUEST_URI'];
return $args;
}//get_args()
}//class Router