A lightweight PHP library for asynchronous HTTP requests using native curl_multi_* functions. No external dependencies required!
- 🚀 Asynchronous HTTP requests using
curl_multi_*functions - 🔄 Automatic fallback to synchronous requests if async is not available
- ⚡ Concurrency control - limit the number of parallel requests
- 🎯 Simple API - clean and intuitive interface
- 📦 Zero dependencies - uses only PHP built-in functions
- 🔧 Flexible configuration - custom headers, timeouts, and options
- 📊 Response objects - structured response handling
- 🧪 Well tested - comprehensive test suite included
- PHP 7.4 or higher
- cURL extension enabled
composer require phputility/asyncOr add it to your composer.json:
{
"require": {
"phputility/async": "^1.0"
}
}use Phputils\Async\HttpClient;
$client = new HttpClient([
'timeout' => 5,
'headers' => ['User-Agent: MyApp/1.0']
]);
$responses = $client->get([
'https://api.github.com',
'https://httpbin.org/get',
'https://api.ransomfeed.it'
]);
foreach ($responses as $url => $response) {
echo "[$url] Status: " . $response['status'] . "\n";
echo "Body length: " . strlen($response['body']) . "\n\n";
}$requests = [
['url' => 'https://httpbin.org/post', 'body' => 'Hello World'],
['url' => 'https://httpbin.org/post', 'body' => '{"key": "value"}']
];
$responses = $client->post($requests);
foreach ($responses as $url => $response) {
if ($response['status'] === 200) {
echo "Success: $url\n";
}
}use Phputils\Async\Request;
$requests = [
Request::get('https://api.example.com/data'),
Request::post('https://api.example.com/create', '{"name": "test"}')
->addHeader('Content-Type', 'application/json'),
Request::put('https://api.example.com/update/1', '{"status": "active"}')
];
$responses = $client->request('GET', $requests);$client = new HttpClient([
'concurrency' => 5, // Maximum 5 parallel requests
'timeout' => 10
]);
$urls = array_fill(0, 20, 'https://httpbin.org/delay/1');
$responses = $client->get($urls);
// This will process 5 requests at a time, taking about 4 seconds total$client = new HttpClient([
'headers' => [
'Authorization: Bearer token123',
'X-API-Version: v2'
],
'timeout' => 15
]);
// Override headers for specific requests
$responses = $client->get(['https://api.example.com'], [
'headers' => ['X-Custom: value']
]);$processedCount = 0;
$callback = function ($url, $response) use (&$processedCount) {
$processedCount++;
echo "Processed $processedCount: $url - Status: {$response['status']}\n";
if ($response['status'] === 200) {
// Process successful response
$data = json_decode($response['body'], true);
// ... handle data
}
};
$responses = $client->get($urls, ['callback' => $callback]);$urls = [
'https://httpbin.org/status/200',
'https://httpbin.org/status/404',
'https://invalid-domain.com'
];
$responses = $client->get($urls);
foreach ($responses as $url => $response) {
if (!empty($response['error'])) {
echo "Error for $url: {$response['error']}\n";
} elseif ($response['status'] >= 400) {
echo "HTTP Error for $url: {$response['status']}\n";
} else {
echo "Success for $url: {$response['status']}\n";
}
}new HttpClient(array $options = [])Options:
timeout(int): Request timeout in seconds (default: 30)headers(array): Default headers for all requestsconcurrency(int): Maximum parallel requests (default: 10)callback(callable): Callback function for each completed requestuser_agent(string): User agent string (default: 'phputils-async/1.0')
Execute GET requests asynchronously.
Execute POST requests asynchronously.
Execute requests with specified HTTP method.
Check if curl_multi_* functions are available.
Request::get(string $url, array $headers = [], array $options = []): Request
Request::post(string $url, string $body = null, array $headers = [], array $options = []): Request
Request::put(string $url, string $body = null, array $headers = [], array $options = []): Request
Request::delete(string $url, string $body = null, array $headers = [], array $options = []): Request$request->addHeader(string $name, string $value): Request
$request->setBody(string $body): Request
$request->setOption(string $key, mixed $value): Request
$request->toArray(): array$status(int|null): HTTP status code$headers(array): Response headers$body(string): Response body$error(string|null): Error message$info(array): Additional cURL info
$response->isSuccess(): bool // Check if status is 200-299
$response->toArray(): array // Convert to array format$urls = array_fill(0, 10, 'https://httpbin.org/delay/1');
// Async execution
$start = microtime(true);
$asyncResponses = $client->get($urls);
$asyncTime = microtime(true) - $start;
// Sequential execution
$start = microtime(true);
$sequentialClient = new HttpClient(['concurrency' => 1]);
$sequentialResponses = $sequentialClient->get($urls);
$sequentialTime = microtime(true) - $start;
echo "Async time: " . round($asyncTime, 2) . "s\n";
echo "Sequential time: " . round($sequentialTime, 2) . "s\n";
echo "Speed improvement: " . round($sequentialTime / $asyncTime, 2) . "x\n";Typical results:
- Async: ~1.2 seconds
- Sequential: ~10.1 seconds
- Speed improvement: ~8.4x faster
Run the test suite:
composer testRun with coverage:
composer test-coverageRun code quality checks:
composer quality- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Initial release
- Async HTTP requests with curl_multi_*
- Concurrency control
- Request/Response objects
- Comprehensive test suite
- Zero external dependencies
If you encounter any issues or have questions, please:
- Check the Issues page
- Create a new issue with detailed information
- For questions, use the Discussions page
Made with ❤️ by the Nuke{} (Ransomfeed team)