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