Official low-level client for Elasticsearch. Its goal is to provide common ground for all Elasticsearch-related code in PHP; because of this it tries to be opinion-free and very extendable.

Đang xem: A quick guide to using elasticsearch in php websites

To maintain consistency across all the low-level clients (Ruby, Python, etc.), clients accept simple associative arrays as parameters. All parameters, from the URI to the document body, are defined in the associative array.

Starting from version 7.4.0, all the endpoints (and namespaces) are autogenerated using the util/GenerateEndpoints.php script. This script reads the Elasticsearch API specs and generated the PHP classes for all the endpoints.

Starting from version 7.7.0 we included also the XPack endpoints of Elasticsearch. These APIs are related to:

Table of Contentselasticsearch-phpQuickstart Wrap upAvailable Licenses


One-to-one mapping with REST API and other language clientsConfigurable, automatic discovery of cluster nodesPersistent, Keep-Alive connections (within the lifetime of the script)Load balancing (with pluggable selection strategy) across all available nodes. Defaults to round-robinPluggable connection pools to offer different connection strategiesGeneralized, pluggable architecture – most components can be replaced with your own custom class if specialized behavior is requiredOption to use asynchronous future, which enables parallel execution of curl requests to multiple nodesNote: X-Pack endpoints are included from elasticsearch-php 7.7+.

Version Matrix

Elasticsearch VersionElasticsearch-PHP Branch
>= 7.x 7.x
>= 6.6, = 6.0, = 5.0, = 2.0, = 1.0,

If you are using Elasticsearch 7.x you can use use Elasticsearch-PHP 7.x branchIf you are using Elasticsearch 6.6 to 6.7, use Elasticsearch-PHP 6.7.x branch.If you are using Elasticsearch 6.0 to 6.5, use Elasticsearch-PHP 6.5.x branch.If you are using Elasticsearch 5.x, use Elasticsearch-PHP 5.0 branch.If you are using Elasticsearch 1.x or 2.x, prefer using the Elasticsearch-PHP 2.0 branch. The 1.0 branch is compatible however.If you are using a version older than 1.0, you must install the 0.4 Elasticsearch-PHP branch. Since ES 0.90.x and below is now EOL, the corresponding 0.4 branch will not receive any more development or bugfixes. Please upgrade.You should never use Elasticsearch-PHP Master branch, as it tracks Elasticsearch master and may contain incomplete features or breaks in backwards compatibility. Only use ES-PHP master if you are developing against ES master for some reason.


Full documentation can be found here. Docs are stored within the repo under /docs/, so if you see a typo or problem, please submit a PR to fix it!

We also provide a code examples generator for PHP using the util/GenerateDocExamples.php script. This command parse the util/alternative_report.spec.json file produced from this JSON specification and it generates the PHP examples foreach digest value. The examples are stored in asciidoc format under docs/examples folder.

Installation via Composer

The recommended method to install Elasticsearch-PHP is through Composer.

Add elasticsearch/elasticsearch as a dependency in your project”s composer.json file (change version to suit your version of Elasticsearch, for instance for ES 7.0):

Require Composer”s autoloader

Composer also prepares an autoload file that”s capable of autoloading all the classes in any of the libraries that it downloads. To use it, just add the following line to your code”s bootstrap process:

use ElasticsearchClientBuilder; require “vendor/autoload.php”; $client = ClientBuilder::create()->build();
You can find out more on how to install Composer, configure autoloading, and other best-practices for defining dependencies at

PHP Version Requirement

Version 7.0 of this library requires at least PHP version 7.1. In addition, it requires the native JSON extension to be version 1.3.7 or higher.

Elasticsearch-PHP BranchPHP Version
7.0 >= 7.1.0
6.0 >= 7.0.0
5.0 >= 5.6.6
2.0 >= 5.4.0
0.4, 1.0 >= 5.3.9


Index a document

In elasticsearch-php, almost everything is configured by associative arrays. The REST endpoint, document and optional parameters – everything is an associative array.

To index a document, we need to specify three pieces of information: index, id and a document body. This is done by constructing an associative array of key:value pairs. The request body is itself an associative array with key:value pairs corresponding to the data in your document:

$params = < "index" => “my_index”, “id” => “my_id”, “body” => <"testField" => “abc”>>;$response = $client->index($params);print_r($response);
The response that you get back indicates the document was created in the index that you specified. The response is an associative array containing a decoded version of the JSON that Elasticsearch returns:

