57
57
* @method Response trace(array $params = null)
58
58
*
59
59
* @property-read Request\Context $context the request's context.
60
- * @property-read FileList $files The files associated with the request.
61
- *
60
+ * @property-read Headers $headers the request's headers .
61
+ * @property-read FileList $files the request's files.
62
62
* @property-read bool $authorization Authorization of the request.
63
63
* @property-read int $content_length Length of the request content.
64
64
* @property-read string $ip Remote IP of the request.
@@ -83,7 +83,7 @@ final class Request implements RequestOptions
83
83
{
84
84
/**
85
85
* @uses get_context
86
- * @uses get_files
86
+ * @uses get_headers
87
87
* @uses get_script_name
88
88
* @uses get_method
89
89
* @uses get_query_string
@@ -126,22 +126,35 @@ final class Request implements RequestOptions
126
126
/**
127
127
* Union of {@see $path_params}, {@see $request_params} and {@see $query_params}.
128
128
*
129
- * **Note:** The property is created during construct and is not updated after. If you modify one of
129
+ * **Note**: The property is created during construct and is not updated after. If you modify one of
130
130
* {@see $path_params}, {@see $request_params} and {@see $query_params}, remember to modify {@see $params} as
131
131
* well.
132
132
*
133
133
* @var array<string, mixed>
134
134
*/
135
135
public array $ params ;
136
136
137
+ /**
138
+ * TODO: The property should be readonly but cloning is only available from PHP 8.3:
139
+ * https://www.php.net/releases/8.3/en.php#readonly_classes
140
+ */
137
141
private Request \Context $ context ;
138
142
139
143
private function get_context (): Request \Context
140
144
{
141
145
return $ this ->context ;
142
146
}
143
147
144
- public Headers $ headers ;
148
+ /**
149
+ * TODO: The property should be readonly but cloning is only available from PHP 8.3:
150
+ * https://www.php.net/releases/8.3/en.php#readonly_classes
151
+ */
152
+ private Headers $ headers ;
153
+
154
+ private function get_headers (): Headers
155
+ {
156
+ return $ this ->headers ;
157
+ }
145
158
146
159
/**
147
160
* Request environment.
@@ -153,30 +166,26 @@ private function get_context(): Request\Context
153
166
/**
154
167
* Files associated with the request.
155
168
*
156
- * @var FileList
169
+ * **Note**: The field is not readonly because it can be overwritten by `with()`.
157
170
*/
158
- private $ files ;
171
+ private FileList $ files ;
159
172
160
173
private function get_files (): FileList
161
174
{
162
- if ($ this ->files instanceof FileList) {
163
- return $ this ->files ;
164
- }
165
-
166
- return $ this ->files = FileList::from ($ this ->files ); // @phpstan-ignore-line
175
+ return $ this ->files ;
167
176
}
168
177
169
178
public $ cookie ;
170
179
171
180
/**
172
181
* A request may be created from the `$_SERVER` super global array. In that case `$_SERVER` is
173
- * used as environment the request is created with the following properties:
182
+ * used as environment, the request is created with the following properties:
174
183
*
175
- * - {@see $cookie}: a reference to the `$_COOKIE` super global array .
184
+ * - {@see $cookie}: a reference to the `$_COOKIE` super global.
176
185
* - {@see $path_params}: initialized to an empty array.
177
- * - {@see $query_params}: a reference to the `$_GET` super global array .
178
- * - {@see $request_params}: a reference to the `$_POST` super global array .
179
- * - {@see $files}: a reference to the `$_FILES` super global array .
186
+ * - {@see $query_params}: a reference to the `$_GET` super global.
187
+ * - {@see $request_params}: a reference to the `$_POST` super global.
188
+ * - {@see $files}: a reference to the `$_FILES` super global.
180
189
*
181
190
* A request may also be created from an array of properties, in which case most of them are
182
191
* mapped to the `$env` constructor param. For instance, `is_xhr` set the
@@ -191,9 +200,10 @@ private function get_files(): FileList
191
200
* available in the environment are ignored.
192
201
*
193
202
* @phpstan-param array<RequestOptions::*, mixed>|string|null $properties Properties of the request.
203
+ *
194
204
* @param array<string, mixed> $env Environment, usually the `$_SERVER` array.
195
205
*
196
- * @throws InvalidArgumentException in attempt to use an unsupported option.
206
+ * @throws InvalidArgumentException in an attempt to use an unsupported option.
197
207
*/
198
208
public static function from (array |string |null $ properties = null , array $ env = []): self
199
209
{
@@ -234,13 +244,13 @@ private static function from_server(): self
234
244
self ::OPTION_PATH_PARAMS => [],
235
245
self ::OPTION_QUERY_PARAMS => &$ _GET ,
236
246
self ::OPTION_REQUEST_PARAMS => $ request_params ,
237
- self ::OPTION_FILES => &$ _FILES // @codeCoverageIgnore
247
+ self ::OPTION_FILES => &$ _FILES , // @codeCoverageIgnore
238
248
239
249
], $ _SERVER );
240
250
}
241
251
242
252
/**
243
- * Creates an instance from an URI.
253
+ * Creates an instance from a URI.
244
254
*
245
255
* @param array<string, mixed> $env
246
256
*/
@@ -260,7 +270,7 @@ private static function from_uri(string $uri, array $env): self
260
270
private static function from_options (array $ options , array $ env ): self
261
271
{
262
272
if ($ options ) {
263
- RequestOptionsMapper::map ($ options , $ env );
273
+ $ options = RequestOptionsMapper::map ($ options , $ env );
264
274
}
265
275
266
276
if (!empty ($ env ['QUERY_STRING ' ])) {
@@ -273,28 +283,28 @@ private static function from_options(array $options, array $env): self
273
283
/**
274
284
* Initialize the properties {@see $env}, {@see $headers} and {@see $context}.
275
285
*
276
- * If the {@see $params} property is `null` it is set with an union of {@see $path_params},
286
+ * If the {@see $params} property is `null` it is set with a union of {@see $path_params},
277
287
* {@see $request_params} and {@see $query_params}.
278
288
*
279
- * @phpstan-param array<string, mixed> $properties Initial properties.
289
+ * @phpstan-param array<string, mixed> $options Initial properties.
280
290
*
281
291
* @param array<string, mixed> $env Environment of the request, usually the `$_SERVER` super global.
282
292
*
283
293
* @throws MethodNotAllowed when the request method is not supported.
284
294
*/
285
- private function __construct (array $ properties , array $ env = [])
295
+ private function __construct (array $ options , array $ env = [])
286
296
{
287
297
$ this ->context = new Request \Context ($ this );
288
298
$ this ->env = $ env ;
289
-
290
- foreach ($ properties as $ property => $ value ) {
291
- $ this ->$ property = $ value ;
292
- }
299
+ $ this ->headers = $ options [self ::OPTION_HEADERS ] ?? new Headers ($ env );
300
+ $ this ->files = $ options [self ::OPTION_FILES ] ?? new FileList ();
301
+ $ this ->path_params = $ options [self ::OPTION_PATH_PARAMS ] ?? [];
302
+ $ this ->query_params = $ options [self ::OPTION_QUERY_PARAMS ] ?? [];
303
+ $ this ->request_params = $ options [self ::OPTION_REQUEST_PARAMS ] ?? [];
304
+ $ this ->params = $ this ->path_params + $ this ->request_params + $ this ->query_params ;
305
+ $ this ->cookie = $ options [self ::OPTION_COOKIE ] ?? null ;
293
306
294
307
$ this ->assert_method ($ this ->method );
295
-
296
- $ this ->headers ??= new Headers ($ env );
297
- $ this ->params = $ this ->path_params + $ this ->request_params + $ this ->query_params ;
298
308
}
299
309
300
310
/**
@@ -323,7 +333,7 @@ public function with(array $options): self
323
333
$ changed = clone $ this ;
324
334
325
335
if ($ options ) {
326
- RequestOptionsMapper::map ($ options , $ changed ->env );
336
+ $ options = RequestOptionsMapper::map ($ options , $ changed ->env );
327
337
328
338
foreach ($ options as $ option => &$ value ) {
329
339
$ changed ->$ option = $ value ;
@@ -434,7 +444,7 @@ private function get_is_local(): bool
434
444
*
435
445
* If defined, the `HTTP_X_FORWARDED_FOR` header is used to retrieve the original IP.
436
446
*
437
- * If the `REMOTE_ADDR` header is empty the request is considered local thus `::1` is returned.
447
+ * If the `REMOTE_ADDR` header is empty, the request is considered local; thus `::1` is returned.
438
448
*
439
449
* @link https://en.wikipedia.org/wiki/X-Forwarded-For
440
450
*/
0 commit comments