ariyx / http-client
A modern, feature-rich PHP HTTP client with advanced capabilities including authentication, middleware, retry mechanisms, and comprehensive testing.
Installs: 1
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 1
Forks: 0
pkg:composer/ariyx/http-client
Requires
- php: ^8.2
- psr/http-message: ^2.0
- psr/log: ^2.0|^3.0
- psr/simple-cache: ^3.0
Requires (Dev)
- mockery/mockery: ^1.6
- monolog/monolog: ^3.0
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^10.0|^11.0
- squizlabs/php_codesniffer: ^3.7
This package is auto-updated.
Last update: 2025-12-12 16:36:56 UTC
README
A modern, feature-rich PHP HTTP client with advanced capabilities including authentication, middleware, retry mechanisms, caching, and comprehensive testing.
โจ Features
- ๐ Modern PHP 8.3+ Support - Built with the latest PHP features and strict typing
- ๐ Multiple Authentication Methods - Basic Auth, Bearer Token, API Key support
- ๐ Middleware System - Retry, Rate Limiting, Logging, Caching middleware
- โก Async Requests - Send multiple requests concurrently
- ๐พ Response Caching - Built-in caching with TTL support
- ๐ก๏ธ Error Handling - Comprehensive exception handling with detailed error information
- ๐ Logging - PSR-3 compatible logging with customizable levels
- โ๏ธ Configuration Management - Flexible configuration system with file support
- ๐งช Comprehensive Testing - Full test coverage with unit and integration tests
- ๐ Extensive Documentation - Detailed documentation with examples
๐ฆ Installation
Install via Composer:
composer require ariyx/http-client
๐ Quick Start
Basic Usage
<?php require 'vendor/autoload.php'; use Ariyx\HttpClient\HttpClient; // Create a new HTTP client $client = new HttpClient(); // Send a GET request $response = $client->get('https://api.example.com/users'); // Check if successful if ($response->isSuccessful()) { $data = $response->json(); echo "User data: " . json_encode($data); } else { echo "Request failed with status: " . $response->getStatusCode(); }
Advanced Usage with Middleware
<?php use Ariyx\HttpClient\HttpClient; use Ariyx\HttpClient\Middleware\RetryMiddleware; use Ariyx\HttpClient\Middleware\LoggingMiddleware; use Ariyx\HttpClient\Auth\BearerAuth; use Ariyx\HttpClient\Request; use Monolog\Logger; use Monolog\Handler\StreamHandler; // Create logger $logger = new Logger('http-client'); $logger->pushHandler(new StreamHandler('app.log', Logger::INFO)); // Create HTTP client with middleware $client = new HttpClient([], $logger); // Add retry middleware $client->addMiddleware(new RetryMiddleware( maxRetries: 3, baseDelay: 1000, backoffMultiplier: 2.0 )); // Add logging middleware $client->addMiddleware(new LoggingMiddleware($logger)); // Create authenticated request $request = Request::get('https://api.example.com/protected') ->setAuthentication(new BearerAuth('your-api-token')); // Send request $response = $client->send($request);
๐ Authentication
Basic Authentication
use Ariyx\HttpClient\Auth\BasicAuth; use Ariyx\HttpClient\Request; $auth = new BasicAuth('username', 'password'); $request = Request::get('https://api.example.com/protected') ->setAuthentication($auth); $response = $client->send($request);
Bearer Token Authentication
use Ariyx\HttpClient\Auth\BearerAuth; $auth = new BearerAuth('your-jwt-token'); $request = Request::get('https://api.example.com/protected') ->setAuthentication($auth); $response = $client->send($request);
API Key Authentication
use Ariyx\HttpClient\Auth\ApiKeyAuth; // Header-based API key $auth = new ApiKeyAuth('your-api-key', 'X-API-Key', ApiKeyAuth::LOCATION_HEADER); // Query parameter-based API key $auth = new ApiKeyAuth('your-api-key', 'api_key', ApiKeyAuth::LOCATION_QUERY); $request = Request::get('https://api.example.com/protected') ->setAuthentication($auth); $response = $client->send($request);
๐ Middleware
Retry Middleware
use Ariyx\HttpClient\Middleware\RetryMiddleware; $retryMiddleware = new RetryMiddleware( maxRetries: 3, // Maximum number of retries baseDelay: 1000, // Base delay in milliseconds backoffMultiplier: 2.0, // Exponential backoff multiplier maxDelay: 10000, // Maximum delay in milliseconds retryableStatusCodes: [500, 502, 503, 504] // Status codes to retry ); $client->addMiddleware($retryMiddleware);
Rate Limiting Middleware
use Ariyx\HttpClient\Middleware\RateLimitMiddleware; $rateLimitMiddleware = new RateLimitMiddleware( maxRequests: 100, // Maximum requests timeWindow: 60 // Time window in seconds ); $client->addMiddleware($rateLimitMiddleware);
Caching Middleware
use Ariyx\HttpClient\Middleware\CacheMiddleware; use Ariyx\HttpClient\Cache\FileCache; $cache = new FileCache('/tmp/http-client-cache'); $cacheMiddleware = new CacheMiddleware( cache: $cache, defaultTtl: 3600, // Default TTL in seconds cacheableMethods: ['GET', 'HEAD'], cacheableStatusCodes: [200, 203, 300, 301, 302, 304, 307, 308] ); $client->addMiddleware($cacheMiddleware);
Logging Middleware
use Ariyx\HttpClient\Middleware\LoggingMiddleware; use Monolog\Logger; use Monolog\Handler\StreamHandler; $logger = new Logger('http-client'); $logger->pushHandler(new StreamHandler('app.log', Logger::INFO)); $loggingMiddleware = new LoggingMiddleware( logger: $logger, requestLogLevel: 'info', responseLogLevel: 'info', logHeaders: true, logBody: false, maxBodyLength: 1000 ); $client->addMiddleware($loggingMiddleware);
โก Async Requests
use Ariyx\HttpClient\Request; // Create multiple requests $requests = [ Request::get('https://api.example.com/users/1'), Request::get('https://api.example.com/users/2'), Request::get('https://api.example.com/users/3'), ]; // Send all requests concurrently $responses = $client->sendAsync($requests); // Process responses foreach ($responses as $index => $response) { if ($response->isSuccessful()) { $userData = $response->json(); echo "User {$index}: " . $userData['name'] . "\n"; } }
โ๏ธ Configuration
Using Configuration Class
use Ariyx\HttpClient\Config\HttpClientConfig; // Create configuration $config = new HttpClientConfig([ 'timeout' => 30, 'connect_timeout' => 10, 'verify_ssl' => true, 'follow_redirects' => true, 'max_redirects' => 5, 'user_agent' => 'MyApp/1.0', 'retry' => [ 'max_retries' => 3, 'base_delay' => 1000, 'backoff_multiplier' => 2.0, ], 'rate_limit' => [ 'max_requests' => 100, 'time_window' => 60, ], 'cache' => [ 'enabled' => true, 'ttl' => 3600, 'driver' => 'file', 'path' => '/tmp/http-client-cache', ], ]); // Load from file $config = HttpClientConfig::fromFile('config/http-client.json'); // Save to file $config->saveToFile('config/http-client.json');
Configuration File Example (JSON)
{
"timeout": 30,
"connect_timeout": 10,
"verify_ssl": true,
"follow_redirects": true,
"max_redirects": 5,
"user_agent": "MyApp/1.0",
"retry": {
"max_retries": 3,
"base_delay": 1000,
"backoff_multiplier": 2.0,
"max_delay": 10000,
"retryable_status_codes": [500, 502, 503, 504]
},
"rate_limit": {
"max_requests": 100,
"time_window": 60
},
"cache": {
"enabled": true,
"ttl": 3600,
"driver": "file",
"path": "/tmp/http-client-cache"
},
"logging": {
"enabled": true,
"request_log_level": "info",
"response_log_level": "info",
"log_headers": true,
"log_body": false,
"max_body_length": 1000
}
}
๐ก๏ธ Error Handling
use Ariyx\HttpClient\Exceptions\RequestException; use Ariyx\HttpClient\Exceptions\ConnectionException; use Ariyx\HttpClient\Exceptions\TimeoutException; try { $response = $client->get('https://api.example.com/data'); } catch (RequestException $e) { echo "Request failed: " . $e->getMessage(); echo "Status code: " . $e->getStatusCode(); echo "URL: " . $e->getUrl(); } catch (ConnectionException $e) { echo "Connection failed: " . $e->getMessage(); echo "Host: " . $e->getHost(); echo "Port: " . $e->getPort(); } catch (TimeoutException $e) { echo "Request timed out: " . $e->getMessage(); echo "Timeout: " . $e->getTimeout() . " seconds"; }
๐ Response Handling
$response = $client->get('https://api.example.com/data'); // Check response status if ($response->isSuccessful()) { // Get response data $json = $response->json(); $xml = $response->xml(); $body = $response->getBody(); // Get response information $statusCode = $response->getStatusCode(); $contentType = $response->getContentType(); $contentLength = $response->getContentLength(); $duration = $response->getDuration(); // Get headers $headers = $response->getHeaders(); $specificHeader = $response->getHeader('Content-Type'); // Get cURL info $info = $response->getInfo(); $totalTime = $response->getTotalTime(); $effectiveUrl = $response->getEffectiveUrl(); }
๐งช Testing
Run the test suite:
# Run all tests composer test # Run with coverage composer test-coverage # Run specific test suite vendor/bin/phpunit tests/Unit vendor/bin/phpunit tests/Integration
๐ Examples
Check the examples/ directory for more detailed examples:
๐ง Development
Code Quality
# Check code style composer cs-check # Fix code style composer cs-fix # Run static analysis composer phpstan # Run all quality checks composer quality
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
๐ License
This project is licensed under the MIT License. See the LICENSE file for details.
๐จโ๐ป Author
Armin Malekzadeh
- Email: arixologist@gmail.com
- GitHub: @ariyx
๐ค Support
If you find this package useful, please consider:
- โญ Starring the repository
- ๐ Reporting bugs
- ๐ก Suggesting new features
- ๐ Improving documentation
- ๐ Contributing code
๐ Changelog
See CHANGELOG.md for a list of changes and version history.