@@ -50,9 +50,14 @@ class Request extends AbstractDataTransferObject
50
50
protected HeadersCollection $ headers ;
51
51
52
52
/**
53
- * @var string| array<string, mixed>|null The request data.
53
+ * @var array<string, mixed>|null The request data (for query params or form data) .
54
54
*/
55
- protected $ data ;
55
+ protected ?array $ data = null ;
56
+
57
+ /**
58
+ * @var string|null The request body (raw string content).
59
+ */
60
+ protected ?string $ body = null ;
56
61
57
62
/**
58
63
* Constructor.
@@ -75,7 +80,13 @@ public function __construct(HttpMethodEnum $method, string $uri, array $headers
75
80
$ this ->method = $ method ;
76
81
$ this ->uri = $ uri ;
77
82
$ this ->headers = new HeadersCollection ($ headers );
78
- $ this ->data = $ data ;
83
+
84
+ // Separate data and body based on type
85
+ if (is_string ($ data )) {
86
+ $ this ->body = $ data ;
87
+ } elseif (is_array ($ data )) {
88
+ $ this ->data = $ data ;
89
+ }
79
90
}
80
91
81
92
/**
@@ -101,8 +112,8 @@ public function getMethod(): HttpMethodEnum
101
112
*/
102
113
public function getUri (): string
103
114
{
104
- // If GET request with array data, append as query parameters
105
- if ($ this ->method === HttpMethodEnum::GET () && is_array ( $ this ->data ) && !empty ($ this ->data )) {
115
+ // If GET request with data, append as query parameters
116
+ if ($ this ->method === HttpMethodEnum::GET () && $ this ->data !== null && !empty ($ this ->data )) {
106
117
$ separator = strpos ($ this ->uri , '? ' ) === false ? '? ' : '& ' ;
107
118
return $ this ->uri . $ separator . http_build_query ($ this ->data );
108
119
}
@@ -136,12 +147,12 @@ public function getHeader(string $name): ?array
136
147
}
137
148
138
149
/**
139
- * Gets the first value of a specific header .
150
+ * Gets header values as a comma-separated string .
140
151
*
141
152
* @since n.e.x.t
142
153
*
143
154
* @param string $name The header name (case-insensitive).
144
- * @return string|null The header value as a concatenated string, or null if not found.
155
+ * @return string|null The header values as a comma-separated string, or null if not found.
145
156
*/
146
157
public function getHeaderAsString (string $ name ): ?string
147
158
{
@@ -166,9 +177,9 @@ public function hasHeader(string $name): bool
166
177
*
167
178
* For GET requests, returns null.
168
179
* For POST/PUT/PATCH requests:
169
- * - If data is a string , returns it as-is
170
- * - If data is an array and Content-Type is JSON, returns JSON-encoded data
171
- * - If data is an array and Content-Type is form, returns URL-encoded data
180
+ * - If body is set , returns it as-is
181
+ * - If data is set and Content-Type is JSON, returns JSON-encoded data
182
+ * - If data is set and Content-Type is form, returns URL-encoded data
172
183
*
173
184
* @since n.e.x.t
174
185
*
@@ -182,18 +193,13 @@ public function getBody(): ?string
182
193
return null ;
183
194
}
184
195
185
- // If data is null, return null
186
- if ($ this ->data === null ) {
187
- return null ;
188
- }
189
-
190
- // If data is already a string, return it as-is
191
- if (is_string ($ this ->data )) {
192
- return $ this ->data ;
196
+ // If body is set, return it as-is
197
+ if ($ this ->body !== null ) {
198
+ return $ this ->body ;
193
199
}
194
200
195
- // If data is an array , encode based on content type
196
- if (is_array ( $ this ->data ) ) {
201
+ // If data is set , encode based on content type
202
+ if ($ this ->data !== null ) {
197
203
$ contentType = $ this ->getContentType ();
198
204
199
205
// JSON encoding
@@ -249,22 +255,43 @@ public function withHeader(string $name, $value): self
249
255
public function withData ($ data ): self
250
256
{
251
257
$ new = clone $ this ;
252
- $ new ->data = $ data ;
258
+ if (is_string ($ data )) {
259
+ $ new ->body = $ data ;
260
+ $ new ->data = null ;
261
+ } elseif (is_array ($ data )) {
262
+ $ new ->data = $ data ;
263
+ $ new ->body = null ;
264
+ } else {
265
+ $ new ->data = null ;
266
+ $ new ->body = null ;
267
+ }
253
268
return $ new ;
254
269
}
255
270
256
271
/**
257
- * Gets the request data.
272
+ * Gets the request data array .
258
273
*
259
274
* @since n.e.x.t
260
275
*
261
- * @return string| array<string, mixed>|null The request data.
276
+ * @return array<string, mixed>|null The request data array .
262
277
*/
263
- public function getData ()
278
+ public function getData (): ? array
264
279
{
265
280
return $ this ->data ;
266
281
}
267
282
283
+ /**
284
+ * Gets the request body string.
285
+ *
286
+ * @since n.e.x.t
287
+ *
288
+ * @return string|null The request body string.
289
+ */
290
+ public function getBodyString (): ?string
291
+ {
292
+ return $ this ->body ;
293
+ }
294
+
268
295
/**
269
296
* {@inheritDoc}
270
297
*
@@ -315,7 +342,10 @@ public function toArray(): array
315
342
self ::KEY_HEADERS => $ this ->headers ->getAll (),
316
343
];
317
344
318
- if ($ this ->data !== null ) {
345
+ // Include whichever data type is set
346
+ if ($ this ->body !== null ) {
347
+ $ array [self ::KEY_DATA ] = $ this ->body ;
348
+ } elseif ($ this ->data !== null ) {
319
349
$ array [self ::KEY_DATA ] = $ this ->data ;
320
350
}
321
351
0 commit comments