// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements.  See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You 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
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// 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.
= PHP Thin Client

== Prerequisites
* link:http://php.net/manual/en/install.php[PHP version 7.2 or higher,window=_blank] and link:https://getcomposer.org/download[Composer Dependency Manager,window=_blank]
* php-xml module
* link:http://php.net/manual/en/mbstring.installation.php[PHP Multibyte String extension].
Depending on your PHP configuration, you may need to additionally install/configure it.

== Installation

The thin client can be installed from the zip archive:

*  Download the link:https://ignite.apache.org/download.cgi#binaries[Apache Ignite binary package,window=_blank].
*  Unpack the archive and navigate to the `{IGNITE_HOME}/platforms/php` folder.
*  Use the command below to install the package.

[source,shell]
----
composer install --no-dev
----

To use the client in your application, include the `vendor/autoload.php` file, generated by Composer, to your source code.

[source,php]
----
require_once "<php_client_root_dir>/vendor/autoload.php";
----

== Creating a Client Instance
All operations of the PHP thin client are performed through a `Client` instance. You can create as many `Client` instances
as needed. All of them will work independently.

[source, php]
----
use Apache\Ignite\Client;

$client = new Client();
----

== Connecting to Cluster

To connect to a cluster, define a `ClientConfiguration` object with the desired connection parameters and use the `Client.connect(...)` method.

[source, php]
----
include::code-snippets/php/ConnectingToCluster.php[tag=connecting,indent=0]
----

The `ClientConfiguration` constructor accepts a list of node endpoints. At least one endpoint must be specified. If you specify more than one, the thin client will use them for link:thin-clients/getting-started-with-thin-clients#client-connection-failover[failover purposes].

If the client cannot connect to the cluster, a `NoConnectionException`  is thrown when attempting to perform any remote operation.

If the client unexpectedly loses the connection before or during an operation, an `OperationStatusUnknownException` is thrown.
In this case, it is not known if the operation has been actually executed in the cluster or not.
The client will try to reconnect to the next node specified in the configuration when the next operation is called by the application.

Call the `disconnect()` method to close the connection.


== Using Key-Value API

=== Getting/Creating a Cache Instance

The client instance provides three methods for obtaining an instance of a cache:

* `getCache(name)` — returns an existing cache by name. The method does not verify if the cache exists in the cluster; instead, you will get an exception when attempting to perform any operation with the cache.
* `getOrCreateCache(name, config)` — returns an existing cache by name or creates a cache with the given configuration.
* `createCache(name, config)` — creates a cache with the given name and parameters.

This is how you can create a cache:

[source, php]
----
include::code-snippets/php/UsingKeyValueApi.php[tag=createCache,indent=0]
----

=== Basic Key-Value Operations

The following code snippet illustrates how to perform basic key-value operations with a cache instance:

[source, php]
----
include::code-snippets/php/UsingKeyValueApi.php[tag=basicOperations,indent=0]
----

////
TODO
=== Asynchronous Execution
////


== Scan Queries
The `Cache.query(ScanQuery)` method can be used to fetch all entries from the cache. It returns a cursor object with the standard PHP Iterator interface — use this cursor to iterate over the result set lazily, one by one. In addition, the cursor has methods to get all results at once.

////
*TODO: illustrate how to use the iterator in the example*
////

[source, php]
----
include::code-snippets/php/UsingKeyValueApi.php[tag=scanQry,indent=0]
----

== Executing SQL Statements
The PHP thin client supports all link:sql-reference[SQL commands] that are supported by Ignite.
The commands are executed via the `query(SqlFieldQuery)` method of the cache object.
The method accepts an instance of `SqlFieldsQuery` that represents a SQL statement.
The `query()` method returns a cursor object with the standard PHP Iterator interface — use this cursor to iterate over the result set lazily, one by one. In addition, the cursor has methods to get all results at once.

[source, php]
----
include::code-snippets/php/UsingKeyValueApi.php[tag=executingSql,indent=0]
----

== Security

=== SSL/TLS
To use encrypted communication between the thin client and the cluster, you have to enable it both in the cluster configuration and the client configuration. Refer to the link:thin-clients/getting-started-with-thin-clients#enabling-ssltls-for-thin-clients[Enabling SSL/TLS for Thin Clients] section for the instruction on the cluster configuration.

Here is an example configuration for enabling SSL in the thin client:
[source, php]
----
include::code-snippets/php/Security.php[tag=tls,indent=0]
----

=== Authentication
Configure link:security/authentication[authentication on the cluster side] and provide a valid user name and password in the client configuration.

[source, php]
----
include::code-snippets/php/Security.php[tag=authentication,indent=0]
----



