This repository was archived by the owner on Aug 14, 2026. It is now read-only.
Repository navigation
Expand file tree
/
Copy pathRequest.php
More file actions
174 lines (151 loc) · 4.7 KB
/
Copy pathRequest.php
File metadata and controls
174 lines (151 loc) · 4.7 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
<?php
/**
* This file is part of the DebugPHP Server.
*
* (c) Leon Schmidt <kontakt@callmeleon.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @see https://github.com/CallMeLeon167/debugphp-server
*/
declare(strict_types=1);
namespace DebugPHP\Server;
/**
* Represents an incoming HTTP request.
*
* Encapsulates all information about the current request:
* HTTP method, URL path, and the decoded JSON body. Provides
* clean accessor methods instead of accessing $_SERVER and
* php://input directly throughout the codebase.
*
* Created via the static factory method:
* $request = Request::fromGlobals();
*/
final class Request
{
/**
* @param string $method HTTP method (GET, POST, etc.).
* @param string $path Normalised URL path (no trailing slash, basePath stripped).
* @param array<string, mixed> $body Decoded JSON body or empty array.
*/
private function __construct(
private readonly string $method,
private readonly string $path,
private readonly array $body,
) {}
/**
* Creates a Request instance from the current PHP superglobals.
*
* Reads the HTTP method and URL from $_SERVER, decodes the JSON
* body from php://input, strips the configured basePath, and
* normalises the path (removes trailing slash).
*
* @return self The current HTTP request.
*/
public static function fromGlobals(): self
{
$methodRaw = $_SERVER['REQUEST_METHOD'] ?? 'GET';
$method = strtoupper(is_string($methodRaw) ? $methodRaw : 'GET');
$rawUri = $_SERVER['REQUEST_URI'] ?? '/';
$uri = is_string($rawUri) ? $rawUri : '/';
$rawPath = parse_url($uri, PHP_URL_PATH);
$path = is_string($rawPath) ? $rawPath : '/';
$baseUrl = Config::baseUrl();
if ($baseUrl !== '' && str_starts_with($path, $baseUrl)) {
$path = substr($path, strlen($baseUrl));
if ($path === '') {
$path = '/';
}
}
if ($path !== '/' && str_ends_with($path, '/')) {
$path = rtrim($path, '/');
}
$body = [];
$raw = file_get_contents('php://input');
if (is_string($raw) && $raw !== '') {
/** @var mixed $decoded */
$decoded = json_decode($raw, true);
if (is_array($decoded)) {
/** @var array<string, mixed> $decoded */
$body = $decoded;
}
}
return new self($method, $path, $body);
}
/**
* Returns the HTTP method (e.g. "GET", "POST", "DELETE").
*
* @return string The HTTP method in uppercase.
*/
public function method(): string
{
return $this->method;
}
/**
* Returns the normalised URL path with basePath stripped (e.g. "/api/session").
*
* @return string The URL path.
*/
public function path(): string
{
return $this->path;
}
/**
* Returns the entire decoded JSON body.
*
* @return array<string, mixed> The request body.
*/
public function body(): array
{
return $this->body;
}
/**
* Reads a string value from the request body.
*
* @param string $key The key to look up in the JSON body.
* @param string $default Fallback value if the key is missing or not a string.
*
* @return string The value or the default.
*/
public function getString(string $key, string $default = ''): string
{
$value = $this->body[$key] ?? null;
return is_string($value) ? $value : $default;
}
/**
* Reads an integer value from the request body.
*
* @param string $key The key to look up in the JSON body.
* @param int $default Fallback value if the key is missing or not numeric.
*
* @return int The value or the default.
*/
public function getInt(string $key, int $default = 0): int
{
$value = $this->body[$key] ?? null;
return is_numeric($value) ? (int) $value : $default;
}
/**
* Returns the raw value for a key from the request body.
*
* @param string $key The key to look up.
*
* @return mixed The value or null if the key is missing.
*/
public function get(string $key): mixed
{
return $this->body[$key] ?? null;
}
/**
* Checks whether a key exists in the request body.
*
* @param string $key The key to check.
*
* @return bool True if the key is present.
*/
public function has(string $key): bool
{
return array_key_exists($key, $this->body);
}
}