1<img align="right" width="auto" height="auto" src="https://www.elastic.co/static-res/images/elastic-logo-200.png"/> 2 3elasticsearch-php 4================= 5 6[](https://github.com/elastic/elasticsearch-php/actions) [](https://packagist.org/packages/elasticsearch/elasticsearch) [](https://packagist.org/packages/elasticsearch/elasticsearch) 7 8Official 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. 9 10To 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. 11 12Starting from version `7.4.0`, all the endpoints (and namespaces) are autogenerated using the [util/GenerateEndpoints.php](https://github.com/elastic/elasticsearch-php/blob/master/util/GenerateEndpoints.php) script. This script reads the [Elasticsearch API specs](https://github.com/elastic/elasticsearch/tree/master/rest-api-spec/src/main/resources/rest-api-spec/api) and generated the PHP classes for all the endpoints. 13 14Starting from version `7.7.0` we included also the [XPack endpoints](https://www.elastic.co/what-is/open-x-pack) of Elasticsearch. 15These APIs are related to: 16 17- [Cross-cluster replication](https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-apis.html) 18- [Graph explorer](https://www.elastic.co/guide/en/elasticsearch/reference/current/graph-explore-api.html) 19- [Info](https://www.elastic.co/guide/en/elasticsearch/reference/current/info-api.html) 20- [Licensing](https://www.elastic.co/guide/en/elasticsearch/reference/current/licensing-apis.html) 21- [Machine learning anomaly detection](https://www.elastic.co/guide/en/elasticsearch/reference/current/ml-apis.html) 22- [Machine learning data frame analytics](https://www.elastic.co/guide/en/elasticsearch/reference/current/ml-df-analytics-apis.html) 23- [Migration](https://www.elastic.co/guide/en/elasticsearch/reference/current/migration-api.html) 24- [Reload search analyzers](https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-reload-analyzers.html) 25- [Rollup](https://www.elastic.co/guide/en/elasticsearch/reference/current/rollup-apis.html) 26- [Security](https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api.html) 27- [Snapshot lifecycle management](https://www.elastic.co/guide/en/elasticsearch/reference/current/snapshot-lifecycle-management-api.html) 28- [Transform](https://www.elastic.co/guide/en/elasticsearch/reference/current/transform-apis.html) 29- [Usage](https://www.elastic.co/guide/en/elasticsearch/reference/current/usage-api.html) 30- [Watcher](https://www.elastic.co/guide/en/elasticsearch/reference/current/watcher-api.html) 31 32Table of Contents 33================= 34 35- [elasticsearch-php](#elasticsearch-php) 36 * [Features](#features) 37 * [Version Matrix](#version-matrix) 38 * [Compatibility](#compatibility) 39 * [Documentation](#documentation) 40 * [Installation via Composer](#installation-via-composer) 41 * [PHP Version Requirement](#php-version-requirement) 42 * [Quickstart](#quickstart) 43 + [Index a document](#index-a-document) 44 + [Get a document](#get-a-document) 45 + [Search for a document](#search-for-a-document) 46 + [Delete a document](#delete-a-document) 47 + [Delete an index](#delete-an-index) 48 + [Create an index](#create-an-index) 49- [Unit Testing using Mock a Elastic Client](#unit-testing-using-mock-a-elastic-client) 50- [Contributing](#contributing) 51- [Wrap up](#wrap-up) 52 * [Available Licenses](#available-licenses) 53 + [Contributions](#contributions) 54 55Features 56-------- 57 58 - One-to-one mapping with REST API and other language clients 59 - Configurable, automatic discovery of cluster nodes 60 - Persistent, Keep-Alive connections (within the lifetime of the script) 61 - Load balancing (with pluggable selection strategy) across all available nodes. Defaults to round-robin 62 - Pluggable connection pools to offer different connection strategies 63 - Generalized, pluggable architecture - most components can be replaced with your own custom class if specialized behavior is required 64 - Option to use asynchronous future, which enables parallel execution of curl requests to multiple nodes 65 66 67**Note:** [X-Pack](https://www.elastic.co/what-is/open-x-pack) endpoints are included from elasticsearch-php 7.7+. 68 69 70Version Matrix 71-------------- 72 73| Elasticsearch-PHP Branch | PHP Version | 74| ----------- | ------------------------ | 75| >= 7.16.0, < 8.0.0 | >= 7.3.0, <= 8.1.99 | 76| >= 7.12.0, < 8.0.0 | >= 7.3.0, <= 8.0.99 | 77| >= 7.11.0, < 8.0.0 | >= 7.1.0, <= 8.0.99 | 78| >= 7.0.0, < 7.11.0 | >= 7.1.0, < 8.0.0 | 79| 6.x | >= 7.0.0, < 8.0.0 | 80| 5.x | >= 5.6.6, < 8.0.0 | 81| 2.x | >= 5.4.0, < 7.0.0 | 82| 0.4, 1.x | >= 5.3.9, < 7.0.0 | 83 84 - If you are using Elasticsearch 7.x, you can use Elasticsearch-PHP 7.x branch. 85 - If you are using Elasticsearch 6.x, you can use Elasticsearch-PHP 6.x branch. 86 - If you are using Elasticsearch 5.x, you can use Elasticsearch-PHP 6.x branch. 87 - 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. 88 - 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. 89 - 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. 90 91Compatibility 92------------- 93 94Language clients are forward compatible; meaning that clients support communicating 95with greater minor versions of Elasticsearch. Elastic language clients are also backwards 96compatible with lesser supported minor Elasticsearch versions. 97 98Documentation 99-------------- 100[Full documentation can be found here.](https://www.elastic.co/guide/en/elasticsearch/client/php-api/current/index.html) Docs are stored within the repo under /docs/, so if you see a typo or problem, please submit a PR to fix it! 101 102We also provide a code examples generator for PHP using the `util/GenerateDocExamples.php` script. This command parses the `util/alternative_report.spec.json` file produced from this [JSON specification](https://raw.githubusercontent.com/elastic/built-docs/master/raw/en/elasticsearch/reference/master/alternatives_report.json) and it generates the PHP examples for each digest value. 103The examples are stored in asciidoc format under `docs/examples` folder. 104 105Installation via Composer 106------------------------- 107The recommended method to install _Elasticsearch-PHP_ is through [Composer](http://getcomposer.org). 108 1091. 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): 110 111 ```json 112 { 113 "require": { 114 "elasticsearch/elasticsearch": "^7.0" 115 } 116 } 117 ``` 118 1192. Download and install Composer: 120 121 ```bash 122 curl -s http://getcomposer.org/installer | php 123 ``` 124 1253. Install your dependencies: 126 127 ```bash 128 php composer.phar install 129 ``` 130 1314. Require Composer's autoloader 132 133 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: 134 135 ```php 136 <?php 137 138 use Elasticsearch\ClientBuilder; 139 140 require 'vendor/autoload.php'; 141 142 $client = ClientBuilder::create()->build(); 143 ``` 144 145You can find out more on how to install Composer, configure autoloading, and other best-practices for defining dependencies at [getcomposer.org](http://getcomposer.org). 146 147PHP Version Requirement 148---- 149Version 7.0 of this library requires at least PHP version 7.1. In addition, it requires the native JSON 150extension to be version 1.3.7 or higher. 151 152| Elasticsearch-PHP Branch | PHP Version | 153| ----------- | ------------------------ | 154| 7.0 | >= 7.1.0 | 155| 6.0 | >= 7.0.0 | 156| 5.0 | >= 5.6.6 | 157| 2.0 | >= 5.4.0 | 158| 0.4, 1.0 | >= 5.3.9 | 159 160 161Quickstart 162---- 163 164 165### Index a document 166 167In elasticsearch-php, almost everything is configured by associative arrays. The REST endpoint, document and optional parameters - everything is an associative array. 168 169To index a document, we need to specify three pieces of information: index, id and a document body. This is done by 170constructing an associative array of key:value pairs. The request body is itself an associative array with key:value pairs 171corresponding to the data in your document: 172 173```php 174$params = [ 175 'index' => 'my_index', 176 'id' => 'my_id', 177 'body' => ['testField' => 'abc'] 178]; 179 180$response = $client->index($params); 181print_r($response); 182``` 183 184The response that you get back indicates the document was created in the index that you specified. The response is an 185associative array containing a decoded version of the JSON that Elasticsearch returns: 186 187```php 188Array 189( 190 [_index] => my_index 191 [_type] => _doc 192 [_id] => my_id 193 [_version] => 1 194 [result] => created 195 [_shards] => Array 196 ( 197 [total] => 1 198 [successful] => 1 199 [failed] => 0 200 ) 201 202 [_seq_no] => 0 203 [_primary_term] => 1 204) 205``` 206 207### Get a document 208 209Let's get the document that we just indexed. This will simply return the document: 210 211```php 212$params = [ 213 'index' => 'my_index', 214 'id' => 'my_id' 215]; 216 217$response = $client->get($params); 218print_r($response); 219``` 220 221The response contains some metadata (index, version, etc.) as well as a `_source` field, which is the original document 222that you sent to Elasticsearch. 223 224```php 225Array 226( 227 [_index] => my_index 228 [_type] => _doc 229 [_id] => my_id 230 [_version] => 1 231 [_seq_no] => 0 232 [_primary_term] => 1 233 [found] => 1 234 [_source] => Array 235 ( 236 [testField] => abc 237 ) 238 239) 240``` 241 242If you want to retrieve the `_source` field directly, there is the `getSource` method: 243 244```php 245$params = [ 246 'index' => 'my_index', 247 'id' => 'my_id' 248]; 249 250$source = $client->getSource($params); 251print_r($source); 252``` 253 254The response will be just the `_source` value: 255 256```php 257Array 258( 259 [testField] => abc 260) 261``` 262 263### Search for a document 264 265Searching is a hallmark of Elasticsearch, so let's perform a search. We are going to use the Match query as a demonstration: 266 267```php 268$params = [ 269 'index' => 'my_index', 270 'body' => [ 271 'query' => [ 272 'match' => [ 273 'testField' => 'abc' 274 ] 275 ] 276 ] 277]; 278 279$response = $client->search($params); 280print_r($response); 281``` 282 283The response is a little different from the previous responses. We see some metadata (`took`, `timed_out`, etc.) and 284an array named `hits`. This represents your search results. Inside of `hits` is another array named `hits`, which contains 285individual search results: 286 287```php 288Array 289( 290 [took] => 33 291 [timed_out] => 292 [_shards] => Array 293 ( 294 [total] => 1 295 [successful] => 1 296 [skipped] => 0 297 [failed] => 0 298 ) 299 300 [hits] => Array 301 ( 302 [total] => Array 303 ( 304 [value] => 1 305 [relation] => eq 306 ) 307 308 [max_score] => 0.2876821 309 [hits] => Array 310 ( 311 [0] => Array 312 ( 313 [_index] => my_index 314 [_type] => _doc 315 [_id] => my_id 316 [_score] => 0.2876821 317 [_source] => Array 318 ( 319 [testField] => abc 320 ) 321 322 ) 323 324 ) 325 326 ) 327 328) 329``` 330 331### Delete a document 332 333Alright, let's go ahead and delete the document that we added previously: 334 335```php 336$params = [ 337 'index' => 'my_index', 338 'id' => 'my_id' 339]; 340 341$response = $client->delete($params); 342print_r($response); 343``` 344 345You'll notice this is identical syntax to the `get` syntax. The only difference is the operation: `delete` instead of 346`get`. The response will confirm the document was deleted: 347 348```php 349Array 350( 351 [_index] => my_index 352 [_type] => _doc 353 [_id] => my_id 354 [_version] => 2 355 [result] => deleted 356 [_shards] => Array 357 ( 358 [total] => 1 359 [successful] => 1 360 [failed] => 0 361 ) 362 363 [_seq_no] => 1 364 [_primary_term] => 1 365) 366``` 367 368 369### Delete an index 370 371Due 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: 372 373```php 374$deleteParams = [ 375 'index' => 'my_index' 376]; 377$response = $client->indices()->delete($deleteParams); 378print_r($response); 379``` 380 381The response: 382 383 384```php 385Array 386( 387 [acknowledged] => 1 388) 389``` 390 391### Create an index 392 393Now that we are starting fresh (no data or index), let's add a new index with some custom settings: 394 395```php 396$params = [ 397 'index' => 'my_index', 398 'body' => [ 399 'settings' => [ 400 'number_of_shards' => 2, 401 'number_of_replicas' => 0 402 ] 403 ] 404]; 405 406$response = $client->indices()->create($params); 407print_r($response); 408``` 409 410Elasticsearch will now create that index with your chosen settings, and return an acknowledgement: 411 412```php 413Array 414( 415 [acknowledged] => 1 416) 417``` 418 419Unit Testing using Mock a Elastic Client 420======================================== 421```php 422use GuzzleHttp\Ring\Client\MockHandler; 423use Elasticsearch\ClientBuilder; 424 425// The connection class requires 'body' to be a file stream handle 426// Depending on what kind of request you do, you may need to set more values here 427$handler = new MockHandler([ 428 'status' => 200, 429 'transfer_stats' => [ 430 'total_time' => 100 431 ], 432 'body' => fopen('somefile.json'), 433 'effective_url' => 'localhost' 434]); 435$builder = ClientBuilder::create(); 436$builder->setHosts(['somehost']); 437$builder->setHandler($handler); 438$client = $builder->build(); 439// Do a request and you'll get back the 'body' response above 440``` 441 442Contributing 443============ 444 445If you want to contribute to this project you need to subscribe to a [Contributor Agreement](https://www.elastic.co/contributor-agreement). 446If 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. 447 448Never send PR to `master` unless you want to contribute to the development version of the client (`master` represents the next major version). 449 450Each PR should include a **unit test** using [PHPUnit](https://phpunit.de/). If you are not familiar with PHPUnit you can have a look at this [reference](https://phpunit.readthedocs.io/en/7.0/). 451 452Wrap up 453======= 454 455That 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. 456 457You'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. 458 459Check out the rest of the [Documentation](https://www.elastic.co/guide/en/elasticsearch/client/php-api/current/index.html) to see how the entire client works. 460 461 462Available Licenses 463------- 464 465Starting with version 1.3.1, Elasticsearch-PHP is available under two licenses: Apache v2.0 and LGPL v2.1. Versions 466prior to 1.3.1 are still licensed with only Apache v2.0. 467 468The user may choose which license they wish to use. Since there is no discriminating executable or distribution bundle 469to differentiate licensing, the user should document their license choice externally, in case the library is re-distributed. 470If no explicit choice is made, assumption is that redistribution obeys rules of both licenses. 471 472### Contributions 473All contributions to the library are to be so that they can be licensed under both licenses. 474 475Apache v2.0 License: 476>Copyright 2013-2016 Elasticsearch 477> 478>Licensed under the Apache License, Version 2.0 (the "License"); 479>you may not use this file except in compliance with the License. 480>You may obtain a copy of the License at 481> 482> http://www.apache.org/licenses/LICENSE-2.0 483> 484>Unless required by applicable law or agreed to in writing, software 485>distributed under the License is distributed on an "AS IS" BASIS, 486>WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 487>See the License for the specific language governing permissions and 488>limitations under the License. 489 490LGPL v2.1 Notice: 491>Copyright (C) 2013-2016 Elasticsearch 492> 493>This library is free software; you can redistribute it and/or 494>modify it under the terms of the GNU Lesser General Public 495>License as published by the Free Software Foundation; either 496>version 2.1 of the License, or (at your option) any later version. 497> 498>This library is distributed in the hope that it will be useful, 499>but WITHOUT ANY WARRANTY; without even the implied warranty of 500>MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 501>Lesser General Public License for more details. 502> 503>You should have received a copy of the GNU Lesser General Public 504>License along with this library; if not, write to the Free Software 505>Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 506