friendship ended with social-app. php is my new best friend
1---
2title: Working with Responses
3description: Learn how to handle and work with HTTP responses in the Fetch PHP package
4---
5
6# Working with Responses
7
8This guide explains how to work with the `Response` class in the Fetch PHP package, which provides a rich set of methods to handle HTTP responses in a convenient and intuitive way.
9
10## Response Basics
11
12When you make an HTTP request with Fetch PHP, you get a `Response` object that represents the HTTP response:
13
14```php
15// Make a simple request
16$response = fetch('https://api.example.com/users');
17
18// The $response is an instance of Fetch\Http\Response
19```
20
21The `Response` class extends PSR-7's `ResponseInterface` and adds many helpful methods to work with HTTP responses.
22
23## Checking Status Codes
24
25### Basic Status Code Checks
26
27```php
28// Get the status code
29$statusCode = $response->getStatusCode(); // Standard PSR-7 method
30$statusCode = $response->status(); // Shorthand method
31
32// Get the status text
33$statusText = $response->getReasonPhrase(); // Standard PSR-7 method
34$statusText = $response->statusText(); // Shorthand method
35```
36
37### Category-Based Status Checks
38
39```php
40// Check if the response is successful (2xx)
41if ($response->successful()) {
42 // Status code is in the 2xx range
43}
44
45// Check for informational responses (1xx)
46if ($response->isInformational()) {
47 // Status code is in the 1xx range
48}
49
50// Check for redirection responses (3xx)
51if ($response->isRedirection() || $response->redirect()) {
52 // Status code is in the 3xx range
53}
54
55// Check for client errors (4xx)
56if ($response->isClientError() || $response->clientError()) {
57 // Status code is in the 4xx range
58}
59
60// Check for server errors (5xx)
61if ($response->isServerError() || $response->serverError()) {
62 // Status code is in the 5xx range
63}
64
65// Check if the response failed (4xx or 5xx)
66if ($response->failed()) {
67 // Status code is either 4xx or 5xx
68}
69```
70
71### Specific Status Code Checks
72
73```php
74// Check for specific status codes
75if ($response->isOk()) { // 200 OK
76 // Handle OK response
77} elseif ($response->isCreated()) { // 201 Created
78 // Handle resource creation
79} elseif ($response->isAccepted()) { // 202 Accepted
80 // Handle accepted but processing
81} elseif ($response->isNoContent()) { // 204 No Content
82 // Handle no content
83} elseif ($response->isUnauthorized()) { // 401 Unauthorized
84 // Handle unauthorized
85} elseif ($response->isForbidden()) { // 403 Forbidden
86 // Handle forbidden
87} elseif ($response->isNotFound()) { // 404 Not Found
88 // Handle not found
89} elseif ($response->isUnprocessableEntity()) { // 422 Unprocessable Entity
90 // Handle validation errors
91}
92
93// Check any status code using isStatus()
94if ($response->isStatus(418)) { // I'm a teapot 🫖
95 echo "This server is a teapot!";
96}
97```
98
99### Using Status Enums
100
101```php
102use Fetch\Enum\Status;
103
104// Get the status code as an enum
105$statusEnum = $response->statusEnum();
106
107// Compare with status enums
108if ($statusEnum === Status::OK) {
109 // Status is exactly 200 OK
110} elseif ($statusEnum === Status::NOT_FOUND) {
111 // Status is exactly 404 Not Found
112}
113
114// Check status with isStatus() using an enum
115if ($response->isStatus(Status::CREATED)) {
116 // Status is 201 Created
117}
118```
119
120## Accessing Response Body
121
122### Getting Raw Content
123
124```php
125// Get the body as a string
126$bodyContents = (string) $response->getBody(); // Standard PSR-7 method
127$bodyContents = $response->body(); // Shorthand method
128$bodyContents = $response->text(); // Alternative method
129
130// Get the body as a binary string (array buffer)
131$binaryData = $response->arrayBuffer();
132
133// Get the body as a stream (similar to a JavaScript Blob)
134$stream = $response->blob();
135while (!feof($stream)) {
136 $chunk = fread($stream, 4096);
137 // Process chunk...
138}
139fclose($stream);
140```
141
142### Working with JSON
143
144```php
145// Parse the body as JSON (returns an array by default)
146$data = $response->json();
147
148// Parse as an object instead of an array
149$object = $response->json(false);
150$object = $response->object(); // Shorthand
151
152// Parse specifically as an array
153$array = $response->array();
154
155// Handle JSON parsing errors
156try {
157 $data = $response->json();
158} catch (RuntimeException $e) {
159 echo "Failed to parse JSON: " . $e->getMessage();
160}
161
162// Silently handle errors (returns empty array/object on error)
163$data = $response->json(true, false); // Don't throw on error
164$object = $response->object(false); // Don't throw on error
165$array = $response->array(false); // Don't throw on error
166```
167
168### Array Access for JSON Responses
169
170The `Response` class implements `ArrayAccess`, allowing you to access JSON data directly:
171
172```php
173// Access JSON data like an array
174$name = $response['name'];
175$email = $response['email'];
176
177// Check if a key exists
178if (isset($response['address'])) {
179 $address = $response['address'];
180}
181
182// Get a value with a default
183$role = $response->get('role', 'user');
184```
185
186### Working with XML
187
188```php
189// Parse the body as XML
190try {
191 $xml = $response->xml();
192
193 // Work with the SimpleXMLElement
194 echo $xml->user->name;
195 foreach ($xml->items->item as $item) {
196 echo $item->name . ": " . $item->price . "\n";
197 }
198} catch (RuntimeException $e) {
199 echo "Failed to parse XML: " . $e->getMessage();
200}
201
202// Silently handle XML parsing errors
203$xml = $response->xml(0, false); // Don't throw on error
204if ($xml !== null) {
205 // Work with the XML
206}
207```
208
209## Working with Headers
210
211```php
212// Get all headers
213$headers = $response->getHeaders(); // Standard PSR-7 method
214$headers = $response->headers(); // Shorthand method
215
216// Get a specific header
217$contentType = $response->getHeaderLine('Content-Type'); // Standard PSR-7 method
218$contentType = $response->header('Content-Type'); // Shorthand method
219
220// Check if a header exists
221if ($response->hasHeader('Content-Type')) {
222 // Header exists
223}
224```
225
226## Content Type Detection
227
228```php
229// Get the content type
230$contentType = $response->contentType();
231
232// Get the content type as an enum
233$contentTypeEnum = $response->contentTypeEnum();
234
235// Check specific content types
236if ($response->hasJsonContent()) {
237 // Response has JSON content
238 $data = $response->json();
239} elseif ($response->hasHtmlContent()) {
240 // Response has HTML content
241 $html = $response->text();
242} elseif ($response->hasTextContent()) {
243 // Response has text-based content
244 $text = $response->text();
245}
246```
247
248## Creating Responses Manually
249
250The `Response` class provides several factory methods to create responses for testing or other purposes:
251
252```php
253use Fetch\Http\Response;
254use Fetch\Enum\Status;
255
256// Create a basic response
257$response = new Response(200, ['Content-Type' => 'text/plain'], 'Hello World');
258
259// Create using a Status enum
260$response = new Response(Status::OK, ['Content-Type' => 'text/plain'], 'Hello World');
261
262// Create a JSON response
263$response = Response::withJson(
264 ['name' => 'John', 'email' => 'john@example.com'],
265 Status::OK
266);
267
268// Create a "No Content" response
269$response = Response::noContent();
270
271// Create a "Created" response
272$response = Response::created(
273 '/resources/123',
274 ['id' => 123, 'name' => 'New Resource']
275);
276
277// Create a redirect response
278$response = Response::withRedirect('/new-location', Status::FOUND);
279```
280
281## Real-World Examples
282
283### Processing a Successful API Response
284
285```php
286$response = fetch('https://api.example.com/users/123');
287
288if ($response->successful()) {
289 $user = $response->json();
290
291 echo "User details:\n";
292 echo "Name: " . $user['name'] . "\n";
293 echo "Email: " . $user['email'] . "\n";
294
295 // Access using array syntax
296 if (isset($response['address'])) {
297 echo "Address: " . $response['address']['street'] . ", " .
298 $response['address']['city'] . "\n";
299 }
300} else {
301 echo "Failed to fetch user: " . $response->status() . " " . $response->statusText();
302}
303```
304
305### Handling Different Response Types
306
307```php
308$response = fetch('https://api.example.com/resource');
309
310// Check content type and process accordingly
311if ($response->hasJsonContent()) {
312 $data = $response->json();
313 // Process JSON data
314} elseif ($response->hasXmlContent()) {
315 $xml = $response->xml();
316 // Process XML data
317} elseif ($response->hasHtmlContent()) {
318 $html = $response->text();
319 // Process HTML content
320} else {
321 $content = $response->text();
322 // Process as plain text
323}
324```
325
326### Handling Validation Errors
327
328```php
329$response = post('https://api.example.com/users', [
330 'name' => '',
331 'email' => 'invalid-email'
332]);
333
334if ($response->isUnprocessableEntity()) {
335 $errors = $response->json()['errors'] ?? [];
336
337 echo "Validation errors:\n";
338 foreach ($errors as $field => $messages) {
339 echo "- {$field}: " . implode(', ', $messages) . "\n";
340 }
341} elseif ($response->successful()) {
342 $user = $response->json();
343 echo "User created with ID: " . $user['id'];
344} else {
345 echo "Error: " . $response->status() . " " . $response->statusText();
346}
347```
348
349### Downloading a File
350
351```php
352$response = fetch('https://example.com/files/document.pdf');
353
354if ($response->successful()) {
355 // Save to file
356 file_put_contents('document.pdf', $response->body());
357 echo "File downloaded successfully!";
358
359 // Or process as a stream
360 $stream = $response->blob();
361 $outputFile = fopen('document.pdf', 'w');
362
363 while (!feof($stream)) {
364 fwrite($outputFile, fread($stream, 8192));
365 }
366
367 fclose($outputFile);
368 fclose($stream);
369} else {
370 echo "Failed to download file: " . $response->status();
371}
372```
373
374### Handling Authentication Responses
375
376```php
377$response = post('https://api.example.com/login', [
378 'email' => 'user@example.com',
379 'password' => 'password123'
380]);
381
382if ($response->isOk()) {
383 $auth = $response->json();
384 $token = $auth['token'];
385
386 // Store the token for future requests
387 $_SESSION['api_token'] = $token;
388
389 echo "Successfully authenticated!";
390} elseif ($response->isUnauthorized()) {
391 echo "Invalid credentials";
392} elseif ($response->isTooManyRequests()) {
393 echo "Too many login attempts. Please try again later.";
394} else {
395 echo "Login failed: " . $response->status();
396}
397```
398
399## Error Handling Best Practices
400
401```php
402try {
403 $response = fetch('https://api.example.com/resource');
404
405 // Check for HTTP errors
406 if ($response->failed()) {
407 if ($response->isNotFound()) {
408 throw new \Exception("Resource not found");
409 } elseif ($response->isUnauthorized()) {
410 throw new \Exception("Authentication required");
411 } else {
412 throw new \Exception("API error: " . $response->status());
413 }
414 }
415
416 // Process the response
417 $data = $response->json();
418
419 // ...
420} catch (\Fetch\Exceptions\NetworkException $e) {
421 // Handle network-related errors
422 echo "Network error: " . $e->getMessage();
423} catch (\Fetch\Exceptions\RequestException $e) {
424 // Handle request-related errors
425 echo "Request error: " . $e->getMessage();
426} catch (\RuntimeException $e) {
427 // Handle response parsing errors
428 echo "Failed to parse response: " . $e->getMessage();
429} catch (\Exception $e) {
430 // Handle other errors
431 echo "Error: " . $e->getMessage();
432}
433```
434
435## Next Steps
436
437- Learn about [Making Requests](/guide/making-requests)
438- Explore [Asynchronous Requests](/guide/async-requests)
439- Discover [Authentication](/guide/authentication)
440- Check out [Error Handling](/guide/error-handling) for more detailed error handling strategies