small / swoole-symfony-http-client
Swoole-based Symfony HTTP client implementation that conforms to the Symfony HttpClientInterface for high-performance asynchronous HTTP requests
Fund package maintenance!
Buy Me A Coffe
Requires
- php: >=8.3
- psr/http-client: *
- psr/http-factory: *
- psr/http-message: *
- small/swoole-patterns: >=22.6.2
- symfony/http-client-contracts: 3.*
- upscale/ext-openswoole: v22.1.*
- upscale/ext-swoole: 5.1.*
Requires (Dev)
Suggests
- ext-openswoole: >=22.1.2
- ext-swoole: >=5.1.4
- openswoole/core: 22.1.5
- symfony/http-client: 7.*
README
Small Swoole Symfony Http Client
Small Swoole Symfony Http Client is a custom HTTP client built using Swoole, designed to be fully compatible with Symfony's HttpClient Component. It provides an asynchronous, non-blocking HTTP client with support for various features such as redirections, retries, timeouts, and more.
Requirements
- PHP 8.3 or higher
- Swoole 5.x or higher or OpenSwoole 22.1.2 or higher
- Composer
Installation
First, ensure you have Swoole installed on your system. You can install it via PECL:
pecl install swoole
Next, install SwooleHttpClient and its dependencies via Composer:
composer require small/swoole-symfony-http-client
Usage
Basic GET Request
use Small\SwooleSymfonyHttpClient\SwooleHttpClient;
$client = new SwooleHttpClient();
$response = $client->request('GET', 'https://example.com');
echo $response->getContent();
Basic POST Request
$client = new SwooleHttpClient();
$response = $client->request('POST', 'https://example.com/api', [
'body' => ['key' => 'value']
]);
echo $response->getContent();
Sending JSON Data
$client = new SwooleHttpClient();
$response = $client->request('PUT', 'https://example.com/api', [
'json' => ['name' => 'John', 'age' => 30]
]);
echo $response->getContent();
Handling Timeouts
$client = new SwooleHttpClient();
try {
$response = $client->request('GET', 'https://example.com/slow-endpoint', [
'timeout' => 2 // in seconds
]);
} catch (Small\SwooleSymfonyHttpClient\Exception\TimeoutException $e) {
echo "Request timed out!";
}
Handling Redirections
$client = new SwooleHttpClient();
$response = $client->withOptions(['max_redirects' => 3])
->request('GET', 'https://example.com/redirect');
echo $response->getContent();
Basic Authentication
$client = new SwooleHttpClient();
$response = $client->withOptions([
'auth_basic' => ['username' => 'admin', 'password' => 'password']
])->request('GET', 'https://example.com/auth');
echo $response->getContent();
Bearer Token Authentication
$client = new SwooleHttpClient();
$response = $client->withOptions([
'auth_bearer' => 'your-bearer-token'
])->request('GET', 'https://example.com/protected');
echo $response->getContent();
Retries on Failed Requests
$client = new SwooleHttpClient();
$response = $client->withOptions([
'retry_failed' => 3 // Retry up to 3 times on failure
])->request('GET', 'https://example.com/flaky-endpoint');
echo $response->getContent();
Custom Headers
$client = new SwooleHttpClient();
$response = $client->withOptions([
'headers' => [
'Accept' => 'application/json',
'Authorization' => 'Bearer token'
]
])->request('GET', 'https://example.com/api');
echo $response->getContent();
PSR-18 Adapter
This library includes a PSR-18 compliant HTTP client adapter, allowing SwooleHttpClient
to be used in contexts expecting a PSR-18 ClientInterface
, such as dependency injection containers or generic HTTP client consumers.
Features Supported in PSR-18 Mode
- Full PSR-18 compliance
- Compatible with any PSR-7 implementation
- Response and Stream factories injected via constructor
- Handles timeouts, redirections, and headers automatically
Usage
use the adapter like this:
use Small\SwooleSymfonyHttpClient\SwooleHttpClient;
use Small\SwooleSymfonyHttpClient\SwooleHttpClientPsr18Adapter;
use Nyholm\Psr7\Factory\Psr17Factory;
$client = new SwooleHttpClient();
$psr17Factory = new Psr17Factory();
// Create the PSR-18 adapter
$adapter = new SwooleHttpClientPsr18Adapter(
$client,
$psr17Factory, // ResponseFactoryInterface
$psr17Factory // StreamFactoryInterface
);
// Create a PSR-7 request
$request = $psr17Factory->createRequest('GET', 'https://example.com');
// Send the request
$response = $adapter->sendRequest($request);
// Get the response body as string
echo $response->getBody();
Poll in order to controle your api consuming flow
In Symfony
Usage: PooledSwooleHttpClient (connection pooling) This variant uses persistent connections through small/swoole-patterns.
Basic example:
use Small\SwooleSymfonyHttpClient\PooledSwooleHttpClient;
$client = new PooledSwooleHttpClient([
'base_uri' => 'http://user:pass@localhost:9501',
'max_connectors' => 10,
'max_wait_time' => 5,
]);
$response = $client->request('GET', '/simpleGet');
echo $response->getStatusCode();
echo $response->getContent();
Available options:
Key | Type | Description |
---|---|---|
base_uri | string | Required. Includes host and optional credentials |
max_connectors | int | (Optional) Max concurrent connections in the pool |
max_wait_time | int | (Optional) Timeout when waiting for a free connector |
rate_controller | array | (Optional) Throttling settings for pooled requests |
Example with rate_controller:
[
'rate_controller' => [
[
'name' => 'api',
'unitForSecond' => 10,
'maxTicks' => 20
]
]
]
PSR-18 adapter to inject pool in PSR-18 compliant interfaces
Usage: PSR-18 Adapter (PooledSwooleHttpClientPsr18Adapter) This adapter allows you to use PooledSwooleHttpClient with any PSR-18 compatible library (e.g. Symfony, HTTPlug).
Example:
use Small\SwooleSymfonyHttpClient\PooledSwooleHttpClient;
use Small\SwooleSymfonyHttpClient\PooledSwooleHttpClientPsr18Adapter;
use Nyholm\Psr7\Factory\Psr17Factory;
$client = new PooledSwooleHttpClient([
'base_uri' => 'http://user:pass@localhost:9501',
]);
$psr17 = new Psr17Factory();
$adapter = new PooledSwooleHttpClientPsr18Adapter(
$client,
$psr17,
$psr17
);
$request = $psr17->createRequest('POST', 'http://localhost:9501/post')
->withHeader('Content-Type', 'application/json')
->withBody($psr17->createStream(json_encode(['key' => 'value'])));
$response = $adapter->sendRequest($request);
echo $response->getStatusCode();
echo $response->getBody()->__toString();
Running Tests
Build containers :
docker compose up -d
And run with composer :
bin/composer unit-tests
License
This project is licensed under the MIT License. See the LICENSE file for details.