Array( <_index> => my_index <_type> => _doc <_id> => my_id <_version> => 1 => created <_shards> => Array ( => 1 => 1 => 0 ) <_seq_no> => 0 <_primary_term> => 1)

$params = < "index" => “my_index”, “id” => “my_id”>;$response = $client->get($params);print_r($response);
The response contains some metadata (index, version, etc.) as well as a _source field, which is the original document that you sent to Elasticsearch.

Array( <_index> => my_index <_type> => _doc <_id> => my_id <_version> => 1 <_seq_no> => 0 <_primary_term> => 1 => 1 <_source> => Array ( => abc ))

$params = < "index" => “my_index”, “id” => “my_id”>;$source = $client->getSource($params);print_r($source);

Search for a document

Searching is a hallmark of Elasticsearch, so let”s perform a search. We are going to use the Match query as a demonstration:

$params = < "index" => “my_index”, “body” => < "query" => < "match" => < "testField" => “abc” > > >>;$response = $client->search($params);print_r($response);
The response is a little different from the previous responses. We see some metadata (took, timed_out, etc.) and an array named hits. This represents your search results. Inside of hits is another array named hits, which contains individual search results:

Array( => 33 => <_shards> => Array ( => 1 => 1 => 0 => 0 ) => Array ( => Array ( => 1 => eq ) => 0.2876821 => Array ( <0> => Array ( <_index> => my_index <_type> => _doc <_id> => my_id <_score> => 0.2876821 <_source> => Array ( => abc ) ) ) ))

$params = < "index" => “my_index”, “id” => “my_id”>;$response = $client->delete($params);print_r($response);
You”ll notice this is identical syntax to the get syntax. The only difference is the operation: delete instead of get. The response will confirm the document was deleted:

Array( <_index> => my_index <_type> => _doc <_id> => my_id <_version> => 2 => deleted <_shards> => Array ( => 1 => 1 => 0 ) <_seq_no> => 1 <_primary_term> => 1)

Delete an index

Due to the dynamic nature of Elasticsearch, the first document we added automatically built an index with some default settings. Let”s delete that index because we want to specify our own settings later:

$deleteParams = < "index" => “my_index”>;$response = $client->indices()->delete($deleteParams);print_r($response);

Create an index

Now that we are starting fresh (no data or index), let”s add a new index with some custom settings:

$params = < "index" => “my_index”, “body” => < "settings" => < "number_of_shards" => 2, “number_of_replicas” => 0 > >>;$response = $client->indices()->create($params);print_r($response);
use GuzzleHttpRingClientMockHandler;use ElasticsearchClientBuilder;// The connection class requires “body” to be a file stream handle// Depending on what kind of request you do, you may need to set more values here$handler = new MockHandler(< "status" => 200, “transfer_stats” => < "total_time" => 100 >, “body” => fopen(“somefile.json”), “effective_url” => “localhost”>);$builder = ClientBuilder::create();$builder->setHosts(<"somehost">);$builder->setHandler($handler);$client = $builder->build();// Do a request and you”ll get back the “body” response above
ContributingIf you want to contribute to this project you need to subscribe a Contributor Agreement. If you want to send a PR for version Y please use the Y.x branch. For instance if you want to send a PR for elasticsearch-php 7 use the 7.x branch.

Never send PR to master unless you want to contribute to the development version of the client (master represents the next major version).

Each PR should include a unit test using PHPUnit. If you are not familiar with PHPUnit you can have a look at this reference.

Wrap upThat was just a crash-course overview of the client and its syntax. If you are familiar with Elasticsearch, you”ll notice that the methods are named just like REST endpoints.

You”ll also notice that the client is configured in a manner that facilitates easy discovery via the IDE. All core actions are available under the $client object (indexing, searching, getting, etc.). Index and cluster management are located under the $client->indices() and $client->cluster() objects, respectively.

Check out the rest of the Documentation to see how the entire client works.

Available Licenses

Starting with version 1.3.1, Elasticsearch-PHP is available under two licenses: Apache v2.0 and LGPL v2.1. Versions prior to 1.3.1 are still licensed with only Apache v2.0.

The user may choose which license they wish to use. Since there is no discriminating executable or distribution bundle to differentiate licensing, the user should document their license choice externally, in case the library is re-distributed. If no explicit choice is made, assumption is that redistribution obeys rules of both licenses.


All contributions to the library are to be so that they can be licensed under both licenses.

Apache v2.0 License:

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

