friendship ended with social-app. php is my new best friend
1--- 2title: Quickstart 3description: Get up and running with the Fetch HTTP package quickly 4--- 5 6# Quickstart 7 8This guide will help you get started with the Fetch HTTP package quickly. 9 10## Installation 11 12```bash 13composer require jerome/fetch-php 14``` 15 16## Basic Usage 17 18The Fetch HTTP package provides a simple, intuitive API for making HTTP requests, inspired by JavaScript's fetch API but built specifically for PHP. 19 20### Making a Simple Request 21 22```php 23// Make a GET request using the global fetch() function 24$response = fetch('https://api.example.com/users'); 25 26// Parse the JSON response 27$users = $response->json(); 28 29// Check for success 30if ($response->successful()) { 31 foreach ($users as $user) { 32 echo $user['name'] . PHP_EOL; 33 } 34} else { 35 echo "Request failed with status: " . $response->status(); 36} 37``` 38 39### HTTP Methods 40 41The package provides helper functions for common HTTP methods: 42 43```php 44// GET request 45$users = get('https://api.example.com/users')->json(); 46 47// POST request with JSON body 48$user = post('https://api.example.com/users', [ 49 'name' => 'John Doe', 50 'email' => 'john@example.com' 51])->json(); 52 53// PUT request to update a resource 54$updatedUser = put('https://api.example.com/users/123', [ 55 'name' => 'John Smith' 56])->json(); 57 58// PATCH request for partial updates 59$user = patch('https://api.example.com/users/123', [ 60 'status' => 'active' 61])->json(); 62 63// DELETE request 64$result = delete('https://api.example.com/users/123')->json(); 65``` 66 67### Request Options 68 69The `fetch()` function accepts various options to customize your request: 70 71```php 72$response = fetch('https://api.example.com/users', [ 73 'method' => 'POST', 74 'headers' => [ 75 'Authorization' => 'Bearer your-token', 76 'Accept' => 'application/json', 77 'X-Custom-Header' => 'value' 78 ], 79 'json' => [ 80 'name' => 'John Doe', 81 'email' => 'john@example.com' 82 ], 83 'query' => [ 84 'include' => 'posts,comments', 85 'sort' => 'created_at' 86 ], 87 'timeout' => 10, 88 'retries' => 3 89]); 90``` 91 92### Working with Responses 93 94The `Response` object provides methods for different content types: 95 96```php 97// JSON response 98$data = $response->json(); // As array 99$object = $response->object(); // As object 100$array = $response->array(); // Explicitly as array 101 102// Plain text response 103$text = $response->text(); 104 105// Raw response body 106$content = $response->body(); 107 108// Binary data 109$binary = $response->arrayBuffer(); 110$stream = $response->blob(); 111 112// XML response 113$xml = $response->xml(); 114``` 115 116You can also access JSON data using array syntax: 117 118```php 119$name = $response['name']; 120$email = $response['email']; 121$address = $response['address']['street']; 122``` 123 124### Checking Response Status 125 126```php 127// Status code checks 128if ($response->isOk()) { // 200 129 // Success 130} elseif ($response->isNotFound()) { // 404 131 // Not found 132} elseif ($response->isUnauthorized()) { // 401 133 // Unauthorized 134} 135 136// Status categories 137if ($response->successful()) { // 2xx 138 // Success 139} elseif ($response->isClientError()) { // 4xx 140 // Client error 141} elseif ($response->isServerError()) { // 5xx 142 // Server error 143} 144``` 145 146### Using Enums 147 148```php 149use Fetch\Enum\Status; 150use Fetch\Enum\Method; 151use Fetch\Enum\ContentType; 152 153// Check status using enum 154if ($response->statusEnum() === Status::OK) { 155 // Status is 200 OK 156} 157 158// Use method enum for requests 159$response = fetch_client()->request(Method::POST, '/users', $userData); 160 161// Use content type enum 162$response = fetch_client() 163 ->withBody($data, ContentType::JSON) 164 ->post('/users'); 165``` 166 167## Authentication 168 169### Bearer Token 170 171```php 172// Using fetch options 173$response = fetch('https://api.example.com/users', [ 174 'token' => 'your-token' 175]); 176 177// Using helper methods 178$response = fetch_client() 179 ->withToken('your-token') 180 ->get('https://api.example.com/users'); 181``` 182 183### Basic Authentication 184 185```php 186// Using fetch options 187$response = fetch('https://api.example.com/users', [ 188 'auth' => ['username', 'password'] 189]); 190 191// Using helper methods 192$response = fetch_client() 193 ->withAuth('username', 'password') 194 ->get('https://api.example.com/users'); 195``` 196 197## Advanced Features 198 199### Global Configuration 200 201Set up global configuration for all requests: 202 203```php 204fetch_client([ 205 'base_uri' => 'https://api.example.com', 206 'headers' => [ 207 'User-Agent' => 'MyApp/1.0', 208 'Accept' => 'application/json' 209 ], 210 'timeout' => 5 211]); 212 213// Now all requests use this configuration 214$users = get('/users')->json(); // Uses base_uri 215$user = get("/users/{$id}")->json(); 216``` 217 218### File Uploads 219 220```php 221$response = fetch('https://api.example.com/upload', [ 222 'method' => 'POST', 223 'multipart' => [ 224 [ 225 'name' => 'file', 226 'contents' => file_get_contents('/path/to/file.jpg'), 227 'filename' => 'upload.jpg', 228 ], 229 [ 230 'name' => 'description', 231 'contents' => 'File description' 232 ] 233 ] 234]); 235 236// Or using the fluent interface 237$response = fetch_client() 238 ->withMultipart([ 239 [ 240 'name' => 'file', 241 'contents' => fopen('/path/to/file.jpg', 'r'), 242 'filename' => 'upload.jpg', 243 ], 244 [ 245 'name' => 'description', 246 'contents' => 'File description' 247 ] 248 ]) 249 ->post('https://api.example.com/upload'); 250``` 251 252### Asynchronous Requests 253 254```php 255use function async; 256use function await; 257use function all; 258 259// Modern async/await pattern 260await(async(function() { 261 // Process multiple requests in parallel 262 $results = await(all([ 263 'users' => async(fn() => fetch('https://api.example.com/users')), 264 'posts' => async(fn() => fetch('https://api.example.com/posts')), 265 'comments' => async(fn() => fetch('https://api.example.com/comments')) 266 ])); 267 268 // Process the results 269 $users = $results['users']->json(); 270 $posts = $results['posts']->json(); 271 $comments = $results['comments']->json(); 272 273 echo "Fetched " . count($users) . " users, " . 274 count($posts) . " posts, and " . 275 count($comments) . " comments"; 276})); 277 278// Traditional promise pattern 279$handler = fetch_client()->getHandler(); 280$handler->async(); 281 282$promise = $handler->get('https://api.example.com/users') 283 ->then(function ($response) { 284 if ($response->successful()) { 285 return $response->json(); 286 } 287 throw new \Exception("Request failed with status: " . $response->getStatusCode()); 288 }) 289 ->catch(function (\Throwable $e) { 290 echo "Error: " . $e->getMessage(); 291 }); 292``` 293 294### Retry Handling 295 296```php 297// Retry failed requests automatically 298$response = fetch('https://api.example.com/unstable', [ 299 'retries' => 3, // Retry up to 3 times 300 'retry_delay' => 100 // Start with 100ms delay (uses exponential backoff) 301]); 302 303// Or using the fluent interface 304$response = fetch_client() 305 ->retry(3, 100) 306 ->retryStatusCodes([408, 429, 500, 502, 503, 504]) // Customize retryable status codes 307 ->retryExceptions(['GuzzleHttp\Exception\ConnectException']) // Customize retryable exceptions 308 ->get('https://api.example.com/unstable'); 309``` 310 311### Content Type Detection 312 313```php 314$response = fetch('https://api.example.com/data'); 315 316// Detect content type 317$contentType = $response->contentType(); 318$contentTypeEnum = $response->contentTypeEnum(); 319 320// Check specific content types 321if ($response->hasJsonContent()) { 322 $data = $response->json(); 323} elseif ($response->hasHtmlContent()) { 324 $html = $response->text(); 325} elseif ($response->hasTextContent()) { 326 $text = $response->text(); 327} 328``` 329 330### Working with URIs 331 332```php 333$response = fetch_client() 334 ->baseUri('https://api.example.com') 335 ->withQueryParameter('page', 1) 336 ->withQueryParameters([ 337 'limit' => 10, 338 'sort' => 'name', 339 'include' => 'posts,comments' 340 ]) 341 ->get('/users'); 342``` 343 344### Logging 345 346```php 347use Monolog\Logger; 348use Monolog\Handler\StreamHandler; 349 350// Create a PSR-3 compatible logger 351$logger = new Logger('http'); 352$logger->pushHandler(new StreamHandler('logs/http.log', Logger::DEBUG)); 353 354// Set it on the client 355$client = fetch_client(); 356$client->setLogger($logger); 357 358// Or set it on the handler 359$handler = fetch_client()->getHandler(); 360$handler->setLogger($logger); 361 362// Now all requests will be logged 363$response = get('https://api.example.com/users'); 364``` 365 366### Creating Mock Responses (For Testing) 367 368```php 369use Fetch\Http\ClientHandler; 370 371// Create a simple mock response 372$mockResponse = ClientHandler::createMockResponse( 373 statusCode: 200, 374 headers: ['Content-Type' => 'application/json'], 375 body: '{"name": "John", "email": "john@example.com"}' 376); 377 378// Create a JSON mock response 379$mockJsonResponse = ClientHandler::createJsonResponse( 380 data: ['name' => 'John', 'email' => 'john@example.com'], 381 statusCode: 200 382); 383``` 384 385## Error Handling 386 387```php 388try { 389 $response = fetch('https://api.example.com/users'); 390 391 if ($response->failed()) { 392 throw new Exception("Request failed with status: " . $response->status()); 393 } 394 395 $users = $response->json(); 396} catch (\Fetch\Exceptions\NetworkException $e) { 397 echo "Network error: " . $e->getMessage(); 398} catch (\Fetch\Exceptions\RequestException $e) { 399 echo "Request error: " . $e->getMessage(); 400} catch (\Fetch\Exceptions\ClientException $e) { 401 echo "Client error: " . $e->getMessage(); 402} catch (Exception $e) { 403 echo "Error: " . $e->getMessage(); 404} 405``` 406 407## Next Steps 408 409Now that you've gotten started with the basic functionality, check out these guides to learn more: 410 411- [Making Requests](/guide/making-requests) - More details on making HTTP requests 412- [Helper Functions](/guide/helper-functions) - Learn about all available helper functions 413- [Working with Responses](/guide/working-with-responses) - Advanced response handling 414- [Working with Enums](/guide/working-with-enums) - Using type-safe enums for HTTP concepts