https://github.com/Thavarshan/fetch-php
🚀 A lightweight HTTP library inspired by JavaScript's fetch, bringing simplicity and flexibility to PHP HTTP requests.
https://github.com/Thavarshan/fetch-php
fetch fetch-api fetch-php guzzle guzzle-php-library guzzlehttp http http-client javascript-fetch javascript-fetch-api php
Last synced: 16 days ago
JSON representation
🚀 A lightweight HTTP library inspired by JavaScript's fetch, bringing simplicity and flexibility to PHP HTTP requests.
- Host: GitHub
- URL: https://github.com/Thavarshan/fetch-php
- Owner: Thavarshan
- License: gpl-3.0
- Created: 2024-09-13T18:33:05.000Z (10 months ago)
- Default Branch: main
- Last Pushed: 2025-05-19T18:10:46.000Z (about 1 month ago)
- Last Synced: 2025-05-22T07:03:18.066Z (about 1 month ago)
- Topics: fetch, fetch-api, fetch-php, guzzle, guzzle-php-library, guzzlehttp, http, http-client, javascript-fetch, javascript-fetch-api, php
- Language: PHP
- Homepage: https://fetch-php.thavarshan.com/
- Size: 2 MB
- Stars: 409
- Watchers: 7
- Forks: 23
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Funding: .github/FUNDING.yml
- License: LICENSE
- Security: .github/SECURITY.md
- Support: .github/SUPPORT.md
Awesome Lists containing this project
README
# Fetch PHP
[](https://packagist.org/packages/jerome/fetch-php)
[](https://github.com/Thavarshan/fetch-php/actions/workflows/tests.yml)
[](https://github.com/Thavarshan/fetch-php/actions/workflows/lint.yml)
[](https://github.com/Thavarshan/fetch-php/actions/workflows/github-code-scanning/codeql)
[](https://phpstan.org/)
[](https://packagist.org/packages/jerome/fetch-php)
[](https://packagist.org/packages/jerome/fetch-php)
[](https://packagist.org/packages/jerome/fetch-php)
[](https://github.com/Thavarshan/fetch-php/stargazers)**Fetch PHP** is a modern HTTP client library for PHP that brings JavaScript's `fetch` API experience to PHP. Built on top of Guzzle, Fetch PHP allows you to write HTTP code with a clean, intuitive JavaScript-like syntax while still maintaining PHP's familiar patterns.
With support for both synchronous and asynchronous requests, a fluent chainable API, and powerful retry mechanics, Fetch PHP streamlines HTTP operations in your PHP applications.
Full documentation can be found [here](https://fetch-php.thavarshan.com/)
---
## Key Features
- **JavaScript-like Syntax**: Write HTTP requests just like you would in JavaScript with the `fetch()` function and `async`/`await` patterns
- **Promise-based API**: Use familiar `.then()`, `.catch()`, and `.finally()` methods for async operations
- **Fluent Interface**: Build requests with a clean, chainable API
- **Built on Guzzle**: Benefit from Guzzle's robust functionality with a more elegant API
- **Retry Mechanics**: Automatically retry failed requests with exponential backoff
- **PHP-style Helper Functions**: Includes traditional PHP function helpers (`get()`, `post()`, etc.) for those who prefer that style## Why Choose Fetch PHP?
### Beyond Guzzle
While Guzzle is a powerful HTTP client, Fetch PHP enhances the experience by providing:
- **JavaScript-like API**: Enjoy the familiar `fetch()` API and `async`/`await` patterns from JavaScript
- **Global client management**: Configure once, use everywhere with the global client
- **Simplified requests**: Make common HTTP requests with less code
- **Enhanced error handling**: Reliable retry mechanics and clear error information
- **Type-safe enums**: Use enums for HTTP methods, content types, and status codes| Feature | Fetch PHP | Guzzle |
|---------|-----------|--------|
| API Style | JavaScript-like fetch + async/await + PHP-style helpers | PHP-style only |
| Client Management | Global client + instance options | Instance-based only |
| Request Syntax | Clean, minimal | More verbose |
| Types | Modern PHP 8.1+ enums | String constants |
| Helper Functions | Multiple styles available | Limited |## Installation
```bash
composer require jerome/fetch-php
```> **Requirements**: PHP 8.1 or higher
## Basic Usage
### JavaScript-style API
```php
// Simple GET request
$response = fetch('https://api.example.com/users');
$users = $response->json();// POST request with JSON body
$response = fetch('https://api.example.com/users', [
'method' => 'POST',
'json' => ['name' => 'John Doe', 'email' => '[email protected]'],
]);
```### PHP-style Helpers
```php
// GET request with query parameters
$response = get('https://api.example.com/users', ['page' => 1, 'limit' => 10]);// POST request with JSON data
$response = post('https://api.example.com/users', [
'name' => 'John Doe',
'email' => '[email protected]'
]);
```### Fluent API
```php
// Chain methods to build your request
$response = fetch_client()
->baseUri('https://api.example.com')
->withHeaders(['Accept' => 'application/json'])
->withToken('your-auth-token')
->withQueryParameters(['page' => 1, 'limit' => 10])
->get('/users');
```## Async/Await Pattern
### Using Async/Await
```php
// Import async/await functions
use function async;
use function await;// Wrap your fetch call in an async function
$promise = async(function() {
return fetch('https://api.example.com/users');
});// Await the result
$response = await($promise);
$users = $response->json();echo "Fetched " . count($users) . " users";
```### Multiple Concurrent Requests with Async/Await
```php
use function async;
use function await;
use function all;// Execute an async function
await(async(function() {
// Create multiple requests
$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";
}));
```### Sequential Requests with Async/Await
```php
use function async;
use function await;await(async(function() {
// First request: get auth token
$authResponse = await(async(fn() =>
fetch('https://api.example.com/auth/login', [
'method' => 'POST',
'json' => [
'username' => 'user',
'password' => 'pass'
]
])
));$token = $authResponse->json()['token'];
// Second request: use token to get user data
$userResponse = await(async(fn() =>
fetch('https://api.example.com/me', [
'token' => $token
])
));return $userResponse->json();
}));
```### Error Handling with Async/Await
```php
use function async;
use function await;try {
$data = await(async(function() {
$response = await(async(fn() =>
fetch('https://api.example.com/users/999')
));if ($response->isNotFound()) {
throw new \Exception("User not found");
}return $response->json();
}));// Process the data
} catch (\Exception $e) {
echo "Error: " . $e->getMessage();
}
```## Traditional Promise-based Pattern
```php
// Set up an async request
// Get the handler for async operations
$handler = fetch_client()->getHandler();
$handler->async();// Make the async request
$promise = $handler->get('https://api.example.com/users');// Handle the result with callbacks
$promise->then(
function ($response) {
// Process successful response
$users = $response->json();
foreach ($users as $user) {
echo $user['name'] . PHP_EOL;
}
},
function ($exception) {
// Handle errors
echo "Error: " . $exception->getMessage();
}
);
```## Advanced Async Usage
### Concurrent Requests with Promise Utilities
```php
use function race;// Create promises for redundant endpoints
$promises = [
async(fn() => fetch('https://api1.example.com/data')),
async(fn() => fetch('https://api2.example.com/data')),
async(fn() => fetch('https://api3.example.com/data'))
];// Get the result from whichever completes first
$response = await(race($promises));
$data = $response->json();
echo "Got data from the fastest source";
```### Controlled Concurrency with Map
```php
use function map;// List of user IDs to fetch
$userIds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];// Process at most 3 requests at a time
$responses = await(map($userIds, function($id) {
return async(function() use ($id) {
return fetch("https://api.example.com/users/{$id}");
});
}, 3));// Process the responses
foreach ($responses as $index => $response) {
$user = $response->json();
echo "Processed user {$user['name']}\n";
}
```### Batch Processing
```php
use function batch;// Array of items to process
$items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];// Process in batches of 3 with max 2 concurrent batches
$results = await(batch(
$items,
function($batch) {
// Process a batch
return async(function() use ($batch) {
$batchResults = [];
foreach ($batch as $id) {
$response = await(async(fn() =>
fetch("https://api.example.com/users/{$id}")
));
$batchResults[] = $response->json();
}
return $batchResults;
});
},
3, // batch size
2 // concurrency
));
```### With Retries
```php
use function retry;// Retry a flaky request up to 3 times with exponential backoff
$data = await(retry(
function() {
return async(function() {
return fetch('https://api.example.com/unstable-endpoint');
});
},
3, // max attempts
function($attempt) {
// Exponential backoff strategy
return min(pow(2, $attempt) * 100, 1000);
}
));
```## Advanced Configuration
### Authentication
```php
// Basic auth
$response = fetch('https://api.example.com/secure', [
'auth' => ['username', 'password']
]);// Bearer token
$response = fetch_client()
->withToken('your-oauth-token')
->get('https://api.example.com/secure');
```### Proxies
```php
$response = fetch('https://api.example.com', [
'proxy' => 'http://proxy.example.com:8080'
]);// Or with fluent API
$response = fetch_client()
->withProxy('http://proxy.example.com:8080')
->get('https://api.example.com');
```### Global Client Configuration
```php
// Configure once at application bootstrap
fetch_client([
'base_uri' => 'https://api.example.com',
'headers' => [
'User-Agent' => 'MyApp/1.0',
'Accept' => 'application/json',
],
'timeout' => 10,
]);// Use the configured client throughout your application
function getUserData($userId) {
return fetch_client()->get("/users/{$userId}")->json();
}function createUser($userData) {
return fetch_client()->post('/users', $userData)->json();
}
```## Working with Responses
```php
$response = fetch('https://api.example.com/users/1');// Check if request was successful
if ($response->isSuccess()) {
// HTTP status code
echo $response->getStatusCode(); // 200// Response body as JSON
$user = $response->json();// Response body as string
$body = $response->getBody()->getContents();// Get a specific header
$contentType = $response->getHeaderLine('Content-Type');// Check status code categories
if ($response->getStatus()->isSuccess()) {
echo "Request succeeded";
}
}
```## Working with Type-Safe Enums
```php
use Fetch\Enum\Method;
use Fetch\Enum\ContentType;
use Fetch\Enum\Status;// Use enums for HTTP methods
$client = fetch_client();
$response = $client->request(Method::POST, '/users', $userData);// Check HTTP status with enums
if ($response->getStatus() === Status::OK) {
// Process successful response
}// Content type handling
$response = $client->withBody($data, ContentType::JSON)->post('/users');
```## Error Handling
```php
// Synchronous error handling
try {
$response = fetch('https://api.example.com/nonexistent');if (!$response->isSuccess()) {
echo "Request failed with status: " . $response->getStatusCode();
}
} catch (\Throwable $e) {
echo "Exception: " . $e->getMessage();
}// Asynchronous error handling
$handler = fetch_client()->getHandler();
$handler->async();$promise = $handler->get('https://api.example.com/nonexistent')
->then(function ($response) {
if ($response->isSuccess()) {
return $response->json();
}
throw new \Exception("Request failed with status: " . $response->getStatusCode());
})
->catch(function (\Throwable $e) {
echo "Error: " . $e->getMessage();
});
```## License
This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details.
## Contributing
Contributions are welcome! We're currently looking for help with:
- Expanding test coverage
- Improving documentation
- Adding support for additional HTTP featuresTo contribute:
1. Fork the Project
2. Create your Feature Branch (`git checkout -b feature/amazing-feature`)
3. Commit your Changes (`git commit -m 'Add some amazing-feature'`)
4. Push to the Branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request## Acknowledgments
- Thanks to **Guzzle HTTP** for providing the underlying HTTP client
- Thanks to all contributors who have helped improve this package
- Special thanks to the PHP community for their support and feedback