LGPL v2.1 Notice:

This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.

Xem thêm: Cách Sửa Lỗi Font Chữ Ô Vuông, Dấu Hỏi Trong Word, Cách Sửa Lỗi Font Chữ Trong Word 2003, 2007, 2010

This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA



My name is Austin Harmon and I am new to elastic search. I am looking to index a couple hundred thousand documents with elastic search and I would like to use the php client to do it. I have my index set up with one shard and one replica since I have a smaller amount of documents. I have looked over all the syntax on the elastic search site and github.This is what my index.php file looks like:

array(“index” => “rvuehistoricaldocuments2009-2013″,”type” => “documents”,”_id” => $i,”body” => array(“_source” => array( //everthing in body is mapping code”enabled” => true),”properties” => array(“doc_name” => array(“type” => “string”,”analyzer” => “standard”),”description” => array(“type” => “string”)));$params<"body"><> = array (“rVuedoc”$i => “ID”$i);$indexParams<"body"><"mappings"><"documents"> = $myTypeMapping; //mapping code}json_encode($params);$client->indices()->create($indexParams); //mapping code$responses = $client->bulk($params);“`?>

I”m not sure if I have everything I need or if I”m doing this right so if you could let me know if this looks correct that would be very helpful.

Thank you,Austin Harmon

Summary of problem or feature request

I am using the search feature of elastic search but this error is coming out while running my files on localhost.

my configuration code:

use ElasticsearchClientBuilder;

require “vendor/autoload.php”;$client = ElasticsearchClientBuilder::create()->build();

the error while sending a query for search :

Fatal error: Uncaught ElasticsearchCommonExceptionsNoNodesAvailableException: No alive nodes found in your cluster in C:xampphtdocselasticvendorelasticsearchelasticsearchsrcElasticsearchConnectionPoolStaticNoPingConnectionPool.php:51 Stack trace: #0 C:xampphtdocselasticvendorelasticsearchelasticsearchsrcElasticsearchTransport.php(72): ElasticsearchConnectionPoolStaticNoPingConnectionPool->nextConnection() #1 C:xampphtdocselasticvendorelasticsearchelasticsearchsrcElasticsearchTransport.php(90): ElasticsearchTransport->getConnection() #2 C:xampphtdocselasticvendorelasticsearchelasticsearchsrcElasticsearchConnectionsConnection.php(227): ElasticsearchTransport->performRequest(“GET”, “/1/books/_searc…”, Array, “{“query”:{“matc…”, Array) #3 C:xampphtdocselasticvendor
eactpromisesrcFulfilledPromise.php(25): ElasticsearchConnectionsConnection->ElasticsearchConnections{closure}(Array) #4 C:xampphtdocselasticvendorguzzlehttp in C:xampphtdocselasticvendorelasticsearchelasticsearchsrcElasticsearchConnectionPoolStaticNoPingConnectionPool.php on line 51

please help me fix this problem. I am using localhost through XAMPP.

Operating System – windowsPHP Version – 7ES-PHP client version – v5.0Elasticsearch version – v5.0

Summary of problem or feature request

I can see that in v.7 the port has disappeared from the host. After further digging I see it”s been specifically requested and fixed in &

Perhaps it is a valid use case (although I don”t really understand it), but the change seems to be causing problems elsewhere – now the port is missing from the log messages too.

Code snippet of problem

Here is an example of what is sent to the logger now:

curl -XDELETE “”But of course this doesn”t work, as it”s trying to reach port 80, instead of 9200

I use elasticsearch v 5.5.2 with laravel 5.3 – scout v -2.0.I a trying to executing below code but I am getting this error. NoNodesAvailableException.

namespace AppHttpControllers;use IlluminateHttpRequest;use ElasticsearchClientBuilder;use ElasticaClient as ElasticaClient;class clientController extends Controller{ protected $elasticsearch; protected $elastica; public function __construct() { $this->elasticsearch = ClientBuilder::create() //->setConnectionPool(“ElasticsearchConnectionPoolSniffingConnectionPool”, <>) ->build(); $elasticConfig=<"host"=>“locahost”, “port”=>9200, “index”=>”pets”>; $this->elastica = new ElasticaClient($elasticConfig); } public function elasticsearchTest(){ $param = < "index" => “pets”, “type” => “dog”, “id”=>”1” >; $res = $this->elasticsearch->get($param); dump($res); }}NoNodesAvailableException in StaticNoPingConnectionPool.php line 51: No alive nodes found in your clusterIt”s working fine in sense. Result:

{ “_index”: “pets”, “_type”: “dog”, “_id”: “1”, “_version”: 1, “found”: true, “_source”: { “name”: “tommy”, “age”: “3”, “color”: “black”, “gender”: “male” }}Also working on http://localhost:9200/pets/dog/1. Result:

{“_index”:”pets”,”_type”:”dog”,”_id”:”1″,”_version”:1,”found”:true,”_source”:{ “name”:”tommy”, “age”:”3″, “color”:”black”, “gender”:”male”}}I also post this on stackover flow but no response.

I am receiving the following error when trying to use the DELETE API.

Elasticsearch\Common\Exceptions\TransportException”,”message”:”SSL certificate problem: self signed certificate in certificate chain”,”file”:”pathto/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Connections/AbstractConnection.php”,”line”:312

in my config file I am setting the verification to false. this is working for everything except delete.

update:I have done some research and it seems that the curl_opt – CURLOPT_SSL_VERIFYPEER is not getting set to false, is there a way to pass this using a config file to the elastic search client?


I”d like to request an update/clarification to about the PHP versions supported.


The table doesn”t use semver (and it shouldn”t necessarily), but >= 7.0.0 and >= 7.1.0 would suggest to me that ES-PHP 6.0 and 7.0 technically support PHP 8.0, (which is obviously out now as a stable release!) but it doesn”t, and can be confirmed by looking at which as ^7.0 and which has ^7.1. And ^7.0 basically means >=7.0.0 etc.

Anything we can do for clarification? As I”m sure there are going to be people coming along and thinking PHP 8 should work…


Summary of problem or feature request

When a list of multiple hosts is configured, randomizeHosts is disabled and StickyRoundRobinSelector is used the first connection goes to the second host (instead to the first one).

e.g. hosts:


Are tried in this order: host2, host3, host4, host1

Code snippet of problem

From StickyRoundRobinSelector::select():

if ($connections<$this->current>->isAlive()) { return $connections<$this->current>; } Because the first connection is not alive (yet), the first connection is skipped first time when select() is called.

System details

elasticsearch-php v7.10.0

Summary of problem or feature request

ClientBuilder::build() adds an Accept-Encoding:gzip header when elasticCloudId is provided but does not handle decompression of gzip compressed responses.

We”re using SymfonyComponentHttpClientHttplugClient as asyncHttpClient which adds gzip by default but does not handle decoding when the Accept-Encoding header is explicitly set.

As per Symfony HTTPClient maintainer:

you explicitly send the request with the “accept-encoding” header. When you do this, you disable transparent compression and you opt-in for explicit compression, which means it”s now your job to effectively decompress.Don”t send the header if that”s not what you want.

Thus the Elastic Client should either handle decompressen (and check whether the required zlib PHP extension is loaded) or the Elastic Client should leave responsibility for decompression to the PsrHttpClientClientInterface implementation and not set the header at all, we prefer the latter.

Code snippet of problem

if (!empty($this->cloudId)) { $transport->setHeader(“Accept-Encoding”, “gzip”);}And in Symfony HTTPClient:

$this->inflate = !isset($options<"normalized_headers"><"accept-encoding">); // This prevents decompression

System details

PHP version: 8.1.8ES-PHP client version: 8.3.2Elasticsearch version: 7.15.2

Summary of problem or feature request

When using symfony/dotenv to provide enviornment variables, this does not use putenv as putenv is not thread safe

However, if one uses getenv instead of $_SERVER and $_ENV the use of putenv is required. Which would not be thread safe. Or it needs to be provided outside PHP but in case of multiple threads using different environment variables it still would not work.

So instead of using getenv (or just getenv), $_SERVER and $_ENV should be used. This way it would also work with symfony/dotenv in default configuration (putenv is disabled).

Normally, $_SERVER<"ELASTIC_CLIENT_APIVERSIONING"> ?? $_ENV<"ELASTIC_CLIENT_APIVERSIONING"> should be able to target all set environment variables. Optionally, a third fallback could be getenv.

Xem thêm: Sửa Lỗi Quạt Máy Tính Kêu To P Quạt Kêu To & Rè Rè Bất Thường

It would be a simple change and it would be thread safe and still works everywhere.

System details

Operating SystemPHP Version 8.1ES-PHP client version 7.17.0Elasticsearch version 7.14

Related Post

Leave a Reply

Your email address will not be published. Required fields are marked *