// 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.
= Ignite for PHP

This chapter explains system requirements for running Ignite and how to install Ignite, start a cluster, and run a simple Hello World example using a thin client for PHP.

Thin Client is a lightweight Ignite connection mode.
It does not participate in cluster, never holds any data, or performs computations.
All it does is establish a socket connection to an individual Ignite node and perform all operations through that node.

== Prerequisites

Ignite was tested on:

include::includes/prereqs.adoc[]

and:

[cols="1,3"]
|=======================================================================
|PHP |Version 7.2 or higher and Composer Dependency Manager. PHP Multibyte String extension. Depending on your PHP configuration, you may need to additionally install/configure it.
|=======================================================================


== Installing Ignite

include::includes/install-ignite.adoc[]

Once that's done, go to `{IGNITE_HOME}/platforms/php` and install Ignite PHP Thin Client as a Composer package using the command below:

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

You're almost ready to run your first application.

== Starting a Node

Before connecting to Ignite from the PHP thin client, you must start at least one Ignite cluster node.

include::includes/starting-node.adoc[]

== Running Your First  Application

Once at least one node is started, you can use the Ignite PHP thin client to perform cache operations.
Your Ignite installation includes several ready-to-run PHP examples in the `{IGNITE_HOME}/platforms/php/examples` directory. For example,


[tabs]
--
tab:Unix[]
[source,shell]
----
cd {IGNITE_HOME}/platforms/php/examples
php CachePutGetExample.php
----

tab:Windows[]
[source,shell]
----
cd {IGNITE_HOME}\platforms\php\examples
php CachePutGetExample.php
----
--


Assuming that the server node is running locally, and that you have completed all of the pre-requisites listed above, here is a very simple _HelloWorld_ example that puts and gets values from the cache.
Note the `require_once` line — make sure the path is correct.
If you followed the instructions above, and if you place this hello world example in your examples folder, it should work.


[source,php]
----
<?php

require_once __DIR__ . '/../vendor/autoload.php';

use Apache\Ignite\Client;
use Apache\Ignite\ClientConfiguration;
use Apache\Ignite\Type\ObjectType;
use Apache\Ignite\Cache\CacheEntry;
use Apache\Ignite\Exception\ClientException;

function performCacheKeyValueOperations(): void
{
    $client = new Client();
    try {
        $client->connect(new ClientConfiguration('127.0.0.1:10800'));
        $cache = $client->getOrCreateCache('myCache')->
            setKeyType(ObjectType::INTEGER);

        // put and get value
        $cache->put(1, 'Hello World');
        $value = $cache->get(1);
        echo($value);
    } catch (ClientException $e) {
        echo($e->getMessage());
    } finally {
        $client->disconnect();
    }
}

performCacheKeyValueOperations();
----

== Next Steps

From here, you may want to:

* Read more about using  link:thin-clients/php-thin-client[PHP Thin Client]
//* Explore the link:https://github.com/gridgain/php-thin-client/tree/master/examples[additional examples] included with GridGain

