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