You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by is...@apache.org on 2018/10/09 14:42:55 UTC

[6/9] ignite git commit: IGNITE-7783: PHP thin client

http://git-wip-us.apache.org/repos/asf/ignite/blob/7d3ea115/modules/platforms/php/src/Apache/Ignite/Cache/CacheKeyConfiguration.php
----------------------------------------------------------------------
diff --git a/modules/platforms/php/src/Apache/Ignite/Cache/CacheKeyConfiguration.php b/modules/platforms/php/src/Apache/Ignite/Cache/CacheKeyConfiguration.php
new file mode 100644
index 0000000..cbbc249
--- /dev/null
+++ b/modules/platforms/php/src/Apache/Ignite/Cache/CacheKeyConfiguration.php
@@ -0,0 +1,107 @@
+<?php
+/*
+ * 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.
+ */
+
+namespace Apache\Ignite\Cache;
+
+use Apache\Ignite\Internal\Binary\BinaryCommunicator;
+use Apache\Ignite\Internal\Binary\MessageBuffer;
+
+/**
+ * Class representing Cache Key part of Ignite CacheConfiguration.
+ *
+ * All configuration settings are optional and have defaults which are defined on a server side.
+ *
+ * See Apache Ignite documentation for details of every configuration setting.
+ */
+class CacheKeyConfiguration
+{
+    private $typeName;
+    private $affinityKeyFieldName;
+
+    /**
+     * CacheKeyConfiguration constructor.
+     *
+     * @param string|null $typeName
+     * @param string|null $affinityKeyFieldName
+     */
+    public function __construct(string $typeName = null, string $affinityKeyFieldName = null)
+    {
+        $this->typeName = $typeName;
+        $this->affinityKeyFieldName = $affinityKeyFieldName;
+    }
+
+    /**
+     *
+     *
+     * @param string $typeName
+     *
+     * @return CacheKeyConfiguration the same instance of the CacheKeyConfiguration.
+     */
+    public function setTypeName(string $typeName): CacheKeyConfiguration
+    {
+        $this->typeName = $typeName;
+        return $this;
+    }
+
+    /**
+     *
+     *
+     * @return string|null
+     */
+    public function getTypeName(): ?string
+    {
+        return $this->typeName;
+    }
+
+    /**
+     *
+     *
+     * @param string $affinityKeyFieldName
+     *
+     * @return CacheKeyConfiguration the same instance of the CacheKeyConfiguration.
+     */
+    public function setAffinityKeyFieldName(string $affinityKeyFieldName): CacheKeyConfiguration
+    {
+        $this->affinityKeyFieldName = $affinityKeyFieldName;
+        return $this;
+    }
+
+    /**
+     *
+     *
+     * @return string|null
+     */
+    public function getAffinityKeyFieldName(): ?string
+    {
+        return $this->affinityKeyFieldName;
+    }
+
+    // This is not the public API method, is not intended for usage by an application.
+    public function write(BinaryCommunicator $communicator, MessageBuffer $buffer): void
+    {
+        BinaryCommunicator::writeString($buffer, $this->typeName);
+        BinaryCommunicator::writeString($buffer, $this->affinityKeyFieldName);
+    }
+
+    // This is not the public API method, is not intended for usage by an application.
+    public function read(BinaryCommunicator $communicator, MessageBuffer $buffer): void
+    {
+        $this->typeName = BinaryCommunicator::readString($buffer);
+        $this->affinityKeyFieldName = BinaryCommunicator::readString($buffer);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/7d3ea115/modules/platforms/php/src/Apache/Ignite/Cache/QueryEntity.php
----------------------------------------------------------------------
diff --git a/modules/platforms/php/src/Apache/Ignite/Cache/QueryEntity.php b/modules/platforms/php/src/Apache/Ignite/Cache/QueryEntity.php
new file mode 100644
index 0000000..6be3c5a
--- /dev/null
+++ b/modules/platforms/php/src/Apache/Ignite/Cache/QueryEntity.php
@@ -0,0 +1,315 @@
+<?php
+/*
+ * 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.
+ */
+
+namespace Apache\Ignite\Cache;
+
+use Apache\Ignite\Exception\ClientException;
+use Apache\Ignite\Internal\Binary\BinaryCommunicator;
+use Apache\Ignite\Internal\Binary\MessageBuffer;
+
+/**
+ * Class representing one Query Entity element of Ignite CacheConfiguration.
+ *
+ * All configuration settings are optional and have defaults which are defined on a server side.
+ *
+ * See Apache Ignite documentation for details of every configuration setting.
+ */
+class QueryEntity
+{
+    private $keyTypeName;
+    private $valueTypeName;
+    private $tableName;
+    private $keyFieldName;
+    private $valueFieldName;
+    private $fields;
+    private $aliases;
+    private $indexes;
+
+    /**
+     * QueryEntity constructor.
+     */
+    public function __construct()
+    {
+        $this->keyTypeName = null;
+        $this->valueTypeName = null;
+        $this->tableName = null;
+        $this->keyFieldName = null;
+        $this->valueFieldName = null;
+        $this->fields = null;
+        $this->aliases = null;
+        $this->indexes = null;
+    }
+
+    /**
+     *
+     *
+     * @param string $keyTypeName
+     *
+     * @return QueryEntity the same instance of the QueryEntity.
+     */
+    public function setKeyTypeName(string $keyTypeName): QueryEntity
+    {
+        $this->keyTypeName = $keyTypeName;
+        return $this;
+    }
+
+    /**
+     *
+     *
+     * @return string|null
+     */
+    public function getKeyTypeName(): ?string
+    {
+        return $this->keyTypeName;
+    }
+
+    /**
+     *
+     *
+     * @param string $valueTypeName
+     *
+     * @return QueryEntity the same instance of the QueryEntity.
+     */
+    public function setValueTypeName(string $valueTypeName): QueryEntity
+    {
+        $this->valueTypeName = $valueTypeName;
+        return $this;
+    }
+
+    /**
+     *
+     *
+     * @return string|null
+     */
+    public function getValueTypeName(): ?string
+    {
+        return $this->valueTypeName;
+    }
+
+    /**
+     *
+     *
+     * @param string $tableName
+     *
+     * @return QueryEntity the same instance of the QueryEntity.
+     */
+    public function setTableName(string $tableName): QueryEntity
+    {
+        $this->tableName = $tableName;
+        return $this;
+    }
+
+    /**
+     *
+     *
+     * @return string|null
+     */
+    public function getTableName(): ?string
+    {
+        return $this->tableName;
+    }
+
+    /**
+     *
+     *
+     * @param string $keyFieldName
+     *
+     * @return QueryEntity the same instance of the QueryEntity.
+     */
+    public function setKeyFieldName(string $keyFieldName): QueryEntity
+    {
+        $this->keyFieldName = $keyFieldName;
+        return $this;
+    }
+
+    /**
+     *
+     *
+     * @return string|null
+     */
+    public function getKeyFieldName(): ?string
+    {
+        return $this->keyFieldName;
+    }
+
+    /**
+     *
+     *
+     * @param string $valueFieldName
+     *
+     * @return QueryEntity the same instance of the QueryEntity.
+     */
+    public function setValueFieldName(string $valueFieldName): QueryEntity
+    {
+        $this->valueFieldName = $valueFieldName;
+        return $this;
+    }
+
+    /**
+     *
+     *
+     * @return string|null
+     */
+    public function getValueFieldName(): ?string
+    {
+        return $this->valueFieldName;
+    }
+
+    /**
+     *
+     *
+     * @param QueryField ...$fields
+     *
+     * @return QueryEntity the same instance of the QueryEntity.
+     */
+    public function setFields(QueryField ...$fields): QueryEntity
+    {
+        $this->fields = $fields;
+        return $this;
+    }
+
+    /**
+     *
+     *
+     * @return QueryField[]|null
+     */
+    public function getFields(): ?array
+    {
+        return $this->fields;
+    }
+
+    /**
+     *
+     *
+     * @param array[string => string] $aliases
+     *
+     * @return QueryEntity the same instance of the QueryEntity.
+     */
+    public function setAliases(array $aliases): QueryEntity
+    {
+        $this->aliases = $aliases;
+        return $this;
+    }
+
+    /**
+     *
+     *
+     * @return array[string => string]|null
+     */
+    public function getAliases(): ?array
+    {
+        return $this->aliases;
+    }
+
+    /**
+     *
+     *
+     * @param QueryIndex ...$indexes
+     *
+     * @return QueryEntity the same instance of the QueryEntity.
+     */
+    public function setIndexes(QueryIndex ...$indexes): QueryEntity
+    {
+        $this->indexes = $indexes;
+        return $this;
+    }
+
+    /**
+     *
+     *
+     * @return QueryIndex[]|null
+     */
+    public function getIndexes(): ?array
+    {
+        return $this->indexes;
+    }
+
+    private function writeAliases(MessageBuffer $buffer): void
+    {
+        $length = $this->aliases ? count($this->aliases) : 0;
+        $buffer->writeInteger($length);
+        if ($length > 0) {
+            foreach ($this->aliases as $key => $value) {
+                BinaryCommunicator::writeString($buffer, $key);
+                BinaryCommunicator::writeString($buffer, $value);
+            }
+        }
+    }
+
+    private function writeSubEntities(BinaryCommunicator $communicator, MessageBuffer $buffer, ?array $entities): void
+    {
+        $length = $entities ? count($entities) : 0;
+        $buffer->writeInteger($length);
+        if ($length > 0) {
+            foreach ($entities as $entity) {
+                $entity->write($communicator, $buffer);
+            }
+        }
+    }
+
+    private function readAliases(MessageBuffer $buffer): void
+    {
+        $length = $buffer->readInteger();
+        $this->aliases = [];
+        if ($length > 0) {
+            for ($i = 0; $i < $length; $i++) {
+                $this->aliases[BinaryCommunicator::readString($buffer)] = BinaryCommunicator::readString($buffer);
+            }
+        }
+    }
+
+    private function readSubEntities(BinaryCommunicator $communicator, MessageBuffer $buffer, string $subEntityClassName): array
+    {
+        $result = [];
+        $length = $buffer->readInteger();
+        if ($length > 0) {
+            for ($i = 0; $i < $length; $i++) {
+                $entity = new $subEntityClassName();
+                $entity->read($communicator, $buffer);
+                array_push($result, $entity);
+            }
+        }
+        return $result;
+    }
+
+    // This is not the public API method, is not intended for usage by an application.
+    public function write(BinaryCommunicator $communicator, MessageBuffer $buffer): void
+    {
+        BinaryCommunicator::writeString($buffer, $this->keyTypeName);
+        BinaryCommunicator::writeString($buffer, $this->valueTypeName);
+        BinaryCommunicator::writeString($buffer, $this->tableName);
+        BinaryCommunicator::writeString($buffer, $this->keyFieldName);
+        BinaryCommunicator::writeString($buffer, $this->valueFieldName);
+        $this->writeSubEntities($communicator, $buffer, $this->fields);
+        $this->writeAliases($buffer);
+        $this->writeSubEntities($communicator, $buffer, $this->indexes);
+    }
+
+    // This is not the public API method, is not intended for usage by an application.
+    public function read(BinaryCommunicator $communicator, MessageBuffer $buffer): void
+    {
+        $this->keyTypeName = BinaryCommunicator::readString($buffer);
+        $this->valueTypeName = BinaryCommunicator::readString($buffer);
+        $this->tableName = BinaryCommunicator::readString($buffer);
+        $this->keyFieldName = BinaryCommunicator::readString($buffer);
+        $this->valueFieldName = BinaryCommunicator::readString($buffer);
+        $this->fields = $this->readSubEntities($communicator, $buffer, QueryField::class);
+        $this->readAliases($buffer);
+        $this->indexes = $this->readSubEntities($communicator, $buffer, QueryIndex::class);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/7d3ea115/modules/platforms/php/src/Apache/Ignite/Cache/QueryField.php
----------------------------------------------------------------------
diff --git a/modules/platforms/php/src/Apache/Ignite/Cache/QueryField.php b/modules/platforms/php/src/Apache/Ignite/Cache/QueryField.php
new file mode 100644
index 0000000..55b7724
--- /dev/null
+++ b/modules/platforms/php/src/Apache/Ignite/Cache/QueryField.php
@@ -0,0 +1,279 @@
+<?php
+/*
+ * 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.
+ */
+
+namespace Apache\Ignite\Cache;
+
+use Apache\Ignite\Exception\ClientException;
+use Apache\Ignite\Internal\Binary\BinaryCommunicator;
+use Apache\Ignite\Internal\Binary\MessageBuffer;
+use Apache\Ignite\Type\ObjectType;
+
+/**
+ * Class representing one Query Field element of QueryEntity of Ignite CacheConfiguration.
+ *
+ * All configuration settings are optional and have defaults which are defined on a server side.
+ *
+ * See Apache Ignite documentation for details of every configuration setting.
+ */
+class QueryField
+{
+    private $name;
+    private $typeName;
+    private $isKeyField;
+    private $isNotNull;
+    private $defaultValue;
+    private $precision;
+    private $scale;
+    private $valueType;
+    private $buffer;
+    private $communicator;
+    private $index;
+
+    /**
+     * QueryField constructor.
+     *
+     * @param string|null $name
+     * @param string|null $typeName
+     */
+    public function __construct(string $name = null, string $typeName = null)
+    {
+        $this->name = $name;
+        $this->typeName = $typeName;
+        $this->isKeyField = false;
+        $this->isNotNull = false;
+        $this->defaultValue = null;
+        $this->precision = -1;
+        $this->scale = -1;
+        $this->valueType = null;
+        $this->buffer = null;
+        $this->communicator = null;
+        $this->index = null;
+    }
+
+    /**
+     *
+     *
+     * @param string $name
+     *
+     * @return QueryField the same instance of the QueryField.
+     */
+    public function setName(string $name): QueryField
+    {
+        $this->name = $name;
+        return $this;
+    }
+
+    /**
+     *
+     *
+     * @return string|null
+     */
+    public function getName(): ?string
+    {
+        return $this->name;
+    }
+
+    /**
+     *
+     *
+     * @param string $typeName
+     *
+     * @return QueryField the same instance of the QueryField.
+     */
+    public function setTypeName(string $typeName): QueryField
+    {
+        $this->typeName = $typeName;
+        return $this;
+    }
+
+    /**
+     *
+     *
+     * @return string|null
+     */
+    public function getTypeName(): ?string
+    {
+        return $this->typeName;
+    }
+
+    /**
+     *
+     *
+     * @param bool $isKeyField
+     *
+     * @return QueryField the same instance of the QueryField.
+     */
+    public function setIsKeyField(bool $isKeyField): QueryField
+    {
+        $this->isKeyField = $isKeyField;
+        return $this;
+    }
+
+    /**
+     *
+     *
+     * @return bool
+     */
+    public function getIsKeyField(): bool
+    {
+        return $this->isKeyField;
+    }
+
+    /**
+     *
+     *
+     * @param bool $isNotNull
+     *
+     * @return QueryField the same instance of the QueryField.
+     */
+    public function setIsNotNull(bool $isNotNull): QueryField
+    {
+        $this->isNotNull = $isNotNull;
+        return $this;
+    }
+
+    /**
+     *
+     *
+     * @return bool
+     */
+    public function getIsNotNull(): bool
+    {
+        return $this->isNotNull;
+    }
+
+    /**
+     *
+     *
+     * @param mixed $defaultValue
+     * @param int|ObjectType|null $valueType type of the default value:
+     *   - either a type code of primitive (simple) type (@ref PrimitiveTypeCodes)
+     *   - or an instance of class representing non-primitive (composite) type
+     *   - or null (or not specified) that means the type is not specified
+     * @return QueryField the same instance of the QueryField.
+     */
+    public function setDefaultValue($defaultValue, $valueType = null): QueryField
+    {
+        $this->defaultValue = $defaultValue;
+        $this->valueType = $valueType;
+        return $this;
+    }
+
+    /**
+     *
+     *
+     * @param int|ObjectType|null $valueType type of the default value:
+     *   - either a type code of primitive (simple) type (@ref PrimitiveTypeCodes)
+     *   - or an instance of class representing non-primitive (composite) type
+     *   - or null (or not specified) that means the type is not specified
+     *
+     * @return mixed
+     *
+     * @throws ClientException if error.
+     */
+    public function getDefaultValue($valueType = null)
+    {
+        if ($this->defaultValue === null) {
+            if ($this->buffer) {
+                $position = $this->buffer->getPosition();
+                $this->buffer->setPosition($this->index);
+                $result = $this->communicator->readObject($this->buffer, $valueType);
+                $this->buffer->setPosition($position);
+                return $result;
+            } else {
+                return null;
+            }
+        } else {
+            return $this->defaultValue;
+        }
+    }
+
+    /**
+     *
+     *
+     * @param int $precision
+     *
+     * @return QueryField the same instance of the QueryField.
+     */
+    public function setPrecision(int $precision): QueryField
+    {
+        $this->precision = $precision;
+        return $this;
+    }
+
+    /**
+     *
+     *
+     * @return int
+     */
+    public function getPrecision(): int
+    {
+        return $this->precision;
+    }
+
+    /**
+     *
+     *
+     * @param int $scale
+     *
+     * @return QueryField the same instance of the QueryField.
+     */
+    public function setScale(int $scale): QueryField
+    {
+        $this->scale = $scale;
+        return $this;
+    }
+
+    /**
+     *
+     *
+     * @return int
+     */
+    public function getScale(): int
+    {
+        return $this->scale;
+    }
+
+    // This is not the public API method, is not intended for usage by an application.
+    public function write(BinaryCommunicator $communicator, MessageBuffer $buffer): void
+    {
+        BinaryCommunicator::writeString($buffer, $this->name);
+        BinaryCommunicator::writeString($buffer, $this->typeName);
+        $buffer->writeBoolean($this->isKeyField);
+        $buffer->writeBoolean($this->isNotNull);
+        $communicator->writeObject($buffer, $this->defaultValue, $this->valueType);
+        $buffer->writeInteger($this->precision);
+        $buffer->writeInteger($this->scale);
+    }
+
+    // This is not the public API method, is not intended for usage by an application.
+    public function read(BinaryCommunicator $communicator, MessageBuffer $buffer): void
+    {
+        $this->name = BinaryCommunicator::readString($buffer);
+        $this->typeName = BinaryCommunicator::readString($buffer);
+        $this->isKeyField = $buffer->readBoolean();
+        $this->isNotNull = $buffer->readBoolean();
+        $this->defaultValue = null;
+        $this->communicator = $communicator;
+        $this->buffer = $buffer;
+        $this->index = $buffer->getPosition();
+        $communicator->readObject($buffer);
+        $this->precision = $buffer->readInteger();
+        $this->scale = $buffer->readInteger();
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/7d3ea115/modules/platforms/php/src/Apache/Ignite/Cache/QueryIndex.php
----------------------------------------------------------------------
diff --git a/modules/platforms/php/src/Apache/Ignite/Cache/QueryIndex.php b/modules/platforms/php/src/Apache/Ignite/Cache/QueryIndex.php
new file mode 100644
index 0000000..796048f
--- /dev/null
+++ b/modules/platforms/php/src/Apache/Ignite/Cache/QueryIndex.php
@@ -0,0 +1,191 @@
+<?php
+/*
+ * 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.
+ */
+
+namespace Apache\Ignite\Cache;
+
+use Apache\Ignite\Exception\ClientException;
+use Apache\Ignite\Internal\Binary\BinaryCommunicator;
+use Apache\Ignite\Internal\Binary\MessageBuffer;
+use Apache\Ignite\Internal\Utils\ArgumentChecker;
+
+/**
+ * Class representing one Query Index element of QueryEntity of Ignite CacheConfiguration.
+ *
+ * All configuration settings are optional and have defaults which are defined on a server side.
+ *
+ * See Apache Ignite documentation for details of every configuration setting.
+ */
+class QueryIndex
+{
+    /** @name QueryIndexType
+     *  @anchor QueryIndexType
+     *  @{
+     */
+    const TYPE_SORTED = 0;
+    const TYPE_FULLTEXT = 1;
+    const TYPE_GEOSPATIAL = 2;
+    /** @} */ // end of QueryIndexType
+
+    private $name;
+    private $type;
+    private $inlineSize;
+    private $fields;
+
+    /**
+     * QueryIndex constructor.
+     *
+     * @param string|null $name
+     * @param int $type one of @ref QueryIndexType constants.
+     *
+     * @throws ClientException if error.
+     */
+    public function __construct(string $name = null, int $type = self::TYPE_SORTED)
+    {
+        $this->name = $name;
+        $this->setType($type);
+        $this->inlineSize = -1;
+        $this->fields = null;
+    }
+
+    /**
+     *
+     *
+     * @param string $name
+     *
+     * @return QueryIndex the same instance of the QueryIndex.
+     */
+    public function setName(string $name): QueryIndex
+    {
+        $this->name = $name;
+        return $this;
+    }
+
+    /**
+     *
+     *
+     * @return string|null
+     */
+    public function getName(): ?string
+    {
+        return $this->name;
+    }
+
+    /**
+     *
+     *
+     * @param int $type one of @ref QueryIndexType constants.
+     *
+     * @return QueryIndex the same instance of the QueryIndex.
+     *
+     * @throws ClientException if error.
+     */
+    public function setType(int $type): QueryIndex
+    {
+        ArgumentChecker::hasValueFrom(
+            $type, 'type', false, [self::TYPE_SORTED, self::TYPE_FULLTEXT, self::TYPE_GEOSPATIAL]);
+        $this->type = $type;
+        return $this;
+    }
+
+    /**
+     *
+     *
+     * @return int index type, one of @ref QueryIndexType constants.
+     */
+    public function getType(): int
+    {
+        return $this->type;
+    }
+
+    /**
+     *
+     *
+     * @param int $inlineSize
+     *
+     * @return QueryIndex the same instance of the QueryIndex.
+     */
+    public function setInlineSize(int $inlineSize): QueryIndex
+    {
+        $this->inlineSize = $inlineSize;
+        return $this;
+    }
+
+    /**
+     *
+     *
+     * @return int
+     */
+    public function getInlineSize(): int
+    {
+        return $this->inlineSize;
+    }
+
+    /**
+     *
+     *
+     * @param array[string => bool] $fields
+     *
+     * @return QueryIndex the same instance of the QueryIndex.
+     */
+    public function setFields(array $fields): QueryIndex
+    {
+        $this->fields = $fields;
+        return $this;
+    }
+
+    /**
+     *
+     *
+     * @return array[string => bool]|null
+     */
+    public function getFields(): ?array
+    {
+        return $this->fields;
+    }
+
+    // This is not the public API method, is not intended for usage by an application.
+    public function write(BinaryCommunicator $communicator, MessageBuffer $buffer): void
+    {
+        BinaryCommunicator::writeString($buffer, $this->name);
+        $buffer->writeByte($this->type);
+        $buffer->writeInteger($this->inlineSize);
+        // write fields
+        $length = $this->fields ? count($this->fields) : 0;
+        $buffer->writeInteger($length);
+        if ($length > 0) {
+            foreach ($this->fields as $key => $value) {
+                BinaryCommunicator::writeString($buffer, $key);
+                $buffer->writeBoolean($value);
+            }
+        }
+    }
+
+    // This is not the public API method, is not intended for usage by an application.
+    public function read(BinaryCommunicator $communicator, MessageBuffer $buffer): void
+    {
+        $this->name = BinaryCommunicator::readString($buffer);
+        $this->type = $buffer->readByte();
+        $this->inlineSize = $buffer->readInteger();
+        // read fields
+        $length = $buffer->readInteger();
+        $this->fields = [];
+        if ($length > 0) {
+            $this->fields[BinaryCommunicator::readString($buffer)] = $buffer->readBoolean();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/7d3ea115/modules/platforms/php/src/Apache/Ignite/Client.php
----------------------------------------------------------------------
diff --git a/modules/platforms/php/src/Apache/Ignite/Client.php b/modules/platforms/php/src/Apache/Ignite/Client.php
new file mode 100644
index 0000000..82847b4
--- /dev/null
+++ b/modules/platforms/php/src/Apache/Ignite/Client.php
@@ -0,0 +1,243 @@
+<?php
+/*
+ * 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.
+ */
+
+namespace Apache\Ignite;
+
+use Apache\Ignite\Exception\ClientException;
+use Apache\Ignite\Cache\CacheConfiguration;
+use Apache\Ignite\Cache\CacheInterface;
+use Apache\Ignite\Internal\Connection\ClientFailoverSocket;
+use Apache\Ignite\Internal\Binary\MessageBuffer;
+use Apache\Ignite\Internal\Binary\BinaryCommunicator;
+use Apache\Ignite\Internal\Utils\ArgumentChecker;
+use Apache\Ignite\Internal\Utils\Logger;
+use Apache\Ignite\Internal\Binary\ClientOperation;
+use Apache\Ignite\Internal\Cache;
+
+/**
+ * @mainpage Public API specification
+ * The thin client allows your PHP applications to work with Apache Ignite clusters via Binary %Client Protocol.
+ *
+ * This is the public API specification of the client.
+ *
+ * If you open it for the first time, start from the Client class.
+ *
+ * For the usage guide and other instructions see accompanied Apache Ignite PHP %Client documentation.
+ */
+
+/**
+ * Class representing Ignite client.
+ */
+class Client
+{
+    private $socket;
+    private $communicator;
+    
+    /**
+     * Public Client constructor.
+     */
+    public function __construct()
+    {
+        $this->socket = new ClientFailoverSocket();
+        $this->communicator = new BinaryCommunicator($this->socket);
+    }
+    
+    /**
+     * Connects the client.
+     *
+     * Reconnects if the client already connected.
+     *
+     * @param ClientConfiguration $config the client configuration.
+     * 
+     * @throws ClientException if error.
+     */
+    public function connect(ClientConfiguration $config): void
+    {
+        $this->socket->connect($config);
+    }
+    
+    /**
+     * Disconnects the client.
+     *
+     * Does nothing if the client already disconnected.
+     */
+    public function disconnect(): void
+    {
+        $this->socket->disconnect();
+    }
+    
+    /**
+     * Creates new cache with the provided name and optional configuration.
+     * 
+     * @param string $name cache name.
+     * @param CacheConfiguration $cacheConfig optional cache configuration.
+     * 
+     * @return CacheInterface new instance of the class with interface representing the created cache.
+     * 
+     * @throws ClientException if error.
+     */
+    public function createCache(
+            string $name,
+            CacheConfiguration $cacheConfig = null): CacheInterface
+    {
+        ArgumentChecker::notEmpty($name, 'name');
+        $this->communicator->send(
+            $cacheConfig ?
+                ClientOperation::CACHE_CREATE_WITH_CONFIGURATION :
+                ClientOperation::CACHE_CREATE_WITH_NAME,
+            function (MessageBuffer $payload) use ($name, $cacheConfig)
+            {
+                $this->writeCacheNameOrConfig($payload, $name, $cacheConfig);
+            });
+        return new Cache($name, $this->communicator);
+    }
+    
+    /**
+     * Gets existing cache with the provided name
+     * or creates new one with the provided name and optional configuration.
+     * 
+     * @param string $name cache name.
+     * @param CacheConfiguration $cacheConfig cache configuration (ignored if cache
+     *   with the provided name already exists).
+     * 
+     * @return CacheInterface new instance of the class with interface representing the existing or created cache.
+     * 
+     * @throws ClientException if error.
+     */
+    public function getOrCreateCache(
+            string $name,
+            CacheConfiguration $cacheConfig = null): CacheInterface
+    {
+        ArgumentChecker::notEmpty($name, 'name');
+        $this->communicator->send(
+            $cacheConfig ?
+                ClientOperation::CACHE_GET_OR_CREATE_WITH_CONFIGURATION :
+                ClientOperation::CACHE_GET_OR_CREATE_WITH_NAME,
+            function (MessageBuffer $payload) use ($name, $cacheConfig)
+            {
+                $this->writeCacheNameOrConfig($payload, $name, $cacheConfig);
+            });
+        return new Cache($name, $this->communicator);
+    }
+    
+    /**
+     * Gets instance of the class with interface representing the cache with the provided name.
+     * The method does not check if the cache with the provided name exists.
+     * 
+     * @param string $name cache name.
+     * 
+     * @return CacheInterface new instance of the class with interface representing the cache.
+     * 
+     * @throws ClientException if error.
+     */
+    public function getCache(string $name): CacheInterface
+    {
+        ArgumentChecker::notEmpty($name, 'name');
+        return new Cache($name, $this->communicator);
+    }
+    
+    /**
+     * Destroys cache with the provided name.
+     *
+     * @param string $name cache name.
+     * 
+     * @throws ClientException if error.
+     */
+    public function destroyCache(string $name): void
+    {
+        ArgumentChecker::notEmpty($name, 'name');
+        $this->communicator->send(
+            ClientOperation::CACHE_DESTROY,
+            function (MessageBuffer $payload) use ($name)
+            {
+                $payload->writeInteger(Cache::calculateId($name));
+            });
+    }
+    
+    /**
+     * Returns configuration of cache with the provided name.
+     * 
+     * @param string $name cache name.
+     * 
+     * @return CacheConfiguration cache configuration.
+     * 
+     * @throws ClientException if error.
+     */
+    public function getCacheConfiguration(string $name): CacheConfiguration
+    {
+        ArgumentChecker::notEmpty($name, 'name');
+        $config = null;
+        $this->communicator->send(
+            ClientOperation::CACHE_GET_CONFIGURATION,
+            function (MessageBuffer $payload) use ($name)
+            {
+                $payload->writeInteger(Cache::calculateId($name));
+                $payload->writeByte(0);
+            },
+            function (MessageBuffer $payload) use (&$config)
+            {
+                $config = new CacheConfiguration();
+                $config->read($this->communicator, $payload);
+            });
+        return $config;
+    }
+    
+    /**
+     * Gets existing cache names.
+     * 
+     * @return array array with the existing cache names.
+     *     The array is empty if no caches exist.
+     * 
+     * @throws ClientException if error.
+     */
+    public function cacheNames(): array
+    {
+        $names = null;
+        $this->communicator->send(
+            ClientOperation::CACHE_GET_NAMES,
+            null,
+            function (MessageBuffer $payload) use (&$names)
+            {
+                $names = $this->communicator->readStringArray($payload);
+            });
+        return $names;
+    }
+    
+    /**
+     * Enables/disables the Ignite client's debug output (including errors logging).
+     * Disabled by default.
+     * 
+     * @param bool $value true to enable, false to disable.
+     */
+    public function setDebug(bool $value): void
+    {
+        Logger::setDebug($value);
+    }
+
+    private function writeCacheNameOrConfig(
+            MessageBuffer $buffer,
+            string $name,
+            CacheConfiguration $cacheConfig = null): void
+    {
+        if ($cacheConfig) {
+            $cacheConfig->write($this->communicator, $buffer, $name);
+        } else {
+            $this->communicator->writeString($buffer, $name);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/7d3ea115/modules/platforms/php/src/Apache/Ignite/ClientConfiguration.php
----------------------------------------------------------------------
diff --git a/modules/platforms/php/src/Apache/Ignite/ClientConfiguration.php b/modules/platforms/php/src/Apache/Ignite/ClientConfiguration.php
new file mode 100644
index 0000000..e10f010
--- /dev/null
+++ b/modules/platforms/php/src/Apache/Ignite/ClientConfiguration.php
@@ -0,0 +1,294 @@
+<?php
+/*
+ * 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.
+ */
+
+namespace Apache\Ignite;
+
+use Apache\Ignite\Exception\ClientException;
+use Apache\Ignite\Internal\Utils\ArgumentChecker;
+
+/**
+ * Class representing Ignite client configuration.
+ *
+ * The configuration includes:
+ *   - (mandatory) Ignite node endpoint(s)
+ *   - (optional) user credentials for authentication
+ *   - (optional) TLS options for secure connection
+ *   - (optional) connection options
+ */
+class ClientConfiguration
+{
+    private $endpoints;
+    private $userName;
+    private $password;
+    private $tlsOptions;
+    private $timeout;
+    private $sendChunkSize;
+    private $receiveChunkSize;
+    private $tcpNoDelay;
+
+    const ENDPOINT_PORT_DEFAULT = 10800;
+
+    /**
+     * Creates an instance of Ignite client configuration
+     * with the provided mandatory settings and default optional settings.
+     *
+     * By default, the client does not use authentication and secure connection.
+     *
+     * @param string ...$endpoints Ignite node endpoint(s). The client randomly connects/reconnects
+     * to one of the specified node.
+     *
+     * @throws ClientException if error.
+     */
+    public function __construct(string ...$endpoints)
+    {
+        ArgumentChecker::notEmpty($endpoints, 'endpoints');
+        $this->endpoints = array_map(array($this, 'parseEndpoint'), $endpoints);
+        $this->userName = null;
+        $this->password = null;
+        $this->tlsOptions = null;
+        $this->timeout = 0;
+        $this->sendChunkSize = 0;
+        $this->receiveChunkSize = 0;
+        $this->tcpNoDelay = true;
+    }
+    
+    /**
+     * Returns Ignite node endpoints specified in the constructor.
+     * 
+     * @return string[] endpoints
+     */
+    public function getEndpoints(): array
+    {
+        return $this->endpoints;
+    }
+
+    /**
+     * Sets username which will be used for authentication during the client's connection.
+     *
+     * If username is not set, the client does not use authentication during connection.
+     * 
+     * @param string|null $userName username. If null, authentication is disabled.
+     * 
+     * @return ClientConfiguration the same instance of the ClientConfiguration.
+     */
+    public function setUserName(?string $userName): ClientConfiguration
+    {
+        $this->userName = $userName;
+        return $this;
+    }
+    
+    /**
+     * Returns the current username.
+     * 
+     * @return string|null username or null (if authentication is disabled).
+     */
+    public function getUserName(): ?string
+    {
+        return $this->userName;
+    }
+    
+    /**
+     * Sets password which will be used for authentication during the client's connection.
+     *
+     * Password is ignored, if username is not set.
+     * If password is not set, it is considered empty.
+     * 
+     * @param string|null $password password. If null, password is empty.
+     * 
+     * @return ClientConfiguration the same instance of the ClientConfiguration.
+     */
+    public function setPassword(?string $password): ClientConfiguration
+    {
+        $this->password = $password;
+        return $this;
+    }
+    
+    /**
+     * Returns the current password.
+     * 
+     * @return string|null password or null (if password is empty).
+     */
+    public function getPassword(): ?string
+    {
+        return $this->password;
+    }
+    
+    /**
+     * Enables and setup TLS connection.
+     *
+     * If not enabled (by default), the client does not use secure connection.
+     *
+     * @param array|null $tlsOptions TLS connection options in the format defined here: http://php.net/manual/en/context.ssl.php
+     * If null, secure connection is not used.
+     *
+     * @return ClientConfiguration the same instance of the ClientConfiguration.
+     */
+    public function setTLSOptions(?array $tlsOptions): ClientConfiguration
+    {
+        $this->tlsOptions = $tlsOptions;
+        return $this;
+    }
+    
+    /**
+     * Returns the current TLS connection options.
+     * 
+     * @return array|null TLS connection options or null (if secure connection is not used).
+     */
+    public function getTLSOptions(): ?array
+    {
+        return $this->tlsOptions;
+    }
+
+    /**
+     * Sets send/receive timeout.
+     *
+     * Default value is defined by the PHP settings.
+     *
+     * @param int $timeout send/receive timeout (in milliseconds).
+     *
+     * @return ClientConfiguration the same instance of the ClientConfiguration.
+     */
+    public function setTimeout(int $timeout): ClientConfiguration
+    {
+        $this->timeout = $timeout;
+        return $this;
+    }
+
+    /**
+     * Returns the current send/receive timeout.
+     *
+     * @return int send/receive timeout (in milliseconds).
+     */
+    public function getTimeout(): int
+    {
+        return $this->timeout;
+    }
+
+    /**
+     * Sets the size of the send chunk.
+     *
+     * 8192 bytes by default.
+     *
+     * @param int $size size of the send chunk (in bytes).
+     *
+     * @return ClientConfiguration the same instance of the ClientConfiguration.
+     */
+    public function setSendChunkSize(int $size): ClientConfiguration
+    {
+        $this->sendChunkSize = $size;
+        return $this;
+    }
+
+    /**
+     * Returns the current size of the send chunk.
+     *
+     * @return int size of the send chunk (in bytes).
+     */
+    public function getSendChunkSize(): int
+    {
+        return $this->sendChunkSize;
+    }
+
+    /**
+     * Sets the size of the receive chunk.
+     *
+     * 8192 bytes by default.
+     *
+     * @param int $size size of the receive chunk (in bytes).
+     *
+     * @return ClientConfiguration the same instance of the ClientConfiguration.
+     */
+    public function setReceiveChunkSize(int $size): ClientConfiguration
+    {
+        $this->receiveChunkSize = $size;
+        return $this;
+    }
+
+    /**
+     * Returns the current size of the receive chunk.
+     *
+     * @return int size of the receive chunk (in bytes).
+     */
+    public function getReceiveChunkSize(): int
+    {
+        return $this->receiveChunkSize;
+    }
+
+    /**
+     * Disables/enables the TCP Nagle algorithm.
+     *
+     * Enabled by default.
+     *
+     * @param bool $tcpNoDelay true to enable, false to disable.
+     *
+     * @return ClientConfiguration the same instance of the ClientConfiguration.
+     */
+    public function setTcpNoDelay(bool $tcpNoDelay): ClientConfiguration
+    {
+        $this->tcpNoDelay = $tcpNoDelay;
+        return $this;
+    }
+
+    /**
+     * Returns the current status of the TCP Nagle algorithm.
+     *
+     * @return bool true if enabled, false if disabled.
+     */
+    public function getTcpNoDelay(): bool
+    {
+        return $this->tcpNoDelay;
+    }
+
+    private function parseEndpoint(string $endpoint): string
+    {
+        $endpoint = trim($endpoint);
+        $host = $endpoint;
+        $port = null;
+        $parsed = explode(':', $endpoint);
+        if (count($parsed) > 2) {
+            // IPv6 address
+            $index = strrpos($endpoint, ']:');
+            if ($index !== false) {
+                $host = substr($endpoint, 0, $index + 1);
+                $port = substr($endpoint, $index + 2);
+            }
+            $first = $host[0];
+            $last = $host[strlen($host) - 1];
+            if ($first === '[' || $last === ']') {
+                if (!($first === '[' && $last === ']')) {
+                    ArgumentChecker::illegalArgument('Incorrect endpoint format: ' . $endpoint);
+                }
+            } else {
+                $host = sprintf('[%s]', $host);
+            }
+        }
+        else {
+            // IPv4 address
+            $host = $parsed[0];
+            if (count($parsed) === 2) {
+                $port = $parsed[1];
+            }
+        }
+        if ($port === null) {
+            $port = self::ENDPOINT_PORT_DEFAULT;
+        } elseif (!ctype_digit($port)) {
+            ArgumentChecker::illegalArgument('Incorrect endpoint format: ' . $endpoint);
+        }
+        return sprintf('%s:%s', $host, $port);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/7d3ea115/modules/platforms/php/src/Apache/Ignite/Data/BinaryObject.php
----------------------------------------------------------------------
diff --git a/modules/platforms/php/src/Apache/Ignite/Data/BinaryObject.php b/modules/platforms/php/src/Apache/Ignite/Data/BinaryObject.php
new file mode 100644
index 0000000..92a3294
--- /dev/null
+++ b/modules/platforms/php/src/Apache/Ignite/Data/BinaryObject.php
@@ -0,0 +1,469 @@
+<?php
+/*
+ * 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.
+ */
+
+namespace Apache\Ignite\Data;
+
+use Apache\Ignite\Type\ObjectType;
+use Apache\Ignite\Type\ComplexObjectType;
+use Apache\Ignite\Exception\ClientException;
+use Apache\Ignite\Internal\Binary\BinaryCommunicator;
+use Apache\Ignite\Internal\Binary\BinaryTypeBuilder;
+use Apache\Ignite\Internal\Binary\BinaryObjectField;
+use Apache\Ignite\Internal\Binary\MessageBuffer;
+use Apache\Ignite\Internal\Binary\BinaryUtils;
+use Apache\Ignite\Internal\Binary\BinaryField;
+use Apache\Ignite\Internal\Utils\ArgumentChecker;
+use Apache\Ignite\Internal\Utils\Logger;
+
+/**
+ * Class representing a complex Ignite object in the binary form.
+ *
+ * It corresponds to ObjectType::COMPLEX_OBJECT,
+ * has mandatory type Id, which corresponds to a name of the complex type,
+ * and includes optional fields.
+ *
+ * An instance of the BinaryObject can be obtained/created by the following ways:
+ *   - returned by the client when a complex object is received from Ignite cache
+ * and is not deserialized to another PHP object.
+ *   - created using the public constructor. Fields may be added to such an instance using setField() method.
+ *   - created from a PHP object using static fromObject() method.
+ */
+class BinaryObject
+{
+    const HEADER_LENGTH = 24;
+    const VERSION = 1;
+
+    // user type
+    const FLAG_USER_TYPE = 0x0001;
+    // schema exists
+    const FLAG_HAS_SCHEMA = 0x0002;
+    // object contains raw data
+    const FLAG_HAS_RAW_DATA = 0x0004;
+    // offsets take 1 byte
+    const FLAG_OFFSET_ONE_BYTE = 0x0008;
+    // offsets take 2 bytes
+    const FLAG_OFFSET_TWO_BYTES = 0x0010;
+    // compact footer, no field IDs
+    const FLAG_COMPACT_FOOTER = 0x0020;
+    
+    private $typeName;
+    private $fields;
+    private $typeBuilder;
+    private $modified;
+    private $buffer;
+    private $schemaOffset;
+    private $hasSchema;
+    private $compactFooter;
+    private $hasRawData;
+    private $offsetType;
+    private $startPos;
+    private $length;
+
+    /**
+     * Creates an instance of the BinaryObject without any fields.
+     *
+     * Fields may be added later using setField() method.
+     *
+     * @param string $typeName name of the complex type to generate the type Id.
+     *
+     * @throws ClientException if error.
+     */
+    public function __construct(string $typeName)
+    {
+        ArgumentChecker::notEmpty($typeName, 'typeName');
+        $this->typeName = $typeName;
+        $this->fields = [];
+        $this->typeBuilder = BinaryTypeBuilder::fromTypeName($typeName);
+        $this->modified = false;
+        $this->buffer = null;
+        $this->schemaOffset = null;
+        $this->hasSchema = false;
+        $this->compactFooter = false;
+        $this->hasRawData = false;
+    }
+
+    /**
+     * Creates an instance of the BinaryObject from the specified instance of PHP class.
+     *
+     * All public properties of the PHP object with their values are added as fields
+     * to the BinaryObject.
+     * Fields may be added or removed later using setField() and removeField() methods.
+     *
+     * If complexObjectType parameter is specified, then the type Id is taken from it.
+     * Otherwise, the type Id is generated from the name of the PHP class which instance is specified.
+     * 
+     * @param object $object instance of PHP class which adds and initializes the fields
+     *     of the BinaryObject instance.
+     * @param ComplexObjectType $complexObjectType instance of complex type definition
+     *   which specifies non-standard mapping of the fields of the BinaryObject instance
+     *   to/from the Ignite types.
+     * 
+     * @return BinaryObject new BinaryObject instance.
+     * 
+     * @throws ClientException if error.
+     */
+    public static function fromObject(object $object, ComplexObjectType $complexObjectType = null): BinaryObject
+    {
+        $typeBuilder = BinaryTypeBuilder::fromObject($object, $complexObjectType);
+        $result = new BinaryObject($typeBuilder->getTypeName());
+        $result->typeBuilder = $typeBuilder;
+        try {
+            $class = new \ReflectionClass($object);
+            foreach ($typeBuilder->getFields() as $field) {
+                $fieldName = $field->getName();
+                if ($class->hasProperty($fieldName)) {
+                    $result->setField(
+                        $fieldName,
+                        $class->getProperty($fieldName)->getValue($object),
+                        $complexObjectType ? $complexObjectType->getFieldType($fieldName) : null);
+                } else {
+                    BinaryUtils::serializationError(true, sprintf('field "%s" does not exist', $fieldName));
+                }
+            }
+        } catch (\ReflectionException $e) {
+            BinaryUtils::serializationError(true, sprintf('class "%s" does not exist', get_class($object)));
+        }
+        return $result;
+    }
+    
+    /**
+     * Sets new value of the specified field.
+     * Adds the specified field, if it did not exist before.
+     *
+     * Optionally, specifies an Ignite type of the field.
+     * If the type is not specified then the Ignite client
+     * tries to make automatic mapping between PHP types and Ignite object types -
+     * according to the mapping table defined in the description of the ObjectType class.
+     * 
+     * @param string $fieldName name of the field.
+     * @param mixed $fieldValue new value of the field.
+     * @param int|ObjectType|null $fieldType Ignite type of the field:
+     *   - either a type code of primitive (simple) type (@ref PrimitiveTypeCodes)
+     *   - or an instance of class representing non-primitive (composite) type
+     *   - or null (or not specified) that means the type is not specified
+     * 
+     * @return BinaryObject the same instance of BinaryObject.
+     * 
+     * @throws ClientException if error.
+     */
+    public function setField(string $fieldName, $fieldValue, $fieldType = null): BinaryObject
+    {
+        ArgumentChecker::notEmpty($fieldName, 'fieldName');
+        BinaryUtils::checkObjectType($fieldType, 'fieldType');
+        $this->modified = true;
+        $field = new BinaryObjectField($fieldName, $fieldValue, $fieldType);
+        $this->fields[$field->getId()] = $field;
+        $this->typeBuilder->setField($fieldName, $field->getTypeCode());
+        return $this;
+    }
+
+    /**
+     * Removes the specified field.
+     * Does nothing if the field does not exist.
+     * 
+     * @param string $fieldName name of the field.
+     * 
+     * @return BinaryObject the same instance of BinaryObject.
+     * 
+     * @throws ClientException if error.
+     */
+    public function removeField(string $fieldName): BinaryObject
+    {
+        ArgumentChecker::notEmpty($fieldName, 'fieldName');
+        $this->modified = true;
+        $fieldId = BinaryField::calculateId($fieldName);
+        if (array_key_exists($fieldId, $this->fields)) {
+            unset($this->fields[$fieldId]);
+        }
+        $this->typeBuilder->removeField($fieldName);
+        return $this;
+    }
+    
+    /**
+     * Checks if the specified field exists in this BinaryObject instance.
+     * 
+     * @param string $fieldName name of the field.
+     * 
+     * @return bool true if exists, false otherwise.
+     * 
+     * @throws ClientException if error.
+     */
+    public function hasField(string $fieldName): bool
+    {
+        ArgumentChecker::notEmpty($fieldName, 'fieldName');
+        $fieldId = BinaryField::calculateId($fieldName);
+        return array_key_exists($fieldId, $this->fields);
+    }
+
+    /**
+     * Returns a value of the specified field.
+     *
+     * Optionally, specifies Ignite type of the field.
+     * If the type is not specified then the Ignite client
+     * tries to make automatic mapping between PHP types and Ignite object types -
+     * according to the mapping table defined in the description of the ObjectType class.
+     *
+     * If field with the specified name doesn't exist, throws Exception::ClientException.
+     * Use hasField() method to ensure the field exists.
+     * 
+     * @param string $fieldName name of the field.
+     * @param int|ObjectType|null $fieldType Ignite type of the field:
+     *   - either a type code of primitive (simple) type (@ref PrimitiveTypeCodes)
+     *   - or an instance of class representing non-primitive (composite) type
+     *   - or null (or not specified) that means the type is not specified
+     * 
+     * @return mixed value of the field.
+     * 
+     * @throws ClientException if error.
+     */
+    public function getField(string $fieldName, $fieldType = null)
+    {
+        ArgumentChecker::notEmpty($fieldName, 'fieldName');
+        BinaryUtils::checkObjectType($fieldType, 'fieldType');
+        $fieldId = BinaryField::calculateId($fieldName);
+        if (array_key_exists($fieldId, $this->fields)) {
+            return $this->fields[$fieldId]->getValue($fieldType);
+        }
+        throw new ClientException(sprintf('Field %s does not exist', $fieldName));
+    }
+    
+    /**
+     * Deserializes this BinaryObject instance into PHP object which corresponds to the specified complex object type.
+     * 
+     * @param ComplexObjectType $complexObjectType instance of class representing complex object type.
+     * 
+     * @return object instance of the PHP object which corresponds to the specified complex object type.
+     * 
+     * @throws ClientException if error.
+     */
+    public function toObject(ComplexObjectType $complexObjectType): object
+    {
+        $className = $complexObjectType->getPhpClassName();
+        if (!$className) {
+            $className = $this->getTypeName();
+        }
+        if (!class_exists($className)) {
+            BinaryUtils::serializationError(false, sprintf('class "%s" does not exist', $className));
+        }
+        $result = new $className;
+        foreach ($this->fields as $field) {
+            $binaryField = $this->typeBuilder->getField($field->getId());
+            if (!$binaryField) {
+                BinaryUtils::serializationError(
+                    false, sprintf('field with id "%s" can not be deserialized', $field->getId()));
+            }
+            $fieldName = $binaryField->getName();
+            $result->$fieldName = $field->getValue($complexObjectType->getFieldType($fieldName));
+        }
+        return $result;
+    }
+    
+    /**
+     * Returns type name of this BinaryObject instance.
+     * 
+     * @return string type name.
+     */
+    public function getTypeName(): string
+    {
+        return $this->typeBuilder->getTypeName();
+    }
+    
+    /**
+     * Returns names of all fields in this BinaryObject instance.
+     * 
+     * @return array names of all fields.
+     * 
+     * @throws ClientException if error.
+     */
+    public function getFieldNames(): array
+    {
+        return array_map(
+            function (int $fieldId): string
+            {
+                $field = $this->typeBuilder->getField($fieldId);
+                if ($field) {
+                    return $field->getName();
+                } else {
+                    BinaryUtils::internalError(
+                        sprintf('Field "%s" is absent in binary type fields', $fieldId));
+                }
+                return null;
+            },
+            $this->typeBuilder->getSchema()->getFieldIds());
+    }
+
+    private static function isFlagSet(int $flags, int $flag): bool
+    {
+        return ($flags & $flag) === $flag;
+    }
+
+    // This is not the public API method, is not intended for usage by an application.
+    public static function fromBuffer(BinaryCommunicator $communicator, MessageBuffer $buffer): BinaryObject
+    {
+        $result = new BinaryObject(' ');
+        $result->buffer = $buffer;
+        $result->startPos = $buffer->getPosition();
+        $result->read($communicator);
+        return $result;
+    }
+
+    // This is not the public API method, is not intended for usage by an application.
+    public function write(BinaryCommunicator $communicator, MessageBuffer $buffer): void
+    {
+        if ($this->buffer && !$this->modified) {
+            $buffer->writeBuffer($this->buffer, $this->startPos, $this->length);
+        } else {
+            $this->typeBuilder->finalize($communicator);
+            $this->startPos = $buffer->getPosition();
+            $buffer->setPosition($this->startPos + BinaryObject::HEADER_LENGTH);
+            $this->hasSchema = count($this->fields) > 0;
+            if ($this->hasSchema) {
+                // write fields
+                $field = null;
+                foreach ($this->fields as $field) {
+                    $field->writeValue($communicator, $buffer, ($this->typeBuilder->getField($field->getId()))->getTypeCode());
+                }
+                $this->schemaOffset = $buffer->getPosition() - $this->startPos;
+                $this->offsetType = $field->getOffsetType($this->startPos);
+                // write schema
+                foreach ($this->fields as $field) {
+                    $field->writeOffset($buffer, $this->startPos, $this->offsetType);
+                }
+            } else {
+                $this->schemaOffset = 0;
+            }
+            $this->length = $buffer->getPosition() - $this->startPos;
+            $this->buffer = $buffer;
+            // write header
+            $this->writeHeader();
+            $this->buffer->setPosition($this->startPos + $this->length);
+            $this->modified = false;
+        }
+
+        if (Logger::isDebug()) {
+            Logger::logDebug('BinaryObject::write');
+            Logger::logBuffer($this->buffer, $this->startPos, $this->length);
+        }
+    }
+
+    private function writeHeader(): void
+    {
+        $this->buffer->setPosition($this->startPos);
+        // type code
+        $this->buffer->writeByte(ObjectType::COMPLEX_OBJECT);
+        // version
+        $this->buffer->writeByte(BinaryObject::VERSION);
+        // flags
+        $flags = BinaryObject::FLAG_USER_TYPE;
+        if ($this->hasSchema) {
+            $flags = $flags | BinaryObject::FLAG_COMPACT_FOOTER | BinaryObject::FLAG_HAS_SCHEMA;
+        }
+        if ($this->offsetType === ObjectType::BYTE) {
+            $flags = $flags | BinaryObject::FLAG_OFFSET_ONE_BYTE;
+        } elseif ($this->offsetType === ObjectType::SHORT) {
+            $flags = $flags | BinaryObject::FLAG_OFFSET_TWO_BYTES;
+        }
+        $this->buffer->writeShort($flags);
+        // type id
+        $this->buffer->writeInteger($this->typeBuilder->getTypeId());
+        // hash code
+        $this->buffer->writeInteger(BinaryUtils::contentHashCode(
+            $this->buffer, $this->startPos + BinaryObject::HEADER_LENGTH, $this->schemaOffset - 1));
+        // length
+        $this->buffer->writeInteger($this->length);
+        // schema id
+        $this->buffer->writeInteger($this->hasSchema ? $this->typeBuilder->getSchemaId() : 0);
+        // schema offset
+        $this->buffer->writeInteger($this->schemaOffset);
+    }
+
+    private function read(BinaryCommunicator $communicator): void
+    {
+        $this->readHeader($communicator);
+        if ($this->hasSchema) {
+            $this->buffer->setPosition($this->startPos + $this->schemaOffset);
+            $fieldOffsets = [];
+            $fieldIds = $this->typeBuilder->getSchema()->getFieldIds();
+            $index = 0;
+            $schemaEndOffset = $this->startPos + $this->length;
+            if ($this->hasRawData) {
+                $schemaEndOffset -= TypeInfo::getTypeInfo(ObjectType::INTEGER)->getSize();
+            }
+            while ($this->buffer->getPosition() < $schemaEndOffset) {
+                if (!$this->compactFooter) {
+                    $fieldId = $this->buffer->readInteger();
+                    $this->typeBuilder->getSchema()->addField($fieldId);
+                } else {
+                    if ($index >= count($fieldIds)) {
+                        BinaryUtils::serializationError(
+                            false, 'wrong number of fields in schema');
+                    }
+                    $fieldId = $fieldIds[$index];
+                    $index++;
+                }
+                array_push($fieldOffsets, [$fieldId, $this->buffer->readNumber($this->offsetType, false)]);
+            }
+            usort($fieldOffsets,
+                function (array $val1, array $val2): int
+                {
+                    return $val1[1] - $val2[1];
+                });
+            for ($i = 0; $i < count($fieldOffsets); $i++) {
+                $fieldId = $fieldOffsets[$i][0];
+                $offset = $fieldOffsets[$i][1];
+                $nextOffset = $i + 1 < count($fieldOffsets) ? $fieldOffsets[$i + 1][1] : $this->schemaOffset;
+                $field = BinaryObjectField::fromBuffer(
+                    $communicator, $this->buffer, $this->startPos + $offset, $nextOffset - $offset, $fieldId);
+                $this->fields[$field->getId()] = $field;
+            }
+        }
+        $this->buffer->setPosition($this->startPos + $this->length);
+    }
+
+    private function readHeader(BinaryCommunicator $communicator): void
+    {
+        // type code
+        $this->buffer->readByte();
+        // version
+        $version = $this->buffer->readByte();
+        if ($version !== BinaryObject::VERSION) {
+            BinaryUtils::internalError();
+        }
+        // flags
+        $flags = $this->buffer->readShort();
+        // type id
+        $typeId = $this->buffer->readInteger();
+        // hash code
+        $this->buffer->readInteger();
+        // length
+        $this->length = $this->buffer->readInteger();
+        // schema id
+        $schemaId = $this->buffer->readInteger();
+        // schema offset
+        $this->schemaOffset = $this->buffer->readInteger();
+        $this->hasSchema = BinaryObject::isFlagSet($flags, BinaryObject::FLAG_HAS_SCHEMA);
+        $this->compactFooter = BinaryObject::isFlagSet($flags, BinaryObject::FLAG_COMPACT_FOOTER);
+        $this->hasRawData = BinaryObject::isFlagSet($flags, BinaryObject::FLAG_HAS_RAW_DATA);
+        $this->offsetType = BinaryObject::isFlagSet($flags, BinaryObject::FLAG_OFFSET_ONE_BYTE) ?
+            ObjectType::BYTE :
+            (BinaryObject::isFlagSet($flags, BinaryObject::FLAG_OFFSET_TWO_BYTES) ?
+                ObjectType::SHORT :
+                ObjectType::INTEGER);
+        $this->typeBuilder = BinaryTypeBuilder::fromTypeId($communicator, $typeId, $this->compactFooter ? $schemaId : null);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/7d3ea115/modules/platforms/php/src/Apache/Ignite/Data/Date.php
----------------------------------------------------------------------
diff --git a/modules/platforms/php/src/Apache/Ignite/Data/Date.php b/modules/platforms/php/src/Apache/Ignite/Data/Date.php
new file mode 100644
index 0000000..356cc36
--- /dev/null
+++ b/modules/platforms/php/src/Apache/Ignite/Data/Date.php
@@ -0,0 +1,84 @@
+<?php
+/*
+ * 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.
+ */
+
+namespace Apache\Ignite\Data;
+
+use \DateTime;
+
+/** 
+ * Class representing Ignite Date type
+ * (number of milliseconds elapsed since January 1, 1970, 00:00:00 UTC).
+ */
+class Date
+{
+    private $millis;
+
+    /**
+     * Public constructor.
+     * 
+     * @param float $millis integer number of milliseconds elapsed since January 1, 1970, 00:00:00 UTC.
+     */
+    public function __construct(float $millis)
+    {
+        $this->millis = $millis;
+    }
+    
+    /**
+     * Creates Date instance from DateTime instance.
+     * 
+     * @param DateTime $dateTime DateTime instance.
+     * 
+     * @return Date new Date instance.
+     */
+    public static function fromDateTime(DateTime $dateTime)
+    {
+        return new Date($dateTime->getTimestamp() * 1000);
+    }
+    
+    /**
+     * Returns the date value as DateTime instance.
+     * 
+     * @return DateTime new DateTime instance.
+     */
+    public function toDateTime(): DateTime
+    {
+        $dateTime = new DateTime();
+        $dateTime->setTimestamp($this->getSeconds());
+        return $dateTime;
+    }
+    
+    /**
+     * Returns the date value as number of milliseconds elapsed since January 1, 1970, 00:00:00 UTC.
+     * 
+     * @return float number of milliseconds elapsed since January 1, 1970, 00:00:00 UTC.
+     */
+    public function getMillis(): float
+    {
+        return $this->millis;
+    }
+    
+    /**
+     * Returns the date value as number of seconds elapsed since January 1, 1970, 00:00:00 UTC.
+     * 
+     * @return float number of seconds elapsed since January 1, 1970, 00:00:00 UTC.
+     */
+    public function getSeconds(): float
+    {
+        return $this->millis / 1000;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/7d3ea115/modules/platforms/php/src/Apache/Ignite/Data/EnumItem.php
----------------------------------------------------------------------
diff --git a/modules/platforms/php/src/Apache/Ignite/Data/EnumItem.php b/modules/platforms/php/src/Apache/Ignite/Data/EnumItem.php
new file mode 100644
index 0000000..3178006
--- /dev/null
+++ b/modules/platforms/php/src/Apache/Ignite/Data/EnumItem.php
@@ -0,0 +1,155 @@
+<?php
+/*
+ * 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.
+ */
+
+namespace Apache\Ignite\Data;
+
+use Apache\Ignite\Internal\Utils\ArgumentChecker;
+use Apache\Ignite\Exception\ClientException;
+
+/**
+ * Class representing an item of Ignite enum type.
+ *
+ * The item is defined by:
+ *   - type Id (mandatory) - Id of the Ignite enum type.
+ *   - ordinal (optional) - ordinal of the item in the Ignite enum type.
+ *   - name (optional) - name of the item (field name in the Ignite enum type).
+ *   - value (optional) - value of the item.
+ * Usually, at least one from the optional ordinal, name or value must be specified
+ * in order to use an instance of this class in Ignite operations.
+ *
+ * To distinguish one item from another, the Ignite client analyzes the optional fields in the following order:
+ * ordinal, name, value.
+ */
+class EnumItem
+{
+    private $typeId;
+    private $ordinal;
+    private $name;
+    private $value;
+    
+    /**
+     * Public constructor.
+     * 
+     * @param int $typeId Id of the Ignite enum type.
+     */
+    public function __construct(int $typeId)
+    {
+        $this->setTypeId($typeId);
+        $this->ordinal = null;
+        $this->name = null;
+        $this->value = null;
+    }
+
+    /**
+     * Returns Id of the Ignite enum type.
+     *
+     * @return int Id of the enum type.
+     */
+    public function getTypeId(): int
+    {
+        return $this->typeId;
+    }
+
+    /**
+     * Updates Id of the Ignite enum type.
+     * 
+     * @param int $typeId new Id of the Ignite enum type.
+     * 
+     * @return EnumItem the same instance of EnumItem.
+     */
+    public function setTypeId(int $typeId): EnumItem
+    {
+        $this->typeId = $typeId;
+        return $this;
+    }
+
+    /**
+     * Returns ordinal of the item in the Ignite enum type
+     * or null if ordinal is not set.
+     *
+     * @return int|null ordinal of the item in the Ignite enum type or null (if ordinal is not set).
+     */
+    public function getOrdinal(): ?int
+    {
+        return $this->ordinal;
+    }
+
+    /**
+     * Sets or updates ordinal of the item in the Ignite enum type.
+     *
+     * @param int $ordinal ordinal of the item in the Ignite enum type.
+     *
+     * @return EnumItem the same instance of EnumItem.
+     */
+    public function setOrdinal(int $ordinal): EnumItem
+    {
+        $this->ordinal = $ordinal;
+        return $this;
+    }
+
+    /**
+     * Returns name of the item
+     * or null if name is not set.
+     *
+     * @return string|null name of the item or null (if name is not set).
+     */
+    public function getName(): ?string
+    {
+        return $this->name;
+    }
+
+    /**
+     * Sets or updates name of the item.
+     *
+     * @param string $name name of the item.
+     *
+     * @return EnumItem the same instance of EnumItem.
+     *
+     * @throws ClientException if error.
+     */
+    public function setName(string $name): EnumItem
+    {
+        ArgumentChecker::notEmpty($name, 'name');
+        $this->name = $name;
+        return $this;
+    }
+
+    /**
+     * Returns value of the item
+     * or null if value is not set.
+     *
+     * @return int|null value of the item or null (if value is not set).
+     */
+    public function getValue(): ?int
+    {
+        return $this->value;
+    }
+
+    /**
+     * Sets or updates value of the item.
+     *
+     * @param int $value value of the item.
+     *
+     * @return EnumItem the same instance of EnumItem.
+     */
+    public function setValue(int $value): EnumItem
+    {
+        $this->value = $value;
+        return $this;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/7d3ea115/modules/platforms/php/src/Apache/Ignite/Data/Time.php
----------------------------------------------------------------------
diff --git a/modules/platforms/php/src/Apache/Ignite/Data/Time.php b/modules/platforms/php/src/Apache/Ignite/Data/Time.php
new file mode 100644
index 0000000..9d0388a
--- /dev/null
+++ b/modules/platforms/php/src/Apache/Ignite/Data/Time.php
@@ -0,0 +1,58 @@
+<?php
+/*
+ * 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.
+ */
+
+namespace Apache\Ignite\Data;
+
+/** 
+ * Class representing Ignite Time type
+ * (number of milliseconds elapsed since midnight, i.e. 00:00:00 UTC).
+ */
+class Time
+{
+    private $millis;
+
+    /**
+     * Public constructor.
+     * 
+     * @param int $millis number of milliseconds elapsed since midnight, i.e. 00:00:00 UTC.
+     */
+    public function __construct(int $millis)
+    {
+        $this->millis = $millis;
+    }
+    
+    /**
+     * Returns the time value as number of milliseconds elapsed since midnight, i.e. 00:00:00 UTC.
+     * 
+     * @return int number of milliseconds elapsed since midnight, i.e. 00:00:00 UTC.
+     */
+    public function getMillis(): int
+    {
+        return $this->millis;
+    }
+
+    /**
+     * Returns the time value as number of seconds elapsed since midnight, i.e. 00:00:00 UTC.
+     * 
+     * @return int number of seconds elapsed since midnight, i.e. 00:00:00 UTC.
+     */
+    public function getSeconds(): int
+    {
+        return $this->millis / 1000;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/7d3ea115/modules/platforms/php/src/Apache/Ignite/Data/Timestamp.php
----------------------------------------------------------------------
diff --git a/modules/platforms/php/src/Apache/Ignite/Data/Timestamp.php b/modules/platforms/php/src/Apache/Ignite/Data/Timestamp.php
new file mode 100644
index 0000000..39ef984
--- /dev/null
+++ b/modules/platforms/php/src/Apache/Ignite/Data/Timestamp.php
@@ -0,0 +1,64 @@
+<?php
+/*
+ * 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.
+ */
+
+namespace Apache\Ignite\Data;
+
+use \DateTime;
+
+/** 
+ * Class representing Ignite Timestamp type
+ * (Ignite Date with additional nanoseconds fraction of the last millisecond).
+ */
+class Timestamp extends Date
+{
+    private $nanos;
+
+    /**
+     * Public constructor.
+     * 
+     * @param float $millis integer number of milliseconds elapsed since January 1, 1970, 00:00:00 UTC.
+     * @param int $nanos nanoseconds of the last millisecond, should be in the range from 0 to 999999.
+     */
+    public function __construct(float $millis, int $nanos)
+    {
+        parent::__construct($millis);
+        $this->nanos = $nanos;
+    }
+    
+    /**
+     * Creates Timestamp instance from DateTime instance.
+     * 
+     * @param DateTime $dateTime DateTime instance.
+     * 
+     * @return Timestamp new Timestamp instance.
+     */
+    public static function fromDateTime(DateTime $dateTime)
+    {
+        return new Timestamp($dateTime->getTimestamp() * 1000, 0);
+    }
+    
+    /**
+     * Returns the nanoseconds of the last millisecond from the timestamp.
+     * 
+     * @return int nanoseconds of the last millisecond.
+     */
+    public function getNanos(): int
+    {
+        return $this->nanos;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/7d3ea115/modules/platforms/php/src/Apache/Ignite/Exception/ClientException.php
----------------------------------------------------------------------
diff --git a/modules/platforms/php/src/Apache/Ignite/Exception/ClientException.php b/modules/platforms/php/src/Apache/Ignite/Exception/ClientException.php
new file mode 100644
index 0000000..88fe56b
--- /dev/null
+++ b/modules/platforms/php/src/Apache/Ignite/Exception/ClientException.php
@@ -0,0 +1,35 @@
+<?php
+/*
+ * 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.
+ */
+
+namespace Apache\Ignite\Exception;
+
+/**
+ * Ignite client general exception.
+ */
+class ClientException extends \Exception
+{
+    /**
+     * Constructs a ClientException with the specified detail message.
+     * 
+     * @param string $message the detail message.
+     */
+    public function __construct(string $message)
+    {
+        parent::__construct($message);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/7d3ea115/modules/platforms/php/src/Apache/Ignite/Exception/NoConnectionException.php
----------------------------------------------------------------------
diff --git a/modules/platforms/php/src/Apache/Ignite/Exception/NoConnectionException.php b/modules/platforms/php/src/Apache/Ignite/Exception/NoConnectionException.php
new file mode 100644
index 0000000..04a7580
--- /dev/null
+++ b/modules/platforms/php/src/Apache/Ignite/Exception/NoConnectionException.php
@@ -0,0 +1,35 @@
+<?php
+/*
+ * 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.
+ */
+
+namespace Apache\Ignite\Exception;
+
+/**
+ * Ignite client is not connected.
+ */
+class NoConnectionException extends ClientException
+{
+    /**
+     * Constructs a NoConnectionException with the specified detail message.
+     * 
+     * @param string $message the detail message.
+     */
+    public function __construct(string $message = null)
+    {
+        parent::__construct($message ? $message : 'Operation is not completed due to the connection problem');
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/7d3ea115/modules/platforms/php/src/Apache/Ignite/Exception/OperationException.php
----------------------------------------------------------------------
diff --git a/modules/platforms/php/src/Apache/Ignite/Exception/OperationException.php b/modules/platforms/php/src/Apache/Ignite/Exception/OperationException.php
new file mode 100644
index 0000000..49862e7
--- /dev/null
+++ b/modules/platforms/php/src/Apache/Ignite/Exception/OperationException.php
@@ -0,0 +1,35 @@
+<?php
+/*
+ * 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.
+ */
+
+namespace Apache\Ignite\Exception;
+
+/**
+ * Ignite server returns error for the requested operation.
+ */
+class OperationException extends ClientException
+{
+    /**
+     * Constructs an OperationException with the specified detail message.
+     * 
+     * @param string $message the detail message.
+     */
+    public function __construct(string $message)
+    {
+        parent::__construct($message);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/7d3ea115/modules/platforms/php/src/Apache/Ignite/Exception/OperationStatusUnknownException.php
----------------------------------------------------------------------
diff --git a/modules/platforms/php/src/Apache/Ignite/Exception/OperationStatusUnknownException.php b/modules/platforms/php/src/Apache/Ignite/Exception/OperationStatusUnknownException.php
new file mode 100644
index 0000000..74aab6d
--- /dev/null
+++ b/modules/platforms/php/src/Apache/Ignite/Exception/OperationStatusUnknownException.php
@@ -0,0 +1,35 @@
+<?php
+/*
+ * 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.
+ */
+
+namespace Apache\Ignite\Exception;
+
+/**
+ * Status of the requested operation is unknown (eg. due to a connection problem during the operation). 
+ */
+class OperationStatusUnknownException extends ClientException
+{
+    /**
+     * Constructs an OperationStatusUnknownException with the specified detail message.
+     * 
+     * @param string $message the detail message.
+     */
+    public function __construct(string $message)
+    {
+        parent::__construct($message);
+    }
+}