1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Anax\Request; |
4
|
|
|
|
5
|
|
|
/** |
6
|
|
|
* Storing information from the request and calculating related essentials. |
7
|
|
|
* |
8
|
|
|
*/ |
9
|
|
|
class Request |
10
|
|
|
{ |
11
|
|
|
/** |
12
|
|
|
* Properties |
13
|
|
|
* |
14
|
|
|
*/ |
15
|
|
|
private $requestUri; // Request URI from $_SERVER |
16
|
|
|
private $scriptName; // Scriptname from $_SERVER, actual scriptname part |
17
|
|
|
private $path; // Scriptname from $_SERVER, path-part |
18
|
|
|
|
19
|
|
|
private $route; // The route |
20
|
|
|
private $routeParts; // The route as an array |
21
|
|
|
|
22
|
|
|
|
23
|
|
|
private $currentUrl; // Current url |
24
|
|
|
private $siteUrl; // Url to this site, http://dbwebb.se |
25
|
|
|
private $baseUrl; // Url to root dir, siteUrl . /some/installation/directory/ |
26
|
|
|
|
27
|
|
|
private $server; // Mapped to $_SERVER |
28
|
|
|
private $get; // Mapped to $_GET |
29
|
|
|
private $post; // Mapped to $_POST |
30
|
|
|
|
31
|
|
|
|
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* Constructor. |
35
|
|
|
* |
36
|
|
|
* |
37
|
|
|
*/ |
38
|
19 |
|
public function __construct() |
39
|
|
|
{ |
40
|
19 |
|
$this->setGlobals(); |
41
|
19 |
|
} |
42
|
|
|
|
43
|
|
|
|
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* Read info from the globals. |
47
|
|
|
* |
48
|
|
|
* @param array $globals use to initiate globals with values. |
49
|
|
|
* |
50
|
|
|
* @return void |
51
|
|
|
*/ |
52
|
19 |
|
public function setGlobals($globals = []) |
53
|
|
|
{ |
54
|
19 |
|
$this->server = isset($globals['server']) ? array_merge($_SERVER, $globals['server']) : $_SERVER; |
55
|
19 |
|
$this->get = isset($globals['get']) ? array_merge($_GET, $globals['get']) : $_GET; |
56
|
19 |
|
$this->post = isset($globals['post']) ? array_merge($_POST, $globals['post']) : $_POST; |
57
|
19 |
|
} |
58
|
|
|
|
59
|
|
|
|
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* Init the request class by reading information from the request. |
63
|
|
|
* |
64
|
|
|
* @return $this |
65
|
|
|
*/ |
66
|
4 |
|
public function init() |
67
|
|
|
{ |
68
|
4 |
|
$this->requestUri = $this->getServer('REQUEST_URI'); |
69
|
4 |
|
$scriptName = $this->getServer('SCRIPT_NAME'); |
70
|
4 |
|
$this->path = rtrim(dirname($scriptName), '/'); |
71
|
4 |
|
$this->scriptName = basename($scriptName); |
72
|
|
|
|
73
|
|
|
// The route and its parts |
74
|
4 |
|
$this->extractRoute(); |
75
|
|
|
|
76
|
|
|
// Prepare to create siteUrl and baseUrl by using currentUrl |
77
|
4 |
|
$this->currentUrl = $this->getCurrentUrl(); |
78
|
4 |
|
$parts = parse_url($this->currentUrl); |
79
|
4 |
|
$this->siteUrl = "{$parts['scheme']}://{$parts['host']}" |
80
|
4 |
|
. (isset($parts['port']) |
81
|
4 |
|
? ":{$parts['port']}" |
82
|
4 |
|
: ''); |
83
|
4 |
|
$this->baseUrl = $this->siteUrl . $this->path; |
84
|
|
|
|
85
|
4 |
|
return $this; |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
|
89
|
|
|
|
90
|
|
|
/** |
91
|
|
|
* Get site url. |
92
|
|
|
* |
93
|
|
|
* @return string |
94
|
|
|
*/ |
95
|
4 |
|
public function getSiteUrl() |
96
|
|
|
{ |
97
|
4 |
|
return $this->siteUrl; |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
|
101
|
|
|
|
102
|
|
|
/** |
103
|
|
|
* Get base url. |
104
|
|
|
* |
105
|
|
|
* @return string |
106
|
|
|
*/ |
107
|
4 |
|
public function getBaseUrl() |
108
|
|
|
{ |
109
|
4 |
|
return $this->baseUrl; |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
|
113
|
|
|
|
114
|
|
|
/** |
115
|
|
|
* Get script name. |
116
|
|
|
* |
117
|
|
|
* @return string |
118
|
|
|
*/ |
119
|
|
|
public function getScriptName() |
120
|
|
|
{ |
121
|
|
|
return $this->scriptName; |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
|
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* Get route parts. |
128
|
|
|
* |
129
|
|
|
* @return array |
130
|
|
|
*/ |
131
|
|
|
public function getRouteParts() |
132
|
|
|
{ |
133
|
|
|
return $this->routeParts; |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
|
137
|
|
|
|
138
|
|
|
/** |
139
|
|
|
* Get the route. |
140
|
|
|
* |
141
|
|
|
* @return string as the current extracted route |
142
|
|
|
*/ |
143
|
6 |
|
public function getRoute() |
144
|
|
|
{ |
145
|
6 |
|
return $this->route; |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
|
149
|
|
|
|
150
|
|
|
/** |
151
|
|
|
* Get the request method. |
152
|
|
|
* |
153
|
|
|
* @return string as the request method |
154
|
|
|
*/ |
155
|
5 |
|
public function getMethod() |
156
|
|
|
{ |
157
|
5 |
|
return $this->getServer("REQUEST_METHOD"); |
158
|
|
|
} |
159
|
|
|
|
160
|
|
|
|
161
|
|
|
|
162
|
|
|
/** |
163
|
|
|
* Extract the part containing the route. |
164
|
|
|
* |
165
|
|
|
* @return string as the current extracted route |
166
|
|
|
*/ |
167
|
10 |
|
public function extractRoute() |
168
|
|
|
{ |
169
|
10 |
|
$requestUri = $this->getServer('REQUEST_URI'); |
170
|
10 |
|
$scriptName = $this->getServer('SCRIPT_NAME'); |
171
|
10 |
|
$scriptPath = dirname($scriptName); |
172
|
10 |
|
$scriptFile = basename($scriptName); |
173
|
|
|
|
174
|
|
|
// Compare REQUEST_URI and SCRIPT_NAME as long they match, |
175
|
|
|
// leave the rest as current request. |
176
|
10 |
|
$i = 0; |
177
|
10 |
|
$len = min(strlen($requestUri), strlen($scriptPath)); |
178
|
|
|
while ($i < $len |
179
|
10 |
|
&& $requestUri[$i] == $scriptPath[$i] |
180
|
10 |
|
) { |
181
|
10 |
|
$i++; |
182
|
10 |
|
} |
183
|
10 |
|
$route = trim(substr($requestUri, $i), '/'); |
184
|
|
|
|
185
|
|
|
// Does the request start with script-name - remove it. |
186
|
10 |
|
$len1 = strlen($route); |
187
|
10 |
|
$len2 = strlen($scriptFile); |
188
|
|
|
|
189
|
|
|
if ($len2 <= $len1 |
190
|
10 |
|
&& substr_compare($scriptFile, $route, 0, $len2, true) === 0 |
191
|
10 |
|
) { |
192
|
10 |
|
$route = substr($route, $len2 + 1); |
193
|
10 |
|
} |
194
|
|
|
|
195
|
|
|
// Remove the ?-part from the query when analysing controller/metod/arg1/arg2 |
196
|
10 |
|
$queryPos = strpos($route, '?'); |
197
|
10 |
|
if ($queryPos !== false) { |
198
|
|
|
$route = substr($route, 0, $queryPos); |
199
|
|
|
} |
200
|
|
|
|
201
|
10 |
|
$route = ($route === false) ? '' : $route; |
202
|
|
|
|
203
|
10 |
|
$this->route = $route; |
204
|
10 |
|
$this->routeParts = explode('/', trim($route, '/')); |
205
|
|
|
|
206
|
10 |
|
return $this->route; |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
|
210
|
|
|
|
211
|
|
|
/** |
212
|
|
|
* Get the current url. |
213
|
|
|
* |
214
|
|
|
* @param boolean $queryString attach query string, default is true. |
215
|
|
|
* |
216
|
|
|
* @return string as current url. |
217
|
|
|
*/ |
218
|
11 |
|
public function getCurrentUrl($queryString = true) |
219
|
|
|
{ |
220
|
11 |
|
$scheme = $this->getServer('REQUEST_SCHEME'); |
221
|
11 |
|
$https = $this->getServer('HTTPS') == 'on' ? true : false; |
222
|
11 |
|
$server = $this->getServer('SERVER_NAME'); |
223
|
11 |
|
$port = $this->getServer('SERVER_PORT'); |
224
|
|
|
|
225
|
11 |
|
$port = ($port == '80') |
226
|
11 |
|
? '' |
227
|
11 |
|
: (($port == 443 && $https) |
228
|
6 |
|
? '' |
229
|
11 |
|
: ':' . $port); |
230
|
|
|
|
231
|
|
|
$uri = $queryString |
232
|
11 |
|
? rtrim($this->getServer('REQUEST_URI'), '/') |
233
|
11 |
|
: rtrim(strtok($this->getServer('REQUEST_URI'), '?'), '/'); |
234
|
|
|
|
235
|
11 |
|
$url = $scheme ? $scheme : 'http'; |
236
|
11 |
|
$url .= '://'; |
237
|
11 |
|
$url .= $server . $port . htmlspecialchars($uri); |
238
|
|
|
|
239
|
11 |
|
return $url; |
240
|
|
|
} |
241
|
|
|
|
242
|
|
|
|
243
|
|
|
|
244
|
|
|
/** |
245
|
|
|
* Get a value from the _SERVER array and use default if it is not set. |
246
|
|
|
* |
247
|
|
|
* @param string $key to check if it exists in the $_SERVER variable |
248
|
|
|
* @param string $default value to return as default |
249
|
|
|
* |
250
|
|
|
* @return mixed |
251
|
|
|
*/ |
252
|
18 |
|
public function getServer($key, $default = null) |
253
|
|
|
{ |
254
|
18 |
|
return isset($this->server[$key]) ? $this->server[$key] : $default; |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
|
258
|
|
|
|
259
|
|
|
/** |
260
|
|
|
* Set variable in the server array. |
261
|
|
|
* |
262
|
|
|
* @param mixed $key the key an the , or an key-value array |
263
|
|
|
* @param string $value the value of the key |
264
|
|
|
* |
265
|
|
|
* @return $this |
266
|
|
|
*/ |
267
|
18 |
View Code Duplication |
public function setServer($key, $value = null) |
|
|
|
|
268
|
|
|
{ |
269
|
18 |
|
if (is_array($key)) { |
270
|
|
|
$this->server = array_merge($this->server, $key); |
271
|
|
|
} else { |
272
|
18 |
|
$this->server[$key] = $value; |
273
|
|
|
} |
274
|
18 |
|
} |
275
|
|
|
|
276
|
|
|
|
277
|
|
|
|
278
|
|
|
/** |
279
|
|
|
* Get a value from the _GET array and use default if it is not set. |
280
|
|
|
* |
281
|
|
|
* @param string $key to check if it exists in the $_GET variable |
282
|
|
|
* @param string $default value to return as default |
283
|
|
|
* |
284
|
|
|
* @return mixed |
285
|
|
|
*/ |
286
|
1 |
|
public function getGet($key, $default = null) |
287
|
|
|
{ |
288
|
1 |
|
return isset($this->get[$key]) ? $this->get[$key] : $default; |
289
|
|
|
} |
290
|
|
|
|
291
|
|
|
|
292
|
|
|
|
293
|
|
|
/** |
294
|
|
|
* Set variable in the get array. |
295
|
|
|
* |
296
|
|
|
* @param mixed $key the key an the , or an key-value array |
297
|
|
|
* @param string $value the value of the key |
298
|
|
|
* |
299
|
|
|
* @return $this |
300
|
|
|
*/ |
301
|
1 |
View Code Duplication |
public function setGet($key, $value = null) |
|
|
|
|
302
|
|
|
{ |
303
|
1 |
|
if (is_array($key)) { |
304
|
|
|
$this->get = array_merge($this->get, $key); |
305
|
|
|
} else { |
306
|
1 |
|
$this->get[$key] = $value; |
307
|
|
|
} |
308
|
1 |
|
} |
309
|
|
|
|
310
|
|
|
|
311
|
|
|
|
312
|
|
|
/** |
313
|
|
|
* Get a value from the _POST array and use default if it is not set. |
314
|
|
|
* |
315
|
|
|
* @param string $key to check if it exists in the $_POST variable |
316
|
|
|
* @param string $default value to return as default |
317
|
|
|
* |
318
|
|
|
* @return mixed |
319
|
|
|
*/ |
320
|
|
|
public function getPost($key = null, $default = null) |
321
|
|
|
{ |
322
|
|
|
if ($key) { |
|
|
|
|
323
|
|
|
return isset($this->post[$key]) ? $this->post[$key] : $default; |
324
|
|
|
} |
325
|
|
|
|
326
|
|
|
return $this->post; |
327
|
|
|
} |
328
|
|
|
} |
329
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.