This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * Scabbia2 LightStack Component |
||
4 | * https://github.com/eserozvataf/scabbia2 |
||
5 | * |
||
6 | * For the full copyright and license information, please view the LICENSE |
||
7 | * file that was distributed with this source code. |
||
8 | * |
||
9 | * @link https://github.com/eserozvataf/scabbia2-lightstack for the canonical source repository |
||
10 | * @copyright 2010-2016 Eser Ozvataf. (http://eser.ozvataf.com/) |
||
11 | * @license http://www.apache.org/licenses/LICENSE-2.0 - Apache License, Version 2.0 |
||
12 | */ |
||
13 | |||
14 | namespace Scabbia\LightStack; |
||
15 | |||
16 | use Scabbia\LightStack\RequestInterface; |
||
17 | |||
18 | /** |
||
19 | * Request implementation |
||
20 | * |
||
21 | * @package Scabbia\LightStack |
||
22 | * @author Eser Ozvataf <[email protected]> |
||
23 | * @since 2.0.0 |
||
24 | */ |
||
25 | class Request implements RequestInterface |
||
26 | { |
||
27 | /** @type string $method request method */ |
||
28 | protected $method; |
||
29 | /** @type string $pathinfo request path info */ |
||
30 | protected $pathinfo; |
||
31 | /** @type array $details request details */ |
||
32 | protected $details; |
||
33 | |||
34 | |||
35 | /** |
||
36 | * Generates a request object from globals |
||
37 | * |
||
38 | * @return RequestInterface request object |
||
39 | * |
||
40 | * @todo fixme: start session if necessary |
||
41 | */ |
||
42 | public static function generateFromGlobals() |
||
0 ignored issues
–
show
generateFromGlobals uses the super-global variable $_POST which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
![]() generateFromGlobals uses the super-global variable $_GET which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
![]() generateFromGlobals uses the super-global variable $_FILES which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
![]() generateFromGlobals uses the super-global variable $_SESSION which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
![]() generateFromGlobals uses the super-global variable $_COOKIE which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
![]() |
|||
43 | { |
||
44 | // request method |
||
45 | if (isset($_SERVER["X-HTTP-METHOD-OVERRIDE"])) { |
||
46 | $tMethod = strtoupper($_SERVER["X-HTTP-METHOD-OVERRIDE"]); |
||
47 | } elseif (isset($_POST["_method"])) { |
||
48 | $tMethod = strtoupper($_POST["_method"]); |
||
49 | } elseif (isset($_SERVER["REQUEST_METHOD"])) { |
||
50 | $tMethod = strtoupper($_SERVER["REQUEST_METHOD"]); |
||
51 | } else { |
||
52 | $tMethod = "GET"; |
||
53 | } |
||
54 | |||
55 | // request uri |
||
56 | if (isset($_SERVER["REQUEST_URI"])) { |
||
57 | if (strncmp( |
||
58 | $_SERVER["REQUEST_URI"], |
||
59 | $_SERVER["HTTP_HOST"], |
||
60 | $tHostLength = strlen($_SERVER["HTTP_HOST"]) |
||
61 | ) === 0) { |
||
62 | $tRequestUri = substr($_SERVER["REQUEST_URI"], $tHostLength); |
||
63 | } else { |
||
64 | $tRequestUri = $_SERVER["REQUEST_URI"]; |
||
65 | } |
||
66 | } elseif (isset($_SERVER["ORIG_PATH_INFO"])) { |
||
67 | $tRequestUri = $_SERVER["ORIG_PATH_INFO"]; |
||
68 | |||
69 | if (isset($_SERVER["QUERY_STRING"]) && strlen($_SERVER["QUERY_STRING"]) > 0) { |
||
70 | $tRequestUri .= "?" . $_SERVER["QUERY_STRING"]; |
||
71 | } |
||
72 | } else { |
||
73 | $tRequestUri = ""; |
||
74 | } |
||
75 | |||
76 | // request pathroot |
||
77 | $tPathRoot = trim(str_replace("\\", "/", pathinfo($_SERVER["SCRIPT_NAME"], PATHINFO_DIRNAME)), "/"); |
||
78 | if (strlen($tPathRoot) > 0) { |
||
79 | $tPathRoot = "/{$tPathRoot}"; |
||
80 | } |
||
81 | |||
82 | // request pathinfo |
||
83 | if (($tPos = strpos($tRequestUri, "?")) !== false) { |
||
84 | $tBaseUriPath = substr($tRequestUri, 0, $tPos); |
||
85 | } else { |
||
86 | $tBaseUriPath = $tRequestUri; |
||
87 | } |
||
88 | |||
89 | $tPathInfo = substr($tBaseUriPath, strlen($tPathRoot)); |
||
90 | |||
91 | // generate request |
||
92 | return new static( |
||
93 | $tMethod, |
||
94 | $tPathInfo, |
||
95 | [ |
||
96 | "get" => $_GET, |
||
97 | "post" => $_POST, |
||
98 | "files" => $_FILES, |
||
99 | "server" => $_SERVER, |
||
100 | "session" => isset($_SESSION) ? $_SESSION : null, |
||
101 | "cookies" => $_COOKIE, |
||
102 | "headers" => function_exists('getallheaders') ? getallheaders() : null |
||
103 | ] |
||
104 | ); |
||
105 | } |
||
106 | |||
107 | /** |
||
108 | * Initializes a request |
||
109 | * |
||
110 | * @param string $uMethod method |
||
111 | * @param string $uPathInfo pathinfo |
||
112 | * @param array|null $uDetails available keys: get, post, files, server, session, cookies, headers |
||
113 | * |
||
114 | * @return Request request object |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Adding a
@return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.
Adding a Please refer to the PHP core documentation on constructors. ![]() |
|||
115 | */ |
||
116 | public function __construct($uMethod, $uPathInfo, array $uDetails = null) |
||
117 | { |
||
118 | $this->method = $uMethod; |
||
119 | $this->pathinfo = $uPathInfo; |
||
120 | $this->details = $uDetails; |
||
0 ignored issues
–
show
It seems like
$uDetails can be null . However, the property $details is declared as array . Maybe change the type of the property to array|null or add a type check?
Our type inference engine has found an assignment of a scalar value (like a string, an integer or null) to a property which is an array. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property. To type hint that a parameter can be either an array or null, you can set a type hint of array and a default value of null. The PHP interpreter will then accept both an array or null for that parameter. function aContainsB(array $needle = null, array $haystack) {
if (!$needle) {
return false;
}
return array_intersect($haystack, $needle) == $haystack;
}
The function can be called with either null or an array for the parameter ![]() |
|||
121 | |||
122 | foreach (["get", "post", "files", "server", "session", "cookies", "headers"] as $tCollection) { |
||
123 | if (!isset($this->details[$tCollection])) { |
||
124 | $this->details[$tCollection] = []; |
||
125 | } |
||
126 | } |
||
127 | } |
||
128 | |||
129 | /** |
||
130 | * Gets endpoint |
||
131 | * |
||
132 | * For http, it's scheme://host:port/directory/ |
||
133 | * |
||
134 | * @return string |
||
135 | */ |
||
136 | public function getEndpoint() |
||
137 | { |
||
138 | return sprintf( |
||
139 | "%s://%s%s", |
||
140 | $this->details["server"]["REQUEST_SCHEME"], |
||
141 | $this->details["server"]["HTTP_HOST"], |
||
142 | $this->details["server"]["SERVER_PORT"] != "80" ? ":" . $this->details["server"]["SERVER_PORT"] : "" |
||
143 | ); |
||
144 | } |
||
145 | |||
146 | /** |
||
147 | * Gets method |
||
148 | * |
||
149 | * @return string |
||
150 | */ |
||
151 | public function getMethod() |
||
152 | { |
||
153 | return $this->method; |
||
154 | } |
||
155 | |||
156 | /** |
||
157 | * Gets path info |
||
158 | * |
||
159 | * @return string |
||
160 | */ |
||
161 | public function getPathInfo() |
||
162 | { |
||
163 | return $this->pathinfo; |
||
164 | } |
||
165 | |||
166 | /** |
||
167 | * Gets remote ip |
||
168 | * |
||
169 | * @return string |
||
170 | */ |
||
171 | public function getRemoteIp() |
||
172 | { |
||
173 | if (isset($this->details["server"]["HTTP_CLIENT_IP"])) { |
||
174 | return $this->details["server"]["HTTP_CLIENT_IP"]; |
||
175 | } |
||
176 | |||
177 | if (isset($this->details["server"]["REMOTE_ADDR"])) { |
||
178 | return $this->details["server"]["REMOTE_ADDR"]; |
||
179 | } |
||
180 | |||
181 | if (isset($this->details["server"]["HTTP_X_FORWARDED_FOR"])) { |
||
182 | return $this->details["server"]["HTTP_X_FORWARDED_FOR"]; |
||
183 | } |
||
184 | |||
185 | return "0.0.0.0"; |
||
186 | } |
||
187 | |||
188 | /** |
||
189 | * Gets accepted content-types |
||
190 | * |
||
191 | * @return array |
||
192 | */ |
||
193 | public function getAcceptedContentTypes() |
||
194 | { |
||
195 | // TODO not implemented |
||
196 | } |
||
197 | |||
198 | /** |
||
199 | * Gets accepted charsets |
||
200 | * |
||
201 | * @return array |
||
202 | */ |
||
203 | public function getAcceptedCharsets() |
||
204 | { |
||
205 | // TODO not implemented |
||
206 | } |
||
207 | |||
208 | /** |
||
209 | * Gets accepted encodings |
||
210 | * |
||
211 | * @return array |
||
212 | */ |
||
213 | public function getAcceptedEncodings() |
||
214 | { |
||
215 | // TODO not implemented |
||
216 | } |
||
217 | |||
218 | /** |
||
219 | * Gets accepted languages |
||
220 | * |
||
221 | * @return array |
||
222 | */ |
||
223 | public function getAcceptedLanguages() |
||
224 | { |
||
225 | // TODO not implemented |
||
226 | } |
||
227 | |||
228 | /** |
||
229 | * Determines whether the request is asynchronous or not |
||
230 | * |
||
231 | * @return bool |
||
232 | */ |
||
233 | public function isAsynchronous() |
||
234 | { |
||
235 | if (!isset($this->details["server"]["HTTP_X_REQUESTED_WITH"])) { |
||
236 | return false; |
||
237 | } |
||
238 | |||
239 | return (strtolower($this->details["server"]["HTTP_X_REQUESTED_WITH"]) === "xmlhttprequest"); |
||
240 | } |
||
241 | |||
242 | /** |
||
243 | * Gets session id |
||
244 | * |
||
245 | * @return string |
||
246 | */ |
||
247 | public function getSessionId() |
||
248 | { |
||
249 | // TODO not implemented |
||
250 | } |
||
251 | |||
252 | /** |
||
253 | * Gets an item from GET collection |
||
254 | * |
||
255 | * @param string $uKey the key for the value |
||
256 | * @param mixed $uDefault default value if the key does not exist in the collection |
||
257 | * |
||
258 | * @return mixed value for the key |
||
259 | */ |
||
260 | View Code Duplication | public function get($uKey, $uDefault = null) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
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. ![]() |
|||
261 | { |
||
262 | if (!isset($this->details["get"][$uKey])) { |
||
263 | return $uDefault; |
||
264 | } |
||
265 | |||
266 | return $this->details["get"][$uKey]; |
||
267 | } |
||
268 | |||
269 | /** |
||
270 | * Gets an item from POST collection |
||
271 | * |
||
272 | * @param string $uKey the key for the value |
||
273 | * @param mixed $uDefault default value if the key does not exist in the collection |
||
274 | * |
||
275 | * @return mixed value for the key |
||
276 | */ |
||
277 | View Code Duplication | public function post($uKey, $uDefault = null) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
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. ![]() |
|||
278 | { |
||
279 | if (!isset($this->details["post"][$uKey])) { |
||
280 | return $uDefault; |
||
281 | } |
||
282 | |||
283 | return $this->details["post"][$uKey]; |
||
284 | } |
||
285 | |||
286 | /** |
||
287 | * Gets an item from FILES collection |
||
288 | * |
||
289 | * @param string $uKey the key for the value |
||
290 | * @param mixed $uDefault default value if the key does not exist in the collection |
||
291 | * |
||
292 | * @return mixed value for the key |
||
293 | */ |
||
294 | View Code Duplication | public function file($uKey, $uDefault = null) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
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. ![]() |
|||
295 | { |
||
296 | if (!isset($this->details["files"][$uKey])) { |
||
297 | return $uDefault; |
||
298 | } |
||
299 | |||
300 | return $this->details["files"][$uKey]; |
||
301 | |||
302 | } |
||
303 | |||
304 | /** |
||
305 | * Gets an item from GET/POST/FILE collections |
||
306 | * |
||
307 | * @param string $uKey the key for the value |
||
308 | * @param mixed $uDefault default value if the key does not exist in the collection |
||
309 | * |
||
310 | * @return mixed value for the key |
||
311 | */ |
||
312 | public function data($uKey, $uDefault = null) |
||
313 | { |
||
314 | foreach (["get", "post", "files"] as $tCollection) { |
||
315 | if (isset($this->details[$tCollection][$uKey])) { |
||
316 | return $this->details[$tCollection][$uKey]; |
||
317 | } |
||
318 | } |
||
319 | |||
320 | return $uDefault; |
||
321 | } |
||
322 | |||
323 | /** |
||
324 | * Gets an item from SERVER collection |
||
325 | * |
||
326 | * @param string $uKey the key for the value |
||
327 | * @param mixed $uDefault default value if the key does not exist in the collection |
||
328 | * |
||
329 | * @return mixed value for the key |
||
330 | */ |
||
331 | View Code Duplication | public function server($uKey, $uDefault = null) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
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. ![]() |
|||
332 | { |
||
333 | if (!isset($this->details["server"][$uKey])) { |
||
334 | return $uDefault; |
||
335 | } |
||
336 | |||
337 | return $this->details["server"][$uKey]; |
||
338 | |||
339 | } |
||
340 | |||
341 | /** |
||
342 | * Gets an item from SESSION collection |
||
343 | * |
||
344 | * @param string $uKey the key for the value |
||
345 | * @param mixed $uDefault default value if the key does not exist in the collection |
||
346 | * |
||
347 | * @return mixed value for the key |
||
348 | */ |
||
349 | View Code Duplication | public function session($uKey, $uDefault = null) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
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. ![]() |
|||
350 | { |
||
351 | if (!isset($this->details["session"][$uKey])) { |
||
352 | return $uDefault; |
||
353 | } |
||
354 | |||
355 | return $this->details["session"][$uKey]; |
||
356 | |||
357 | } |
||
358 | |||
359 | /** |
||
360 | * Gets an item from COOKIE collection |
||
361 | * |
||
362 | * @param string $uKey the key for the value |
||
363 | * @param mixed $uDefault default value if the key does not exist in the collection |
||
364 | * |
||
365 | * @return mixed value for the key |
||
366 | */ |
||
367 | View Code Duplication | public function cookie($uKey, $uDefault = null) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
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. ![]() |
|||
368 | { |
||
369 | if (!isset($this->details["cookies"][$uKey])) { |
||
370 | return $uDefault; |
||
371 | } |
||
372 | |||
373 | return $this->details["cookies"][$uKey]; |
||
374 | |||
375 | } |
||
376 | |||
377 | /** |
||
378 | * Gets an item from HEADER collection |
||
379 | * |
||
380 | * @param string $uKey the key for the value |
||
381 | * @param mixed $uDefault default value if the key does not exist in the collection |
||
382 | * |
||
383 | * @return mixed value for the key |
||
384 | */ |
||
385 | View Code Duplication | public function header($uKey, $uDefault = null) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
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. ![]() |
|||
386 | { |
||
387 | if (!isset($this->details["headers"][$uKey])) { |
||
388 | return $uDefault; |
||
389 | } |
||
390 | |||
391 | return $this->details["headers"][$uKey]; |
||
392 | |||
393 | } |
||
394 | |||
395 | /** |
||
396 | * Checks if item is in the specified collection |
||
397 | * |
||
398 | * @param string|null $uCollection the key of the collection |
||
399 | * @param string $uKey the key for the value |
||
400 | * |
||
401 | * @return bool true if item exists in the collection |
||
402 | */ |
||
403 | public function has($uCollection, $uKey) |
||
404 | { |
||
405 | return isset($this->details[$uCollection][$uKey]); |
||
406 | } |
||
407 | |||
408 | /** |
||
409 | * Gets all items from GET/POST/FILE/SERVER/SESSION/COOKIE/HEADER collections |
||
410 | * |
||
411 | * @param string|null $uCollection the key if only one collection's items are needed |
||
412 | * |
||
413 | * @return array available collections: get, post, files, server, session, cookies, headers |
||
414 | */ |
||
415 | public function all($uCollection = null) |
||
416 | { |
||
417 | if ($uCollection !== null) { |
||
418 | return $this->details[$uCollection]; |
||
419 | } |
||
420 | |||
421 | return $this->details; |
||
422 | } |
||
423 | } |
||
424 |
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: