egeloen/http-adapter
Deprecated HTTP client abstraction for PHP 5.4.8+ that issues requests via multiple adapters (cURL, Guzzle, Buzz, Zend, etc.) and follows PSR-7 message standards. Bugfixes only; new features moved to php-http.
Installation:
composer require egeloen/http-adapter
(Note: This package is deprecated; prefer php-http/httplug for new projects.)
Basic Usage:
use Ivory\HttpAdapter\Adapter\GuzzleAdapter;
use GuzzleHttp\Client;
use Psr\Http\Message\RequestInterface;
$client = new Client();
$adapter = new GuzzleAdapter($client);
$request = $adapter->createRequest('GET', 'https://api.example.com/data');
$response = $adapter->sendRequest($request);
First Use Case:
Replace Laravel’s native HTTP client (e.g., Http::get()) with this adapter for cross-adapter compatibility:
$adapter = new GuzzleAdapter(new Client());
$response = $adapter->sendRequest($adapter->createRequest('GET', 'https://api.example.com'));
$body = (string) $response->getBody();
Adapter Selection:
GuzzleAdapter for modern APIs, CurlAdapter for legacy systems).$adapter = new CurlAdapter(); // For PHP’s built-in cURL
PSR-7 Compliance:
RequestInterface, ResponseInterface) for consistency:
$request = $adapter->createRequest('POST', '/endpoint')
->withHeader('Content-Type', 'application/json')
->withBody(\GuzzleHttp\Psr7\stream_for(json_encode(['key' => 'value'])));
Event-Driven Extensions:
EventDispatcherHttpAdapter to hook into lifecycle events:
use Ivory\HttpAdapter\EventDispatcherHttpAdapter;
use Symfony\Component\EventDispatcher\EventDispatcher;
$dispatcher = new EventDispatcher();
$eventAdapter = new EventDispatcherHttpAdapter($adapter, $dispatcher);
// Add subscribers (e.g., logging, caching)
$dispatcher->addSubscriber(new \Ivory\HttpAdapter\Event\Subscriber\LoggerSubscriber());
Parallel Requests:
MultiHttpAdapter for concurrent requests:
$multiAdapter = new MultiHttpAdapter([$adapter1, $adapter2]);
$responses = $multiAdapter->sendRequests([$request1, $request2]);
Service Provider:
Bind adapters to Laravel’s container in AppServiceProvider:
public function register()
{
$this->app->singleton('guzzle.adapter', function () {
return new GuzzleAdapter(new \GuzzleHttp\Client());
});
}
Facade Wrapper: Create a facade for cleaner syntax:
// app/Facades/HttpAdapter.php
namespace App\Facades;
use Ivory\HttpAdapter\Adapter\GuzzleAdapter;
use Illuminate\Support\Facades\Facade;
class HttpAdapter extends Facade
{
protected static function getFacadeAccessor() { return 'guzzle.adapter'; }
}
Usage:
$response = HttpAdapter::get()->sendRequest(HttpAdapter::get()->createRequest('GET', '/'));
Middleware: Extend Laravel’s HTTP client middleware to use this adapter:
// app/Http/Middleware/HttpAdapterMiddleware.php
public function handle($request, Closure $next)
{
$adapter = app('guzzle.adapter');
$response = $adapter->sendRequest($adapter->createRequest(
$request->method(),
$request->fullUrl()
));
return response($response->getBody(), $response->getStatusCode());
}
Deprecation Warning:
php-http/httplug for long-term support.Adapter-Specific Quirks:
guzzlehttp/guzzle (v3–v6 supported). Ensure version compatibility.curl PHP extension enabled. Test with:
if (!extension_loaded('curl')) {
throw new \RuntimeException('cURL extension required for CurlAdapter');
}
react/http and async handling. Not ideal for synchronous Laravel routes.Event Dispatcher Overhead:
$dispatcher->removeSubscriber($loggerSubscriber); // Disable logging in prod
PSR-7 Compliance:
FileGetContentsAdapter) may not fully support PSR-7. Validate responses:
if (!$response instanceof \Psr\Http\Message\ResponseInterface) {
throw new \RuntimeException('Adapter returned non-PSR-7 response');
}
Logging Events:
LoggerSubscriber to debug request/response cycles:
$dispatcher->addSubscriber(new LoggerSubscriber(new \Monolog\Logger('http')));
Retry Logic:
RetrySubscriber to handle transient failures:
$retrySubscriber = new RetrySubscriber();
$retrySubscriber->setMaxRetries(3);
$dispatcher->addSubscriber($retrySubscriber);
Cookie Management:
CookieSubscriber to persist cookies across requests:
$cookieJar = new \Ivory\HttpAdapter\Event\Cookie\CookieJar();
$dispatcher->addSubscriber(new CookieSubscriber($cookieJar));
Performance:
MultiHttpAdapter with many concurrent requests (risk of resource exhaustion).GuzzleAdapter vs. CurlAdapter) using:
$start = microtime(true);
$adapter->sendRequest($request);
echo "Time: " . (microtime(true) - $start) . "s";
Custom Adapters:
Ivory\HttpAdapter\Adapter\HttpAdapterInterface for proprietary HTTP clients:
class CustomAdapter implements HttpAdapterInterface
{
public function sendRequest(RequestInterface $request) { ... }
public function createRequest($method, $uri, array $headers = []) { ... }
}
Event Subscribers:
class RateLimitSubscriber implements SubscriberInterface
{
public static function getSubscribedEvents()
{
return [Events::REQUEST_CREATED => 'onRequestCreated'];
}
public function onRequestCreated(RequestCreatedEvent $event) { ... }
}
Middleware Integration:
$dispatcher->addSubscriber(new class implements SubscriberInterface {
public static function getSubscribedEvents() { return [Events::REQUEST_CREATED => 'addAuthHeader']; }
public function addAuthHeader(RequestCreatedEvent $event) {
$event->getRequest()->withHeader('Authorization', 'Bearer ' . auth()->token());
}
});
Testing:
$mockAdapter = $this->createMock(HttpAdapterInterface::class);
$mockAdapter->method('sendRequest')->willReturn(new \GuzzleHttp\Psr7\Response(200));
$eventAdapter = new EventDispatcherHttpAdapter($mockAdapter, new EventDispatcher());
How can I help you explore Laravel packages today?