PHPackages                             elastic/transport - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [HTTP &amp; Networking](/categories/http)
4. /
5. elastic/transport

ActiveLibrary[HTTP &amp; Networking](/categories/http)

elastic/transport
=================

HTTP transport PHP library for Elastic products

v9.0.1(1y ago)1920.6M—1.3%18[4 issues](https://github.com/elastic/elastic-transport-php/issues)[2 PRs](https://github.com/elastic/elastic-transport-php/pulls)7MITPHPPHP ^8.1CI passing

Since Mar 10Pushed 9mo ago169 watchersCompare

[ Source](https://github.com/elastic/elastic-transport-php)[ Packagist](https://packagist.org/packages/elastic/transport)[ RSS](/packages/elastic-transport/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (14)Versions (38)Used By (7)

[![](https://camo.githubusercontent.com/c9d308aa45784dfd20af1d3b574a1cb3deb3ed3b6d1cb450487814498396a4b4/68747470733a2f2f7777772e656c61737469632e636f2f7374617469632d7265732f696d616765732f656c61737469632d6c6f676f2d3230302e706e67)](https://camo.githubusercontent.com/c9d308aa45784dfd20af1d3b574a1cb3deb3ed3b6d1cb450487814498396a4b4/68747470733a2f2f7777772e656c61737469632e636f2f7374617469632d7265732f696d616765732f656c61737469632d6c6f676f2d3230302e706e67)

HTTP transport for Elastic PHP clients
======================================

[](#http-transport-for-elastic-php-clients)

[![Build status](https://github.com/elastic/elastic-transport-php/workflows/Test/badge.svg)](https://github.com/elastic/elastic-transport-php/actions)

This is a HTTP transport PHP library for communicate with [Elastic](https://www.elastic.co/)products, like [Elasticsearch](https://github.com/elastic/elasticsearch).

It implements [PSR-7](https://www.php-fig.org/psr/psr-7/) standard for managing HTTP messages and [PSR-18](https://www.php-fig.org/psr/psr-18/) for sending HTTP requests. Moreover, it uses the [PSR-17](https://www.php-fig.org/psr/psr-17/) for building `PSR-7` objects like HTTP requests, HTTP responses, URI, etc.

It uses the [HTTPlug](http://httplug.io/) library to automatic discovery a [PSR-18](https://www.php-fig.org/psr/psr-18/)client, a [PSR-17](https://www.php-fig.org/psr/psr-17/) factory and the [HttpAsyncClient](https://github.com/php-http/httplug/blob/master/src/HttpAsyncClient.php)interface with [Promise](https://docs.php-http.org/en/latest/components/promise.html) for asyncronous HTTP requestes.

Starting from 9.0.0 version, if no PSR-18 clients are discovered, the library uses a default [custom HTTP client](src/Client/Curl.php) based on [cURL](https://curl.se/). This client relies on the [cURL php extension](https://www.php.net/manual/en/book.curl.php)that must be installed. Moreover, this client does **not** implement the [HttpAsyncClient](https://github.com/php-http/httplug/blob/master/src/HttpAsyncClient.php)interface, which means you won't be able to send asynchronous requests. If you need support for asynchronous requests, consider installing a PST-18 HTTP client like [Guzzle](https://github.com/guzzle/guzzle):

```
composer require guzzlehttp/guzzle
```

or [Symfony HTTP Client](https://github.com/symfony/http-client):

```
composer require symfony/http-client
```

The architecture of the Transport is flexible and customizable, you can configure it using a [PSR-18](https://www.php-fig.org/psr/psr-18/) client, a [PSR-3](https://www.php-fig.org/psr/psr-3/)logger and a custom [NodePoolInterface](src/NodePool/NodePoolInterface.php), to manage a cluster of nodes.

Quick start
-----------

[](#quick-start)

The main component of this library is the [Transport](src/Transport.php) class.

This class uses 3 components:

- a PSR-18 client, using [ClientInterface](https://www.php-fig.org/psr/psr-18/#interfaces);
- a Node pool, using [NodePoolInterface](src/NodePool/NodePoolInterface.php);
- a PSR-3 logger, using [LoggerInterface](https://www.php-fig.org/psr/psr-3/#3-psrlogloggerinterface).

While the `PSR-3` and `PSR-18` are well known standard in the PHP community, the `NodePoolInterface`is a new interface proposed in this library. The idea of this interface is to provide a class that is able to select a node for a list of hosts. For instance, using Elasticsearch, that is a distributed search engine, you need to manage a cluster of nodes. Each node exposes a common HTTP API and you can send the HTTP requests to one or more nodes. The `NodePoolInterface` is a component that can be used to manage the routing of the HTTP requests to the cluster node topology.

In order to buid a `Transport` instance, you can use the `TransportBuilder` as follows:

```
use Elastic\Transport\TransportBuilder;

$transport = TransportBuilder::create()
    ->setHosts(['localhost:9200'])
    ->build();
```

This example shows how to set the transport to communicate with one node located at `localhost:9200`(e.g. Elasticsearch default port).

By default, `TransportBuilder` will use the autodiscovery feature of [HTTPlug](http://httplug.io/)for the [PSR-18](https://www.php-fig.org/psr/psr-18/) client, the [SimpleNodePool](src/NodePool/SimpleNodePool.php)as `NodePoolInterface` and the [NullLogger](https://github.com/php-fig/log/blob/master/Psr/Log/NullLogger.php)as `LoggerInterface`.

The `Tranport` class itself implements the [PSR-18](https://www.php-fig.org/psr/psr-18/) and the [HttpAsyncClient](https://github.com/php-http/httplug/blob/master/src/HttpAsyncClient.php) interfaces, that means you can use it to send any HTTP request using the `Tranport::sendRequest()` function as follows:

```
use Http\Discovery\Psr17FactoryDiscovery;

$factory = Psr17FactoryDiscovery::findRequestFactory();
$request = $factory->createRequest('GET', '/info'); // PSR-7 request
$response = $transport->sendRequest($request);
var_dump($response); // PSR-7 response
```

The `sendRequest` function will use `$request` to send the HTTP request to the `localhost:9200`node specified in the previous example code. This behaviour can be used to specify only the URL path in the HTTP request, the host is selected at runtime using the `NodePool` implementation.

**NOTE**: if you send a `$request` that contains already a host the `Transport` will use it without using the `NodePool` to select a node specified in `TransportBuilder::setHosts()`settings.

For instance, the following example will send the `/info` request to `domain` and not `localhost`.

```
use Elastic\Transport\TransportBuilder;

$transport = TransportBuilder::create()
    ->setHosts(['localhost:9200'])
    ->build();

$request = new Request('GET', 'https://domain.com/info');
$response = $transport->sendRequest($request); // the HTTP request will be sent to domain.com

echo $transport->lastRequest()->getUri()->getHost(); // domain.com
```

Asyncronous requests
--------------------

[](#asyncronous-requests)

You can send an asyncronous HTTP request using the `Transport::sendAsyncRequest()` as follows:

```
use Http\Discovery\Psr17FactoryDiscovery;

$factory = Psr17FactoryDiscovery::findRequestFactory();
$request = $factory->createRequest('GET', '/info'); // PSR-7 request
$promise= $transport->sendAsyncRequest($request);
var_dump($promise); // Promise
var_dump($promise->wait()); // PSR-7 response
```

The `$promise` contains a [Promise](https://docs.php-http.org/en/latest/components/promise.html) object. A promise is an object that does not block the execution of PHP. This means the promise does not contain the HTTP response. In order to read the HTTP response you need to use the `wait()` function.

Another approach to use a promise is to specify the functions to be called on success and on faliure of the HTTP request. This can achieved using the `then()` function as follows:

```
$promise->then(function (ResponseInterface $response) {
    // onFulfilled callback, $reponse is PSR-7
    echo 'The response is available';

    return $response;
}, function (Exception $e) {
    // onRejected callback
    echo 'An error happens';

    throw $e;
});
```

For more information about the usage of Promise objetcs you can read the [documentation](https://docs.php-http.org/en/latest/components/promise.html)from HTTPlug.

Set the number of retries
-------------------------

[](#set-the-number-of-retries)

You can specify the number of retries for any HTTP requests. This means if the HTTP request will fail the client will automatically try to perform another request (or more).

By default, the number of retries is zero (0). If you want you can change it using the `Transport::setRetries()`function, as follows:

```
use Elastic\Transport\TransportBuilder;

$transport = TransportBuilder::create()
    ->setHosts([
        '10.0.0.10:9200',
        '10.0.0.20:9200',
        '10.0.0.30:9200'
    ])
    ->build();

$transport->setRetries(1);
$factory = Psr17FactoryDiscovery::findRequestFactory();
$request = $factory->createRequest('GET', '/info');
// If a node is down, the transports retry automatically using another one
$response = $transport->sendRequest($request);
```

This feature can be interesting as retry mechanism especially useful if you have a cluster of nodes. You can read the following section about `Node Pool` to understand how to configure the selection of nodes in a cluster environment.

Node Pool
---------

[](#node-pool)

The `SimpleNodePool` is the default node pool algorithm used by `Tranposrt`. It uses the following default values: [RoundRobin](src/NodePool/Selector/RoundRobin.php) as `SelectorInterface` and [NoResurrect](src/NodePool/Resurrect/FalseResurrect.php) as `ResurrectInterface`.

The [Round-robin](https://en.wikipedia.org/wiki/Round-robin_scheduling) algorithm select the nodes in order, from the first node in the array to the latest. When arrived to the latest nodes, it will start again from the first.

\* **NOTE**: the order of the nodes is randomized at runtime to maximize the usage of all the hosts.

The [NoResurrect](src/NodePool/Resurrect/FalseResurrect.php) option does not try to resurrect the node that has been marked as dead. For instance, using `Elasticsearch` you can try to resurrect a dead node using the `HEAD /` API. If you want to use this behaviour you can use the [ElasticsearchResurrect](/src/NodePool/Resurrect/ElasticsearchResurrect.php) class.

Use a custom Selector
---------------------

[](#use-a-custom-selector)

You can specify a `SelectorInterface` implementation when you create a `NodePoolInterface` instance. For instance, imagine you implemented a `CustomSelector` and a custom `CustomResurrect` you can use it as follows:

```
use Elastic\Transport\NodePool\SimpleNodePool;
use Elastic\Transport\TransportBuilder;

$nodePool = new SimpleNodePool(
    new CustomSelector(),
    new CustomResurrect()
);

$transport = TransportBuilder::create()
    ->setHosts(['localhost:9200'])
    ->setNodePool($nodePool)
    ->build();
```

Use a custom PSR-3 loggers
--------------------------

[](#use-a-custom-psr-3-loggers)

You can specify a PSR-3 `LoggerInterface` implementation using the `TransportBuilder`. For instance, if you want to use [monolog](https://github.com/Seldaek/monolog) library you can use the following configuration:

```
use Elastic\Transport\TransportBuilder;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;

$logger = new Logger('name');
$logger->pushHandler(new StreamHandler('debug.log', Logger::DEBUG));

$transport = TransportBuilder::create()
    ->setHosts(['localhost:9200'])
    ->setLogger($logger)
    ->build();
```

Use a custom PSR-18 clients
---------------------------

[](#use-a-custom-psr-18-clients)

You can specify a `PSR-18` client using the `TransportBuilder::setClient()` function. For instance, if you want to use [Symfony HTTP Client](https://symfony.com/doc/current/http_client.html)you can use the following configuration:

```
use Elastic\Transport\TransportBuilder;
use Symfony\Component\HttpClient\Psr18Client;

$transport = TransportBuilder::create()
    ->setHosts(['localhost:9200'])
    ->setClient(new Psr18Client)
    ->build();
```

As mentioned in the introduction, we use the [HTTPlug](http://httplug.io/) library to automatic discovery a [PSR-18](https://www.php-fig.org/psr/psr-18/) client.

You can use the `TransportBuilder::setClient()` to specify the client manually, for instance if you have multiple HTTP client library installed.

By default, if the [PSR-18](https://www.php-fig.org/psr/psr-18/) client implements the [HttpAsyncClient](https://github.com/php-http/httplug/blob/master/src/HttpAsyncClient.php)it will use it when using `Transport::sendAsyncRequest()`. If you want you can override this setting using the `Transport::setAsyncClient()` function. That means you can use a [PSR-18](https://www.php-fig.org/psr/psr-18/) client for the syncronous requests and a different [HttpAsyncClient](https://github.com/php-http/httplug/blob/master/src/HttpAsyncClient.php)client for the asyncronous requests.

OpenTelemetry
-------------

[](#opentelemetry)

Starting from v8.9.0 we introduced the support of OpenTelemetry for the HTTP send request. Right now the support is only for syncronous HTTP call.

In order to enable the OpenTelemetry you need to set the ENV variable `OTEL_PHP_INSTRUMENTATION_ELASTICSEARCH_ENABLED` to true.

We added the support of OpenTelemetry natively in the `Transport:sendRequest()` function. By default, the Transport create a span from a Tracer provider (e.g. Global) with the following attributes:

```
http.request.method
url.full
server.address
server.port

```

We also added a `$opts` array as second optional parameter for the `Transport:sendRequest()`to pass additional attributes for OTel instrumentation.

We created an [OpenTelemetry](src/OpenTelemetry.php) class to provide all the configuration.

Copyright and License
---------------------

[](#copyright-and-license)

Copyright (c) [Elasticsearch B.V](https://www.elastic.co).

This software is licensed under the MIT License. Read the [LICENSE](LICENSE) file for more information.

###  Health Score

57

—

FairBetter than 98% of packages

Maintenance50

Moderate activity, may be stable

Popularity60

Solid adoption and visibility

Community33

Small or concentrated contributor base

Maturity73

Established project with proven stability

 Bus Factor1

Top contributor holds 95% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~52 days

Recently: every ~9 days

Total

30

Last Release

375d ago

Major Versions

v7.16.0 → v8.0.0-rc12022-02-17

v7.17.0 → v8.2.02022-06-22

7.17.x-dev → v8.3.02022-06-27

8.x-dev → 9.x-dev2025-04-09

PHP version history (4 changes)v7.12.0beta1PHP ^7.3|^8.0

v8.0.0-rc1PHP ^7.4|^8.0

v8.0.1PHP ^7.4 || ^8.0

9.x-devPHP ^8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/75c7c511421feb14316a01d29a7566bd4fdd97147b5a4f3faa5a065f9d0a0193?d=identicon)[ezimuel](/maintainers/ezimuel)

---

Top Contributors

[![ezimuel](https://avatars.githubusercontent.com/u/475967?v=4)](https://github.com/ezimuel "ezimuel (133 commits)")[![mikevrind](https://avatars.githubusercontent.com/u/594341?v=4)](https://github.com/mikevrind "mikevrind (2 commits)")[![itsgoingd](https://avatars.githubusercontent.com/u/821582?v=4)](https://github.com/itsgoingd "itsgoingd (1 commits)")[![ruudk](https://avatars.githubusercontent.com/u/104180?v=4)](https://github.com/ruudk "ruudk (1 commits)")[![shyim](https://avatars.githubusercontent.com/u/6224096?v=4)](https://github.com/shyim "shyim (1 commits)")[![marcing](https://avatars.githubusercontent.com/u/190209?v=4)](https://github.com/marcing "marcing (1 commits)")[![gjuric](https://avatars.githubusercontent.com/u/223015?v=4)](https://github.com/gjuric "gjuric (1 commits)")

---

Tags

httppsr-7psr-17psr-18elastictransport

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/elastic-transport/health.svg)

```
[![Health](https://phpackages.com/badges/elastic-transport/health.svg)](https://phpackages.com/packages/elastic-transport)
```

###  Alternatives

[phpro/http-tools

HTTP tools for developing more consistent HTTP implementations.

28137.8k](/packages/phpro-http-tools)[laudis/neo4j-php-client

Neo4j-PHP-Client is the most advanced PHP Client for Neo4j

184616.9k31](/packages/laudis-neo4j-php-client)[vultr/vultr-php

The Official Vultr API PHP Wrapper.

2243.9k1](/packages/vultr-vultr-php)[chillerlan/php-httpinterface

A PSR-7/17/18 http message/client implementation

1417.1k5](/packages/chillerlan-php-httpinterface)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

245.2k](/packages/aedart-athenaeum)[amphp/http-client-psr7

PSR-7 adapter for Amp's HTTP client.

1454.7k4](/packages/amphp-http-client-psr7)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
