### Perform Common HTTP Methods (GET, POST, PUT, PATCH, DELETE) in PHP Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/quickstart.md Shows helper functions for making various HTTP requests: GET, POST (with JSON body), PUT (for updates), PATCH (for partial updates), and DELETE. All return JSON data. ```php // GET request $users = get('https://api.example.com/users')->json(); // POST request with JSON body $user = post('https://api.example.com/users', [ 'name' => 'John Doe', 'email' => 'john@example.com' ])->json(); // PUT request to update a resource $updatedUser = put('https://api.example.com/users/123', [ 'name' => 'John Smith' ])->json(); // PATCH request for partial updates $user = patch('https://api.example.com/users/123', [ 'status' => 'active' ])->json(); // DELETE request $result = delete('https://api.example.com/users/123')->json(); ``` -------------------------------- ### Make a GET Request and Parse JSON in PHP Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/quickstart.md Demonstrates how to make a simple GET request using the global fetch() function, parse the JSON response, and check for successful request status. ```php // Make a GET request using the global fetch() function $response = fetch('https://api.example.com/users'); // Parse the JSON response $users = $response->json(); // Check for success if ($response->successful()) { foreach ($users as $user) { echo $user['name'] . PHP_EOL; } } else { echo "Request failed with status: " . $response->status(); } ``` -------------------------------- ### GET Request with Query Parameters - Fetch PHP Source: https://github.com/thavarshan/fetch-php/blob/main/docs/examples/index.md Shows how to perform a GET request with query parameters using the `get()` helper function. It illustrates accessing response data using array syntax. Dependencies: Fetch HTTP package. Input: URL, query parameters. Output: Parsed JSON data or error message. ```php // Make a GET request with query parameters $response = get('https://api.example.com/users', [ 'page' => 1, 'per_page' => 20, 'sort' => 'name' ]); // Access data using array syntax if ($response->successful()) { echo "Total users: " . $response['meta']['total'] . "\n"; foreach ($response['data'] as $user) { echo "- " . $user['name'] . "\n"; } } ``` -------------------------------- ### Basic GET Request - Fetch PHP Source: https://github.com/thavarshan/fetch-php/blob/main/docs/examples/index.md Demonstrates how to make a basic GET request using the fetch() function. It checks for a successful response, parses JSON, and iterates through the data. Dependencies: Fetch HTTP package. Input: URL. Output: Parsed JSON data or error message. ```php // Make a GET request $response = fetch('https://api.example.com/users'); // Check if the request was successful if ($response->successful()) { // Parse the JSON response $users = $response->json(); // Use the data foreach ($users as $user) { echo $user['name'] . "\n"; } } else { echo "Error: " . $response->status() . " " . $response->statusText(); } ``` -------------------------------- ### Access JSON Response Data using Array Syntax in PHP Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/quickstart.md Provides an example of accessing nested JSON data directly using array key notation on the response object, simplifying data retrieval. ```php $name = $response['name']; $email = $response['email']; $address = $response['address']['street']; ``` -------------------------------- ### Logging Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/quickstart.md Configure PSR-3 compatible logging for HTTP requests and responses to aid in debugging and monitoring. ```APIDOC ## Logging ### Description Integrate a PSR-3 compliant logger to capture details of HTTP requests and responses for debugging. ### Method All HTTP methods. ### Endpoint All endpoints. ### Parameters #### Logger Configuration - **setLogger(Psr\Log\LoggerInterface $logger)** - Sets the logger instance on the client or handler. ### Request Example ```php use Monolog\Logger; use Monolog\Handler\StreamHandler; $logger = new Logger('http'); $logger->pushHandler(new StreamHandler('logs/http.log', Logger::DEBUG)); $client = fetch_client(); $client->setLogger($logger); // Or set it on the handler $handler = fetch_client()->getHandler(); $handler->setLogger($logger); $response = get('https://api.example.com/users'); ``` ### Response Logs will be generated based on the configured logger and the log level. ``` -------------------------------- ### First Successful Request with Fetch HTTP Package Source: https://github.com/thavarshan/fetch-php/blob/main/docs/examples/async-patterns.md Explains how to use the `any()` function from the Fetch HTTP package to get the result of the first request that successfully completes, while ignoring any failed requests. This is beneficial for dealing with redundant endpoints where only one needs to be operational. Dependencies include fetch, async, await, and any functions. ```php use function fetch; use function async; use function await; use function any; // Create promises for redundant endpoints $promises = [ async(fn() => fetch('https://api1.example.com/data')), // Might fail async(fn() => fetch('https://api2.example.com/data')), // Might fail async(fn() => fetch('https://api3.example.com/data')) // Should work ]; try { // Get the first successful response $response = await(any($promises)); $data = $response->json(); echo "Got data from a working endpoint"; } catch(\Exception $e) { echo "All endpoints failed: " . $e->getMessage(); } ``` -------------------------------- ### PHP OAuth 2.0 Callback Handling Example Source: https://github.com/thavarshan/fetch-php/blob/main/docs/examples/api-integration.md This example demonstrates how to handle a callback from an OAuth 2.0 provider in a PHP controller. It retrieves the authorization code from the GET parameters, verifies the state parameter against the session to prevent CSRF, and then uses the `OAuth2Client` to obtain access and refresh tokens. It stores these tokens in the session and proceeds to make an authenticated API request. ```php // Usage example (in a controller) function oauthCallback() { $code = $_GET['code'] ?? null; $state = $_GET['state'] ?? null; // Verify state to prevent CSRF if ($state !== $_SESSION['oauth_state']) { die('Invalid state parameter'); } $oauth = new OAuth2Client( 'your-client-id', 'your-client-secret', 'https://your-app.com/oauth/callback', 'https://api.example.com/oauth/token', 'https://api.example.com/oauth/authorize' ); try { $tokenData = $oauth->getAccessToken($code); // Store tokens securely $_SESSION['access_token'] = $tokenData['access_token']; $_SESSION['refresh_token'] = $tokenData['refresh_token']; $_SESSION['expires_at'] = time() + $tokenData['expires_in']; // Fetch user profile with the token $user = $oauth->request('https://api.example.com/me'); // Do something with the user data // ... // Redirect to dashboard header('Location: /dashboard'); exit; } catch (\Exception $e) { // Handle exceptions, e.g., log the error and display an error message error_log('OAuth Error: ' . $e->getMessage()); die('An error occurred during OAuth authentication.'); } } ``` -------------------------------- ### Basic Test Setup with MockServer Source: https://github.com/thavarshan/fetch-php/blob/main/docs/api/testing.md Demonstrates a basic test setup using PHPUnit and Fetch's MockServer. It configures mock responses for specific URLs during the test setup and resets the server after the test. ```php use PHPUnit\Framework\TestCase; use Fetch\Testing\MockServer; use Fetch\Testing\MockResponse; class MyServiceTest extends TestCase { protected function setUp(): void { parent::setUp(); MockServer::fake([ 'https://api.example.com/users' => MockResponse::json(['users' => []]), ]); } protected function tearDown(): void { MockServer::resetInstance(); parent::tearDown(); } public function test_fetches_users(): void { $response = get('https://api.example.com/users'); $this->assertEquals(200, $response->status()); MockServer::assertSent('https://api.example.com/users'); } } ``` -------------------------------- ### Quick Start with Fetch PHP Mocking Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/testing.md This snippet demonstrates the basic setup for mocking HTTP requests in Fetch PHP. It involves defining fake responses for specific URLs using MockServer and then asserting that requests were sent to those URLs. This is essential for testing code that makes HTTP calls without relying on actual network connectivity. ```php use Fetch\Testing\MockServer; use Fetch\Testing\MockResponse; // Set up fake responses MockServer::fake([ 'https://api.example.com/users' => MockResponse::json(['users' => []]), ]); // Make requests (they will be mocked) $response = get('https://api.example.com/users'); // Assert requests were sent MockServer::assertSent('https://api.example.com/users'); ``` -------------------------------- ### Method Chaining for API Requests - PHP Source: https://github.com/thavarshan/fetch-php/blob/main/docs/examples/index.md Shows how to use the fluent interface of Fetch PHP for method chaining, allowing for a more readable and expressive way to build API requests. This includes setting headers, query parameters, and timeouts before making the GET request. The output is a response object which can then be checked for success and parsed. ```php $response = fetch_client() ->getHandler() ->withHeader('X-API-Key', 'your-api-key') ->withQueryParameter('include', 'comments,likes') ->withQueryParameter('sort', 'created_at') ->timeout(5) ->get('https://api.example.com/posts'); if ($response->successful()) { $posts = $response->json(); // Process posts } ``` -------------------------------- ### PHP Content Type Detection with Fetch API Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/quickstart.md Explains how to detect and work with different content types of HTTP responses using the fetch library in PHP. It provides methods to get the content type string, an enumerated type, and convenient boolean checks for JSON, HTML, or plain text content. This allows for appropriate handling of response data based on its format. ```php $response = fetch('https://api.example.com/data'); // Detect content type $contentType = $response->contentType(); $contentTypeEnum = $response->contentTypeEnum(); // Check specific content types if ($response->hasJsonContent()) { $data = $response->json(); } elseif ($response->hasHtmlContent()) { $html = $response->text(); } elseif ($response->hasTextContent()) { $text = $response->text(); } ``` -------------------------------- ### Upload and Download Images with Resizing in PHP Source: https://github.com/thavarshan/fetch-php/blob/main/docs/examples/file-handling.md This snippet demonstrates uploading an image file along with resizing instructions (width, height, crop) to an API endpoint. It then downloads the processed image from the returned URL and saves it locally. The process involves using multipart form data for the upload and then a simple GET request for the download. ```php use function fetch; // Upload an image with resizing instructions $response = fetch('https://api.example.com/images', [ 'method' => 'POST', 'multipart' => [ [ 'name' => 'image', 'contents' => file_get_contents('/path/to/photo.jpg'), 'filename' => 'photo.jpg', 'headers' => ['Content-Type' => 'image/jpeg'] ], [ 'name' => 'width', 'contents' => '800' ], [ 'name' => 'height', 'contents' => '600' ], [ 'name' => 'crop', 'contents' => 'true' ] ] ]); if ($response->successful()) { $result = $response->json(); echo "Image uploaded and processed. URLs:\n"; echo "- Original: " . $result['original_url'] . "\n"; echo "- Resized: " . $result['resized_url'] . "\n"; // Download the processed image $processedImage = fetch($result['resized_url']); if ($processedImage->successful()) { // Save to disk file_put_contents('processed-image.jpg', $processedImage->getBody()->getContents()); echo "Processed image downloaded successfully"; } } else { echo "Image upload failed: " . $response->getStatusCode(); } ``` -------------------------------- ### Sequential Requests with Dependencies using Fetch HTTP Package Source: https://github.com/thavarshan/fetch-php/blob/main/docs/examples/async-patterns.md Illustrates how to make sequential HTTP requests where each subsequent request depends on the result of the previous one. This example chains `await` calls within nested `async` functions to ensure proper ordering and data flow. Dependencies include fetch, async, and await functions. ```php use function fetch; use function async; use function await; await(async(function() { // First, get a list of users $usersResponse = await(async(function() { return fetch('https://api.example.com/users'); })); $users = $usersResponse->json(); // Get the first user's ID $userId = $users[0]['id']; // Then, fetch posts for that user $postsResponse = await(async(function() use ($userId) { return fetch("https://api.example.com/users/{$userId}/posts"); })); $posts = $postsResponse->json(); // Get the first post's ID $postId = $posts[0]['id']; // Finally, fetch comments for that post $commentsResponse = await(async(function() use ($postId) { return fetch("https://api.example.com/posts/{$postId}/comments"); })); $comments = $commentsResponse->json(); return [ 'user' => $users[0], 'posts' => $posts, 'comments' => $comments ]; })); ``` -------------------------------- ### Working with URIs Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/quickstart.md Demonstrates how to configure base URIs and add query parameters to requests using a fluent interface. ```APIDOC ## Working with URIs ### Description Configure the base URI for requests and append query parameters using a fluent API. ### Method GET, POST, PUT, DELETE, etc. ### Endpoint Relative paths are appended to the base URI. ### Parameters #### Request Options (Fluent Interface) - **baseUri(string $uri)** - Sets the base URI for all subsequent requests. - **withQueryParameter(string $key, string $value)** - Adds a single query parameter. - **withQueryParameters(array $params)** - Adds multiple query parameters. ### Request Example ```php $response = fetch_client() ->baseUri('https://api.example.com') ->withQueryParameter('page', 1) ->withQueryParameters([ 'limit' => 10, 'sort' => 'name', 'include' => 'posts,comments' ]) ->get('/users'); ``` ### Response Returns the API response based on the constructed URI and parameters. ``` -------------------------------- ### Verify Fetch HTTP Package Installation Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/installation.md This PHP script demonstrates how to verify the Fetch HTTP package installation by making a simple GET request to a test URL and checking the response status and body. It requires the Composer autoloader to be included and utilizes the global 'fetch' helper function. ```php successful()) { echo "Installation successful!\n"; echo "Response status: " . $response->status() . "\n"; echo "Response body: " . $response->body() . "\n"; } else { echo "Something went wrong. HTTP status: " . $response->status() . "\n"; } ``` -------------------------------- ### Authenticate Requests with Basic Authentication in PHP Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/quickstart.md Demonstrates how to implement Basic Authentication for requests, either by passing username and password in fetch options or using the withAuth helper method. ```php // Using fetch options $response = fetch('https://api.example.com/users', [ 'auth' => ['username', 'password'] ]); // Using helper methods $response = fetch_client() ->withAuth('username', 'password') ->get('https://api.example.com/users'); ``` -------------------------------- ### Configure Global Settings for HTTP Requests in PHP Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/quickstart.md Shows how to set global configuration options like base URI, default headers, and timeouts for all subsequent requests made using the fetch client. ```php fetch_client([ 'base_uri' => 'https://api.example.com', 'headers' => [ 'User-Agent' => 'MyApp/1.0', 'Accept' => 'application/json' ], 'timeout' => 5 ]); // Now all requests use this configuration $users = get('/users')->json(); // Uses base_uri $user = get("/users/{$id}")->json(); ``` -------------------------------- ### File Uploads Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/quickstart.md This section explains how to upload files using the Fetch PHP library, demonstrating both direct and fluent interface approaches. ```APIDOC ## File Uploads ### Description Upload files using the `fetch` function with `multipart` data or the fluent interface. ### Method POST ### Endpoint `https://api.example.com/upload` ### Parameters #### Request Body (Multipart) - **file** (file) - Required - The file to upload. - **description** (string) - Optional - A description for the file. ### Request Example (Direct) ```php $response = fetch('https://api.example.com/upload', [ 'method' => 'POST', 'multipart' => [ [ 'name' => 'file', 'contents' => file_get_contents('/path/to/file.jpg'), 'filename' => 'upload.jpg', ], [ 'name' => 'description', 'contents' => 'File description' ] ] ]); ``` ### Request Example (Fluent Interface) ```php $response = fetch_client() ->withMultipart([ [ 'name' => 'file', 'contents' => fopen('/path/to/file.jpg', 'r'), 'filename' => 'upload.jpg', ], [ 'name' => 'description', 'contents' => 'File description' ] ]) ->post('https://api.example.com/upload'); ``` ### Response #### Success Response (200) Details depend on the API's response to the upload. ``` -------------------------------- ### Log to External Services with PHP Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/logging.md Configure Monolog to send critical errors to Slack while also logging to a file. This setup is useful for production environments to get immediate alerts for critical issues. ```php use Monolog\Logger; use Monolog\Handler\StreamHandler; use Monolog\Handler\SlackWebhookHandler; use Fetch\Http\ClientHandler; // Create a logger that sends critical errors to Slack $logger = new Logger('http'); // Log to file $logger->pushHandler(new StreamHandler('logs/http.log', Logger::INFO)); // Also send critical errors to Slack $logger->pushHandler(new SlackWebhookHandler( 'https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX', '#api-errors', 'API Monitor', true, null, false, false, Logger::CRITICAL )); // Use the logger $client = ClientHandler::create(); $client->setLogger($logger); ``` -------------------------------- ### Creating Mock Responses (For Testing) Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/quickstart.md Generate mock HTTP responses for use in automated testing scenarios, simulating API behavior. ```APIDOC ## Creating Mock Responses (For Testing) ### Description Generate mock responses to simulate API behavior during testing without making actual HTTP requests. ### Method N/A (for creating mocks) ### Endpoint N/A (for creating mocks) ### Parameters #### Mock Response Creation - **ClientHandler::createMockResponse(int $statusCode, array $headers, string $body)** - Creates a generic mock response. - **ClientHandler::createJsonResponse(array $data, int $statusCode)** - Creates a JSON mock response. ### Request Example ```php use Fetch\Http\ClientHandler; // Create a simple mock response $mockResponse = ClientHandler::createMockResponse( statusCode: 200, headers: ['Content-Type' => 'application/json'], body: '{"name": "John", "email": "john@example.com"}' ); // Create a JSON mock response $mockJsonResponse = ClientHandler::createJsonResponse( data: ['name' => 'John', 'email' => 'john@example.com'], statusCode: 200 ); ``` ``` -------------------------------- ### Getting Debug Information from Fetch PHP Handler Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/promise-operations.md Provides an example of how to access and retrieve debug information from the `ClientHandler` in Fetch PHP. This can be useful for understanding the underlying network operations and diagnosing issues. ```php $handler = fetch_client()->getHandler(); $debugInfo = $handler->debug(); print_r($debugInfo); ``` -------------------------------- ### Asynchronous Requests Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/quickstart.md Demonstrates how to perform asynchronous HTTP requests using both the modern async/await pattern and the traditional promise pattern. ```APIDOC ## Asynchronous Requests ### Description Make non-blocking HTTP requests to improve application performance by fetching multiple resources concurrently. ### Method GET (typically for fetching data) ### Endpoint Multiple endpoints can be fetched concurrently. ### Parameters N/A for the asynchronous pattern itself, parameters are specific to the requests being made. ### Request Example (Async/Await) ```php use function async; use function await; use function all; await(async(function() { $results = await(all([ 'users' => async(fn() => fetch('https://api.example.com/users')), 'posts' => async(fn() => fetch('https://api.example.com/posts')), 'comments' => async(fn() => fetch('https://api.example.com/comments')) ])); $users = $results['users']->json(); $posts = $results['posts']->json(); $comments = $results['comments']->json(); echo "Fetched " . count($users) . " users, " . count($posts) . " posts, and " . count($comments) . " comments"; })); ``` ### Request Example (Promise Pattern) ```php $handler = fetch_client()->getHandler(); $handler->async(); $promise = $handler->get('https://api.example.com/users') ->then(function ($response) { if ($response->successful()) { return $response->json(); } throw new \Exception("Request failed with status: " . $response->getStatusCode()); }) ->catch(function (\Throwable $e) { echo "Error: " . $e->getMessage(); }); ``` ### Response Results are processed after all asynchronous operations complete or through promise callbacks. ``` -------------------------------- ### Synchronous HTTP Request Example in PHP Source: https://github.com/thavarshan/fetch-php/wiki/Overview Demonstrates how to perform a synchronous HTTP GET request using the `fetch` function and parse the JSON response. It fetches data from a public API and prints the resulting array. ```php $response = fetch('https://jsonplaceholder.typicode.com/todos/1'); // Get JSON response $data = $response->json(); print_r($data); ``` -------------------------------- ### PHP File Uploads using Fetch API Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/quickstart.md Demonstrates how to upload files using the fetch function in PHP, both with direct parameters and the fluent interface. It shows how to include file contents, filenames, and other form data in the multipart request. The input is a file path and associated data, and the output is a response object. ```php $response = fetch('https://api.example.com/upload', [ 'method' => 'POST', 'multipart' => [ [ 'name' => 'file', 'contents' => file_get_contents('/path/to/file.jpg'), 'filename' => 'upload.jpg', ], [ 'name' => 'description', 'contents' => 'File description' ] ] ]); // Or using the fluent interface $response = fetch_client() ->withMultipart([ [ 'name' => 'file', 'contents' => fopen('/path/to/file.jpg', 'r'), 'filename' => 'upload.jpg', ], [ 'name' => 'description', 'contents' => 'File description' ] ]) ->post('https://api.example.com/upload'); ``` -------------------------------- ### Customize HTTP Requests with Options in PHP Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/quickstart.md Illustrates how to use the fetch() function with an options array to configure request method, headers, JSON payload, query parameters, timeout, and retries. ```php $response = fetch('https://api.example.com/users', [ 'method' => 'POST', 'headers' => [ 'Authorization' => 'Bearer your-token', 'Accept' => 'application/json', 'X-Custom-Header' => 'value' ], 'json' => [ 'name' => 'John Doe', 'email' => 'john@example.com' ], 'query' => [ 'include' => 'posts,comments', 'sort' => 'created_at' ], 'timeout' => 10, 'retries' => 3 ]); ``` -------------------------------- ### Asynchronous HTTP Request Example in PHP Source: https://github.com/thavarshan/fetch-php/wiki/Overview Shows how to make an asynchronous HTTP GET request using `fetch_async` and handle the response using a promise. It fetches data, processes it upon completion, and then waits for the operation to finish. ```php $promise = fetch_async('https://jsonplaceholder.typicode.com/todos/1'); $promise->then(function ($response) { $data = $response->json(); print_r($data); })->wait(); ``` -------------------------------- ### Matching HTTP Methods with MockServer in Fetch PHP Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/testing.md This example demonstrates how to mock different responses based on the HTTP method (GET, POST, PUT, DELETE) used in a request to a specific URL. This is crucial for testing APIs that handle various operations on the same resource. ```php MockServer::fake([ 'GET https://api.example.com/users' => MockResponse::json(['users' => []]), 'POST https://api.example.com/users' => MockResponse::created(['id' => 123]), 'PUT https://api.example.com/users/123' => MockResponse::ok(['updated' => true]), 'DELETE https://api.example.com/users/123' => MockResponse::noContent(), ]); ``` -------------------------------- ### PHP Error Handling for Fetch Requests Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/quickstart.md Illustrates robust error handling for HTTP requests made with the fetch library in PHP using try-catch blocks. It shows how to catch specific exceptions like NetworkException, RequestException, and ClientException, as well as general exceptions. The code also includes a check for failed responses using the `failed()` method. ```php try { $response = fetch('https://api.example.com/users'); if ($response->failed()) { throw new Exception("Request failed with status: " . $response->status()); } $users = $response->json(); } catch (\Fetch\Exceptions\NetworkException $e) { echo "Network error: " . $e->getMessage(); } catch (\Fetch\Exceptions\RequestException $e) { echo "Request error: " . $e->getMessage(); } catch (\Fetch\Exceptions\ClientException $e) { echo "Client error: " . $e->getMessage(); } catch (Exception $e) { echo "Error: " . $e->getMessage(); } ``` -------------------------------- ### PHP Working with URIs using Fetch API Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/quickstart.md Demonstrates how to construct and manipulate URIs for HTTP requests using the fetch library in PHP, particularly with the fluent interface. It shows how to set a base URI and append query parameters, either individually or as an array, to form the final request URL. This simplifies building complex API endpoints. ```php $response = fetch_client() ->baseUri('https://api.example.com') ->withQueryParameter('page', 1) ->withQueryParameters([ 'limit' => 10, 'sort' => 'name', 'include' => 'posts,comments' ]) ->get('/users'); ``` -------------------------------- ### PHP: Integration Test Fetching GitHub User Profile Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/testing.md Provides an example of an integration test that fetches a user profile from the GitHub API. It includes setup to skip the test if a GitHub API token is not configured and asserts the success of the request and the presence of expected data. ```php /** * @group integration */ class GithubApiIntegrationTest extends TestCase { protected function setUp(): void { // Skip if no API token is configured if (empty(getenv('GITHUB_API_TOKEN'))) { $this->markTestSkipped('No GitHub API token available'); } } public function test_can_fetch_user_profile(): void { $response = fetch('https://api.github.com/user', [ 'headers' => [ 'Authorization' => 'Bearer ' . getenv('GITHUB_API_TOKEN'), 'Accept' => 'application/vnd.github.v3+json', ], ]); $this->assertTrue($response->successful()); $this->assertEquals(200, $response->status()); $user = $response->json(); $this->assertArrayHasKey('login', $user); } } ``` -------------------------------- ### Utilize Enums for HTTP Status, Methods, and Content Types in PHP Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/quickstart.md Shows how to use predefined enums for HTTP status codes, request methods, and content types to improve code readability and type safety when making requests. ```php use Fetch\Enum\Status; use Fetch\Enum\Method; use Fetch\Enum\ContentType; // Check status using enum if ($response->statusEnum() === Status::OK) { // Status is 200 OK } // Use method enum for requests $response = fetch_client()->request(Method::POST, '/users', $userData); // Use content type enum $response = fetch_client() ->withBody($data, ContentType::JSON) ->post('/users'); ``` -------------------------------- ### Check HTTP Response Status Codes and Categories in PHP Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/quickstart.md Demonstrates methods for checking the HTTP status of a response, including specific status codes (e.g., isOk, isNotFound) and status categories (successful, clientError, serverError). ```php // Status code checks if ($response->isOk()) { // 200 // Success } elseif ($response->isNotFound()) { // 404 // Not found } elseif ($response->isUnauthorized()) { // 401 // Unauthorized } // Status categories if ($response->successful()) { // 2xx // Success } elseif ($response->isClientError()) { // 4xx // Client error } elseif ($response->isServerError()) { // 5xx // Server error } ``` -------------------------------- ### PHP ApiClient for Authenticated Requests with Token Refresh Source: https://github.com/thavarshan/fetch-php/blob/main/docs/examples/authentication.md An API client that uses a TokenManager to obtain and refresh access tokens for making authenticated HTTP requests. It handles GET and POST requests and automatically retries requests if a 401 error indicates token expiration. Dependencies include the `TokenManager` class and a `fetch` function. ```php baseUrl = rtrim($baseUrl, '/'); $this->tokenManager = $tokenManager; } public function get(string $endpoint, array $query = null) { return $this->request('GET', $endpoint, $query); } public function post(string $endpoint, array $data) { return $this->request('POST', $endpoint, $data); } private function request(string $method, string $endpoint, ?array $data = null) { try { // Get a valid access token $accessToken = $this->tokenManager->getAccessToken(); $options = [ 'method' => $method, 'headers' => [ 'Authorization' => "Bearer {$accessToken}", 'Accept' => 'application/json' ] ]; if ($data !== null) { if ($method === 'GET') { $options['query'] = $data; } else { $options['json'] = $data; } } $response = fetch($this->baseUrl . '/' . ltrim($endpoint, '/'), $options); if ($response->status() === 401 && $response->body() === 'Token has expired') { // Force token refresh and retry $this->tokenManager->setTokens(null); return $this->request($method, $endpoint, $data); } if (!$response->successful()) { throw new \RuntimeException( "API request failed: " . $response->status() . " " . $response->body() ); } return $response->json(); } catch (\Exception $e) { // Handle exceptions } } } ``` -------------------------------- ### Retry Handling Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/quickstart.md Configure automatic retries for failed requests, specifying the number of retries, delay, and conditions for retrying. ```APIDOC ## Retry Handling ### Description Automatically retry requests that fail due to transient network issues or server errors. ### Method GET, POST, PUT, DELETE, etc. ### Endpoint Any endpoint that might experience temporary failures. ### Parameters #### Request Options - **retries** (int) - Optional - The maximum number of times to retry the request. - **retry_delay** (int) - Optional - The initial delay in milliseconds before the first retry. Uses exponential backoff. ### Request Example (Direct) ```php $response = fetch('https://api.example.com/unstable', [ 'retries' => 3, 'retry_delay' => 100 ]); ``` ### Request Example (Fluent Interface) ```php $response = fetch_client() ->retry(3, 100) ->retryStatusCodes([408, 429, 500, 502, 503, 504]) ->retryExceptions(['GuzzleHttp\Exception\ConnectException']) ->get('https://api.example.com/unstable'); ``` ### Response Returns the response from the successful retry or the final error if all retries fail. ``` -------------------------------- ### PHP Logging HTTP Requests with Fetch API Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/quickstart.md Details how to integrate a PSR-3 compatible logger with the fetch library in PHP to log HTTP requests and responses. It shows how to create a Monolog logger instance and attach it to the fetch client or handler. All subsequent requests made through the configured client or handler will then be logged to the specified destination. ```php use Monolog\Logger; use Monolog\Handler\StreamHandler; // Create a PSR-3 compatible logger $logger = new Logger('http'); $logger->pushHandler(new StreamHandler('logs/http.log', Logger::DEBUG)); // Set it on the client $client = fetch_client(); $client->setLogger($logger); // Or set it on the handler $handler = fetch_client()->getHandler(); $handler->setLogger($logger); // Now all requests will be logged $response = get('https://api.example.com/users'); ``` -------------------------------- ### Get Raw Response Body - PHP Source: https://github.com/thavarshan/fetch-php/blob/main/docs/examples/index.md Demonstrates how to retrieve the raw response body from an API request when the content is not JSON or XML. It shows fetching content and also using the text() method. This is useful for handling plain text or binary data. The primary input is a URL, and the output is the raw content of the response. ```php // Get raw response body (for non-JSON/XML content) $response = get('https://api.example.com/text-content'); $content = $response->body(); // Or using text() method $text = $response->text(); echo "Content length: " . strlen($content) . " bytes"; ``` -------------------------------- ### PHP Asynchronous Requests with Fetch API Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/quickstart.md Illustrates performing multiple HTTP requests concurrently using the fetch library in PHP. It supports both modern async/await patterns and the traditional promise-based approach. The input involves URLs to fetch, and the output is processed results from these requests, demonstrating parallel execution and result aggregation. ```php use function async; use function await; use function all; // Modern async/await pattern await(async(function() { // Process multiple requests in parallel $results = await(all([ 'users' => async(fn() => fetch('https://api.example.com/users')), 'posts' => async(fn() => fetch('https://api.example.com/posts')), 'comments' => async(fn() => fetch('https://api.example.com/comments')) ])); // Process the results $users = $results['users']->json(); $posts = $results['posts']->json(); $comments = $results['comments']->json(); echo "Fetched " . count($users) . " users, " . count($posts) . " posts, and " . count($comments) . " comments"; })); // Traditional promise pattern $handler = fetch_client()->getHandler(); $handler->async(); $promise = $handler->get('https://api.example.com/users') ->then(function ($response) { if ($response->successful()) { return $response->json(); } throw new \Exception("Request failed with status: " . $response->getStatusCode()); }) ->catch(function (\Throwable $e) { echo "Error: " . $e->getMessage(); }); ``` -------------------------------- ### PHP Retry Handling for Fetch Requests Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/quickstart.md Shows how to configure automatic retries for failed HTTP requests using the fetch library in PHP. It covers setting the number of retries, the delay between retries (with exponential backoff), and customizing which status codes or exceptions trigger a retry. This improves resilience against transient network issues. ```php // Retry failed requests automatically $response = fetch('https://api.example.com/unstable', [ 'retries' => 3, // Retry up to 3 times 'retry_delay' => 100 // Start with 100ms delay (uses exponential backoff) ]); // Or using the fluent interface $response = fetch_client() ->retry(3, 100) ->retryStatusCodes([408, 429, 500, 502, 503, 504]) // Customize retryable status codes ->retryExceptions(['GuzzleHttp\Exception\ConnectException']) // Customize retryable exceptions ->get('https://api.example.com/unstable'); ``` -------------------------------- ### Content Type Detection Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/quickstart.md Provides methods to detect and handle different content types returned by the API, including JSON, HTML, and plain text. ```APIDOC ## Content Type Detection ### Description Easily determine and handle the content type of an API response. ### Method GET (typically) ### Endpoint Any API endpoint. ### Response #### Success Response (200) - **contentType()** (string) - Returns the detected content type (e.g., 'application/json'). - **contentTypeEnum()** (string) - Returns a more specific enum for common types. - **hasJsonContent()** (bool) - Returns true if the content is JSON. - **hasHtmlContent()** (bool) - Returns true if the content is HTML. - **hasTextContent()** (bool) - Returns true if the content is plain text. ### Response Example ```php $response = fetch('https://api.example.com/data'); $contentType = $response->contentType(); $contentTypeEnum = $response->contentTypeEnum(); if ($response->hasJsonContent()) { $data = $response->json(); } elseif ($response->hasHtmlContent()) { $html = $response->text(); } elseif ($response->hasTextContent()) { $text = $response->text(); } ``` ``` -------------------------------- ### Processing JSON Responses - Fetch PHP Source: https://github.com/thavarshan/fetch-php/blob/main/docs/examples/index.md Shows various ways to handle JSON responses, including getting data as an associative array (default), as an object, and using array access syntax directly on the response object. Dependencies: Fetch HTTP package. Input: URL returning JSON. Output: Parsed JSON data. ```php $response = get('https://api.example.com/users/123'); // Get as associative array (default) $userData = $response->json(); echo $userData['name']; // Get as object $userObject = $response->object(); echo $userObject->name; // Using array access syntax directly on response $name = $response['name']; $email = $response['email']; ``` -------------------------------- ### Authenticate Requests with Bearer Token in PHP Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/quickstart.md Explains two ways to include a Bearer token for authentication: directly in fetch options or by using the withToken helper method on the fetch client. ```php // Using fetch options $response = fetch('https://api.example.com/users', [ 'token' => 'your-token' ]); // Using helper methods $response = fetch_client() ->withToken('your-token') ->get('https://api.example.com/users'); ``` -------------------------------- ### get() shorthand for HTTP GET requests (PHP) Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/helper-functions.md The `get()` function is a convenient shorthand for making HTTP GET requests. It simplifies the process by allowing you to specify the URL, optional query parameters, and additional request options. ```php function get( string $url, ?array $query = null, ?array $options = [] ): ResponseInterface // Example: Simple GET request $response = get('https://api.example.com/users'); // Example: GET with query parameters $response = get('https://api.example.com/users', [ 'page' => 1, 'per_page' => 20 ]); // Example: GET with additional options $response = get('https://api.example.com/users', null, [ 'headers' => ['Accept' => 'application/json'], 'timeout' => 5 ]); ``` -------------------------------- ### Configure Global Defaults - PHP Source: https://github.com/thavarshan/fetch-php/blob/main/docs/examples/index.md Illustrates how to set global default configurations for the Fetch PHP client, such as base URI, timeout, and headers. This simplifies subsequent API calls by avoiding repetitive configuration. The configuration is applied once at the application's bootstrap. Inputs include an associative array of configuration options. ```php // Configure once at application bootstrap fetch_client([ 'base_uri' => 'https://api.example.com', 'timeout' => 10, 'headers' => [ 'User-Agent' => 'MyApp/1.0', 'Accept' => 'application/json' ] ]); // Now use simplified calls in your code $users = get('/users')->json(); // Uses base_uri $user = post('/users', ['name' => 'John'])->json(); ``` -------------------------------- ### Record and Replay HTTP Requests in PHP Source: https://github.com/thavarshan/fetch-php/blob/main/docs/api/testing.md This PHP code snippet demonstrates recording HTTP requests using MockServer and Recorder, then replaying them. It sets up a mock response for a specific URL, starts recording, makes a request, stops recording to get the recordings, resets the mock server, replays the recorded requests, and finally asserts the replayed response. ```php public function test_records_and_replays(): void { // Record real requests MockServer::fake([ 'https://api.example.com/users' => MockResponse::json(['id' => 1]), ]); Recorder::start(); get('https://api.example.com/users'); $recordings = Recorder::stop(); // Reset and replay MockServer::resetInstance(); Recorder::replay($recordings); $response = get('https://api.example.com/users'); $this->assertEquals(['id' => 1], $response->json()); } ``` -------------------------------- ### Handle Different Response Types in PHP Source: https://github.com/thavarshan/fetch-php/blob/main/docs/guide/quickstart.md Shows how to extract data from a response object based on its content type, including JSON (as array or object), plain text, raw body, binary data, and XML. ```php // JSON response $data = $response->json(); // As array $object = $response->object(); // As object $array = $response->array(); // Explicitly as array // Plain text response $text = $response->text(); // Raw response body $content = $response->body(); // Binary data $binary = $response->arrayBuffer(); $stream = $response->blob(); // XML response $xml = $response->xml(); ``` -------------------------------- ### PHP Logging API Requests with Monolog Source: https://github.com/thavarshan/fetch-php/blob/main/docs/examples/error-handling.md This PHP function `fetchWithLogging` integrates with Monolog to log failed API requests and exceptions. It logs warning messages for non-successful HTTP responses and error messages for caught exceptions. The function requires Monolog to be installed and configured, and it accepts a URL and optional fetch options as input, returning the response object. ```php use function fetch; use Monolog\Logger; use Monolog\Handler\StreamHandler; // Create a logger $logger = new Logger('api'); $logger->pushHandler(new StreamHandler('logs/api.log', Logger::ERROR)); function fetchWithLogging(string $url, array $options = []) { global $logger; try { $startTime = microtime(true); $response = fetch($url, $options); $duration = microtime(true) - $startTime; // Log all non-successful responses if ($response->failed()) { $logger->warning("API request failed", [ 'url' => $url, 'method' => $options['method'] ?? 'GET', 'status' => $response->status(), 'duration' => round($duration, 3), 'response' => substr($response->body(), 0, 1000) // Limit response size in logs ]); } return $response; } catch (\Exception $e) { // Log exceptions $logger->error("API request exception", [ 'url' => $url, 'method' => $options['method'] ?? 'GET', 'exception' => get_class($e), 'message' => $e->getMessage(), 'trace' => $e->getTraceAsString() ]); throw $e; } } // Using the function try { $response = fetchWithLogging('https://api.example ``` -------------------------------- ### POST Request to Create Resource - Fetch PHP Source: https://github.com/thavarshan/fetch-php/blob/main/docs/examples/index.md Illustrates creating a resource via a POST request with JSON data using the `post()` function. It handles successful creation and validation errors. Dependencies: Fetch HTTP package. Input: URL, JSON data. Output: Created resource data or validation errors. ```php // Create a user with JSON data $response = post('https://api.example.com/users', [ 'name' => 'John Doe', 'email' => 'john@example.com', 'role' => 'admin' ]); // Check for success and get the created resource if ($response->successful()) { $user = $response->json(); echo "Created user with ID: " . $user['id'] . "\n"; } elseif ($response->isUnprocessableEntity()) { // Handle validation errors $errors = $response->json()['errors']; foreach ($errors as $field => $messages) { echo "$field: " . implode(', ', $messages) . "\n"; } } else { echo "Error: " . $response->status(); } ``` -------------------------------- ### Installing Dependencies with Composer Source: https://github.com/thavarshan/fetch-php/blob/main/CLAUDE.md Install project dependencies using Composer. ```shell composer install ```