// 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 Quick Start Guide 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, install PHP Thin Client as a Composer package using the command below:

include::includes/install-php-composer.adoc[]

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 `{client_dir}/examples` directory.
Here is example how to run one of them:


[tabs]
--
tab:Unix[]
[source,shell]
----
cd {client_dir}/examples
php CachePutGetExample.php
----
tab:Windows[]
[source,shell]
----
cd {client_dir}\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/apache/ignite-php-thin-client/tree/master/examples[additional examples] included with GridGain

