From 5f2d3003d0c52601623a0f1b812a085c128095d7 Mon Sep 17 00:00:00 2001
From: Konstantin Shulgin <konstantin.shulgin@gmail.com>
Date: Fri, 16 Dec 2011 15:08:38 +0400
Subject: [PATCH] feature-php-driver-improve:

initial implementarion of new php driver.
---
 connector/php/exampleCall.php                 |   37 -
 connector/php/exampleInsert.php               |   66 -
 connector/php/exampleSelect.php               |  100 -
 connector/php/exampleUpdate.php               |   98 -
 connector/php/tarantool.c                     | 3232 ++++++++---------
 connector/php/tarantool.h                     |  199 +-
 connector/php/test/admin.phpt                 |  112 +
 connector/php/test/bin/run-test.bash          |  204 ++
 connector/php/test/call.phpt                  |   93 +
 connector/php/test/delete.phpt                |  125 +
 connector/php/test/errors.phpt                |   26 +
 connector/php/test/etc/php.ini                | 1851 ++++++++++
 connector/php/test/etc/tarantool_box.cfg      |   55 +
 connector/php/test/insert.phpt                |  173 +
 connector/php/test/lib/lua/test.lua           |   25 +
 .../php/test/lib/php/tarantool_utest.php      |  183 +
 connector/php/test/run-test                   |    1 +
 connector/php/test/select.phpt                |  346 ++
 connector/php/test/update_fields.phpt         |   96 +
 19 files changed, 4986 insertions(+), 2036 deletions(-)
 delete mode 100644 connector/php/exampleCall.php
 delete mode 100644 connector/php/exampleInsert.php
 delete mode 100644 connector/php/exampleSelect.php
 delete mode 100644 connector/php/exampleUpdate.php
 create mode 100644 connector/php/test/admin.phpt
 create mode 100755 connector/php/test/bin/run-test.bash
 create mode 100644 connector/php/test/call.phpt
 create mode 100644 connector/php/test/delete.phpt
 create mode 100644 connector/php/test/errors.phpt
 create mode 100644 connector/php/test/etc/php.ini
 create mode 100644 connector/php/test/etc/tarantool_box.cfg
 create mode 100644 connector/php/test/insert.phpt
 create mode 100644 connector/php/test/lib/lua/test.lua
 create mode 100644 connector/php/test/lib/php/tarantool_utest.php
 create mode 120000 connector/php/test/run-test
 create mode 100644 connector/php/test/select.phpt
 create mode 100644 connector/php/test/update_fields.phpt

diff --git a/connector/php/exampleCall.php b/connector/php/exampleCall.php
deleted file mode 100644
index d02a7dda72..0000000000
--- a/connector/php/exampleCall.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-define("NMSPACE", 0);
-
-if(!extension_loaded('tarantool')) {
-	dl('tarantool.so');
-}
-
-/**
- *  Tarantool::constructor
- * 
- *  @param optional string host default 127.0.0.1
- *  @param optional number port default 33013
- */
-$tnt = new Tarantool('localhost');
-
-/**
- *  Tarantool::call
- * 
- *  @param procname procedure namei
- *  @param array    procedure argumetns
- * 
- *  @return count of tuples
- */
-$tuple = array('test', 'x', 'abd', 1023);
-
-$res = $tnt->insert(NMSPACE, $tuple);
-
-$tuple = array(NMSPACE, 0, 'test');
-
-$res = $tnt->call("box.select", $tuple);
-
-var_dump($res);
-
-while(($res = $tnt->getTuple()) != false) {
-    var_dump($res);
-}
diff --git a/connector/php/exampleInsert.php b/connector/php/exampleInsert.php
deleted file mode 100644
index 2766fd65ed..0000000000
--- a/connector/php/exampleInsert.php
+++ /dev/null
@@ -1,66 +0,0 @@
-<?php
-if(!extension_loaded('tarantool')) {
-	dl('tarantool.so');
-}
-
-define("NMSPACE", 0);
-
-$tnt = new Tarantool('tfn24');
-$res=0;
-
-/**
- *  Tarantool::insert
- * 
- *  @param namespace
- *  @param array of tuple
- * 
- *  @return result
- */
-
-
-$tuple = array(1, 'x','abd', 1023 );
-$res += $tnt->insert(NMSPACE, $tuple);
-
-$tuple = array(2, 'z','abd', 1023 );
-$res += $tnt->insert(NMSPACE,$tuple);
-
-$tuple = array(3, 'z','abc', 1025 );
-$res += $tnt->insert(NMSPACE,$tuple);
-
-$tuple = array(4, 'y','abd', 1025 );
-$res += $tnt->insert(NMSPACE,$tuple);
-
-$tuple = array(5, 'y','abc', 1025 );
-$res += $tnt->insert(NMSPACE,$tuple);
-
-$tuple = array(6, 'x','abd', 1025 );
-$res += $tnt->insert(NMSPACE,$tuple);
-
-$tuple = array(7, 'x','abc', 1025 );
-$res += $tnt->insert(NMSPACE,$tuple);
-
-$tuple = array(8, 'x','abd', 1025 );
-$res += $tnt->insert(NMSPACE,$tuple);
-
-$tuple = array(9, 'x','abc', 1024 );
-$res += $tnt->insert(NMSPACE,$tuple);
-
-$tuple = array(9, 'x','abc', 1024 );
-$res += $tnt->insert(NMSPACE,$tuple);
-echo "inserted $res tuples\n";
-
-$tuple = array('9', 66,65, 1024 );
-$res = $tnt->insert(NMSPACE,$tuple);
-if (!$res)
-    echo $tnt->getError();
-else    
-    echo "inserted $res tuples\n";
-    
-$tuple = array(10, 66,65, 'xdf' );
-$res = $tnt->insert(NMSPACE,$tuple);
-
-if (!$res)
-    echo $tnt->getError();
-else    
-    echo "inserted $res tuples\n";
-    
\ No newline at end of file
diff --git a/connector/php/exampleSelect.php b/connector/php/exampleSelect.php
deleted file mode 100644
index f3b3c1c58f..0000000000
--- a/connector/php/exampleSelect.php
+++ /dev/null
@@ -1,100 +0,0 @@
-<?php
-
-define("NMSPACE", 0);
-define("PRIMARYINDEX", 0);
-define("INDEX_1", 1);
-define("INDEX_2", 2);
-define("INDEX_3", 3);
-
-
-if(!extension_loaded('tarantool')) {
-	dl('tarantool.so');
-}
-
-$res = true;
-
-/**
- *  Tarantool::constructor
- * 
- *  @param optional string host default 127.0.0.1
- *  @param optional number port default 33013
- */
-$tnt = new Tarantool('tfn24');
-
-echo 'single tuple select by primary key (key=1)', PHP_EOL;
-
-/**
- *  Tarantool::select
- * 
- *  @param number namespace
- *  @param number index No 
- *  @param mixed key 
- *  @param optional limit default all
- *  @param optional offset default 0
- * 
- *  @return count of tuples
- */
-$res = $tnt->select(NMSPACE,PRIMARYINDEX,1); // namespace,index, key
-var_dump($res);
-$res = $tnt->getTuple();
-var_dump($res);
-
-
-echo "some tuple select by fielNo[1] = 'x'\n";
-$res = $tnt->select(NMSPACE,INDEX_1,'x'); // namespace,index, key
-var_dump($res);
-
-while( ($res = $tnt->getTuple()) != false){
-    var_dump($res);
-}
-
-echo "some tuple select by index = 2  (fielNo[1] = 'x' and fielNo[2] = 'abc')\n";
-$res = $tnt->select(NMSPACE,INDEX_2,array('x', 'abc')); // namespace,index, key
-var_dump($res);
-
-while( ($res = $tnt->getTuple()) != false){
-    var_dump($res);
-}
-
-echo "some tuple select by index = 3  (fielNo[3] = 1025)\n";
-$res = $tnt->select(NMSPACE,INDEX_3,1025); // namespace,index, key
-var_dump($res);
-
-while( ($res = $tnt->getTuple()) != false){
-    var_dump($res);
-}
-
-echo "some tuple select by index = 3  (fielNo[3] = 1025) LIMIT=3\n";
-$res = $tnt->select(NMSPACE,INDEX_3,1025,3); // namespace,index, key, limit
-var_dump($res);
-
-while( ($res = $tnt->getTuple()) != false){
-    var_dump($res);
-}
-
-echo "some tuple select by index = 3  (fielNo[3] = 1025) NEXT 3 (offset=3, limit=3)\n";
-$res = $tnt->select(NMSPACE,INDEX_3,1025,3,3); // namespace,index, key, limit, offset
-var_dump($res);
-
-while( ($res = $tnt->getTuple()) != false){
-    var_dump($res);
-}
-
-// multi select
-/// SELECT * FROM t0 WHERE k0 IN (1,2) 
-$count = $tnt->mselect(NMSPACE,PRIMARYINDEX, array(1,2)); // ns, idx , keys, [limit, offset]  
-print "count=$count\n";
-while ( false != ($res = $tnt->getTuple())) {    
-    var_dump($res);  
-}
-
-/// SELECT * FROM t0 WHERE k1 IN ('x','z') 
-$count = $tnt->mselect(NMSPACE,INDEX_1, array('x','z')); // ns, idx , keys, [limit, offset]
-print "count=$count\n";
-while ( false != ($res = $tnt->getTuple())) {    
-    var_dump($res);  
-}
-
-
-
-
diff --git a/connector/php/exampleUpdate.php b/connector/php/exampleUpdate.php
deleted file mode 100644
index 0d07f62091..0000000000
--- a/connector/php/exampleUpdate.php
+++ /dev/null
@@ -1,98 +0,0 @@
-<?php
-
-define("NMSPACE", 0);
-define("PRIMARYINDEX", 0);
-
-define("FIELD_1", 1);
-define("FIELD_2", 2);
-define("FIELD_3", 3);
-
-if(!extension_loaded('tarantool')) {
-	dl('tarantool.so');
-}
-
-$res = true;
-
-// constructor(host,port);
-$tnt = new Tarantool('tfn24');
-
-$tnt->select(NMSPACE,PRIMARYINDEX,1);
-$tuple = $tnt->getTuple();
-var_dump($tuple);
-
-/**
- *  Tarantool::inc
- * 
- *  @param namespace
- *  @param primary key
- *  @param field No for increment
- *  @param optional incremental data default +1
- * 
- *  @return bool result
- */
-// increment
-$tnt->inc(NMSPACE,1,FIELD_3);
-
-$tnt->select(NMSPACE,PRIMARYINDEX,1);
-$tuple = $tnt->getTuple();
-var_dump($tuple);
-
-
-// duble increment (+2)
-$tnt->inc(NMSPACE,1,FIELD_3,2);
-
-$tnt->select(NMSPACE,PRIMARYINDEX,1);
-$tuple = $tnt->getTuple();
-var_dump($tuple);
-
-
-// decrement
-$res = $tnt->inc(NMSPACE,1,FIELD_3,-1);
-echo "increment tuple res=$res\n";
-
-$tnt->select(NMSPACE,PRIMARYINDEX,1);
-$tuple = $tnt->getTuple();
-var_dump($tuple);
-
-// error, type inxex must be NUM 
-$res = $tnt->inc(NMSPACE,1,FIELD_2);
-echo "increment tuple res=$res\n";
-if (!$res)
-    echo $tnt->getError();
-$tnt->select(NMSPACE,PRIMARYINDEX,1);
-$tuple = $tnt->getTuple();
-var_dump($tuple);
-
-/**
- *  Tarantool::update
- * 
- *  @param namespace
- *  @param primary key
- *  @param array of new data:
- *          array( fieldNo => newValue, ... )
- * 
- *  @return bool result
- */
-$res = $tnt->update(NMSPACE,1,array(2=>'y'));
-echo "update tuple res=$res\n";
-
-$tnt->select(NMSPACE,0,1);
-$tuple = $tnt->getTuple();
-var_dump($tuple);
-
-
-$res = $tnt->update(NMSPACE,1,array(1 => 'z', 2=>'abc'));
-echo "update tuple res=$res\n";
-
-$tnt->select(NMSPACE,0,1);
-$tuple = $tnt->getTuple();
-var_dump($tuple);
-
-
-// Error  type inxex 0 must be NUM 
-$res = $tnt->update(NMSPACE,1,array(0 => 'z', 2=>'abc'));
-echo "update tuple res=$res\n";
-if (!$res)
-    echo $tnt->getError();
-
-
diff --git a/connector/php/tarantool.c b/connector/php/tarantool.c
index b9b917c959..fc1a825dcb 100644
--- a/connector/php/tarantool.c
+++ b/connector/php/tarantool.c
@@ -16,197 +16,152 @@
   | Copyright (c) 2011                                                   |
   +----------------------------------------------------------------------+
 */
-
-/* $Id: header 252479 2008-02-07 19:39:50Z iliaa $ */
-
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
+#include <stdint.h>
+#include <stdbool.h>
 #include <netinet/in.h>
 #include <netdb.h>
+#include <inttypes.h>
 
-#include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
-#include "zend_exceptions.h"
+#include <php.h>
+#include <php_ini.h>
+#include <ext/standard/info.h>
+#include <zend_exceptions.h>
 
 #include "tarantool.h"
 
-/* If you declare any globals in php_tarantool.h uncomment this:
-ZEND_DECLARE_MODULE_GLOBALS(tarantool)
-*/
-
-/* True global resources - no need for thread safety here */
-static int le_tarantool;
-
-zend_class_entry *tarantool_class_entry;
-
-typedef  struct {
-		uint32_t type;
-		uint32_t len;
-		uint32_t request_id;
-} Header;
-
-typedef struct _tarantool_object {
-	zend_object  zo;
-	char * host;		//	tarantool host
-	int port;			//  tarantool port
-	int admin_port;		//  tarantool admin port
-	int bodyLen;		// body len from tuples header
-	int countTuples;	// count tuples
-	int readedTuples;	//
-	int readed;			// readed byte
-	uint32_t errorcode;		// error code
-	php_stream * stream;
-	php_stream * admin_stream;
-} tarantool_object;
-
-#define HEADER_SIZE sizeof(Header)
-
-typedef union {
-	u_char b;
-	uint32_t  i;
-} b2i;
-
-typedef	struct {
-	uint32_t count;
-	u_char data[];
-} Tuple;
-
-typedef	struct {
-	uint32_t fieldNo;
-	int8_t code;
-	u_char arg[];
-} Operation;
-
-
-// sizeof(spaceNo) + sizeof(flag) + sizeof(tuple.count)
-#define INSERT_REQUEST_SIZE 12
-typedef	struct {
-	uint32_t spaceNo;
-	uint32_t flag;
-	Tuple tuple;
-} InsertRequest;
-
-typedef	struct {
-	uint32_t spaceNo;
-	Tuple tuple;
-} DeleteRequest;
-
-
-// sizeof(count) + sizeof(operation.fieldNo) + sizeof(operation.code) +1 // 10
-#define UPDATE_REQUEST_SIZE 10
-typedef	struct {
-	uint32_t count;
-	Operation operation;
-} UpdateRequest;
-
-
 
-#define SELECT_REQUEST_SIZE 20
-typedef	struct {
-	uint32_t spaceNo;
-	uint32_t indexNo;
-	uint32_t offset;
-	uint32_t limit;
-	uint32_t count;
-	char	 tuples[];
-} SelectRequest;
-
-typedef	struct {
-	uint32_t len;
-	Tuple tuple;
-} FTuple;
-
-
-typedef	struct {
-	uint32_t code;			// request error code
-	uint32_t tuples_count;	// count of tuples
-} SelectResponseBody;
-
-
-#define SELECT_RESPONSE_SIZE sizeof(SelectResponseTuple)
-typedef	struct {
-	uint32_t size;			// tuple size in bytes
-	uint32_t count;			// count elements in tuple
-} SelectResponseTuple;
-
-typedef	struct {
-	uint32_t code;
-	uint32_t count;
-	char data[];
-} Response;
-
-//typedef	struct {
-//	uint32_t code;
-//	uint32_t count;
-//	char data[];
-//} UpdateResponse;
-
-
-static void printLine( u_char *p );
-static void printLine3( u_char *p );
-
-static void
-leb128_write(char * buf, unsigned long value);
-
-static int
-leb128_size(unsigned long value);
-
-static int
-leb128_read(char * buf, int size, unsigned long * value);
-
-/* {{{ tarantool_functions[]
- *
- * Every user visible function must have an entry in tarantool_functions[].
- */
-const zend_function_entry tarantool_functions[] = {
-	 PHP_ME(tarantool_class, __construct, NULL, ZEND_ACC_PUBLIC)
-	{NULL, NULL, NULL}
+/*============================================================================*
+ * Tarantool extension structures defintion
+ *============================================================================*/
+
+/* I/O buffer */
+struct io_buf {
+	/* buffer's size */
+	size_t size;
+    /* buffer's capacity */
+	size_t capacity;
+	/* read position in the I/O buffer */
+	size_t readed;
+	/* buffer value */
+	uint8_t *value;
 };
 
-zend_function_entry tarantool_class_functions[] = {
-	 PHP_ME(tarantool_class, __construct,	NULL, ZEND_ACC_PUBLIC)
-
-	 PHP_ME(tarantool_class, insert,		NULL, ZEND_ACC_PUBLIC)
-	 PHP_ME(tarantool_class, select,		NULL, ZEND_ACC_PUBLIC)
-	 PHP_ME(tarantool_class, mselect,		NULL, ZEND_ACC_PUBLIC)
-	 PHP_ME(tarantool_class, call,			NULL, ZEND_ACC_PUBLIC)
-	 PHP_ME(tarantool_class, getTuple,		NULL, ZEND_ACC_PUBLIC)
-	 PHP_ME(tarantool_class, delete,		NULL, ZEND_ACC_PUBLIC)
-	 PHP_ME(tarantool_class, update,		NULL, ZEND_ACC_PUBLIC)
-	 PHP_ME(tarantool_class, inc,		NULL, ZEND_ACC_PUBLIC)
-	 PHP_ME(tarantool_class, getError,		NULL, ZEND_ACC_PUBLIC)
-	 PHP_ME(tarantool_class, getInfo,		NULL, ZEND_ACC_PUBLIC)
-	 PHP_ME(tarantool_class, getStat,		NULL, ZEND_ACC_PUBLIC)
-	 PHP_ME(tarantool_class, getConf,		NULL, ZEND_ACC_PUBLIC)
+/* tarantool object */
+typedef struct tarantool_object {
+	zend_object zo;
+	/* host name */
+	char *host;
+	/* tarantool primary port */
+	int port;
+	/* tarantool admin port */
+	int admin_port;
+	/* tarantool primary connection */
+	php_stream *stream;
+	/* tarantool admin connecion */
+	php_stream *admin_stream;
+	/* I/O buffer */
+	struct io_buf *io_buf;
+	/* additional buffer for splice args */
+	struct io_buf *splice_field;
+} tarantool_object;
+
+/* iproto header */
+struct iproto_header {
+	/* command code */
+	uint32_t type;
+	/* command length */
+	uint32_t length;
+	/* request id */
+	uint32_t request_id;
+} __attribute__((packed));
+
+/* tarantool select command request */
+struct tnt_select_request {
+	/* space number */
+	int32_t space_no;
+	/* index number */
+	int32_t index_no;
+	/* select offset from begining */
+	int32_t offset;
+	/* maximail number tuples in responce */
+	int32_t limit;
+} __attribute__((packed));
+
+/* tarantool insert command request */
+struct tnt_insert_request {
+	/* space number */
+	int32_t space_no;
+	/* flags */
+	int32_t flags;
+} __attribute__((packed));
+
+/* tarantool update fields command request */
+struct tnt_update_fields_request {
+	/* space number */
+	int32_t space_no;
+	/* flags */
+	int32_t flags;
+} __attribute__((packed));
+
+/* tarantool delete command request */
+struct tnt_delete_request {
+	/* space number */
+	int32_t space_no;
+	/* flags */
+	int32_t flags;
+} __attribute__((packed));
+
+/* tarantool call command request */
+struct tnt_call_request {
+	/* flags */
+	int32_t flags;
+} __attribute__((packed));
+
+/* tarantool command response */
+struct tnt_response {
+	/* return code */
+	int32_t return_code;
+	/* count */
+	int32_t count;
+} __attribute__((packed));
+
+
+/*============================================================================*
+ * Global variables definition
+ *============================================================================*/
+
+
+/*----------------------------------------------------------------------------*
+ * Tarantool module variables
+ *----------------------------------------------------------------------------*/
+
+/* module functions list */
+zend_function_entry tarantool_module_functions[] = {
+	PHP_ME(tarantool_class, __construct, NULL, ZEND_ACC_PUBLIC)
 	{NULL, NULL, NULL}
 };
 
-
-/* }}} */
-
-/* {{{ tarantool_module_entry
- */
+/* tarantool module struct */
 zend_module_entry tarantool_module_entry = {
 #if ZEND_MODULE_API_NO >= 20010901
 	STANDARD_MODULE_HEADER,
 #endif
 	"tarantool",
-	tarantool_functions,
+	tarantool_module_functions,
 	PHP_MINIT(tarantool),
 	PHP_MSHUTDOWN(tarantool),
 	NULL,
 	NULL,
 	PHP_MINFO(tarantool),
 #if ZEND_MODULE_API_NO >= 20010901
-	"0.1", /* Replace with version number for your extension */
+	"1.0",
 #endif
 	STANDARD_MODULE_PROPERTIES
 };
-/* }}} */
-
 
 
 #ifdef COMPILE_DL_TARANTOOL
@@ -214,1875 +169,1798 @@ ZEND_GET_MODULE(tarantool)
 #endif
 
 
-static int php_tnt_connect( tarantool_object *ctx TSRMLS_DC) {
-			// open stream
-		struct timeval tv;
-		tv.tv_sec = TARANTOOL_TIMEOUT;
-		tv.tv_usec = 0;
+/*----------------------------------------------------------------------------*
+ * Tarantool class variables
+ *----------------------------------------------------------------------------*/
 
-		char * errstr = NULL, *hostname = NULL;
-		int   err = 0, hostname_len;
+/* tarantool class methods */
+const zend_function_entry tarantool_class_methods[] = {
+	PHP_ME(tarantool_class, __construct, NULL, ZEND_ACC_PUBLIC)
+	PHP_ME(tarantool_class, select, NULL, ZEND_ACC_PUBLIC)
+	PHP_ME(tarantool_class, insert, NULL, ZEND_ACC_PUBLIC)
+	PHP_ME(tarantool_class, update_fields, NULL, ZEND_ACC_PUBLIC)
+	PHP_ME(tarantool_class, delete, NULL, ZEND_ACC_PUBLIC)
+	PHP_ME(tarantool_class, call, NULL, ZEND_ACC_PUBLIC)
+	PHP_ME(tarantool_class, admin, NULL, ZEND_ACC_PUBLIC)
+	{NULL, NULL, NULL}
+};
 
-		if (ctx->port) {
-			hostname_len = spprintf(&hostname, 0, "tcp://%s:%d", ctx->host, ctx->port);
-		} else {
-			php_printf("port undefined\n");
-		}
+/* tarantool class */
+zend_class_entry *tarantool_class_ptr;
 
 
-		ctx->stream = php_stream_xport_create( hostname, hostname_len,
-											   ENFORCE_SAFE_MODE | REPORT_ERRORS,
-											   STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT,
-											   NULL, &tv, NULL, &errstr, &err);
+/*============================================================================*
+ * local functions declaration
+ *============================================================================*/
 
-		efree(hostname);
 
-		if (err && errstr) {
-			php_printf("stream error: %s\n", errstr);
-			ctx->stream = NULL;
-			efree(errstr);
-		}
+/*----------------------------------------------------------------------------*
+ * I/O buffer interface
+ *----------------------------------------------------------------------------*/
 
-		if (!ctx->stream) {
-			return 1;
-		}
+/* create I/O buffer instance */
+static struct io_buf *
+io_buf_create();
 
-		return 0;
-}
+/* destroy I/O buffer */
+static void
+io_buf_destroy(struct io_buf *buf);
 
-static int php_tnt_admin_connect( tarantool_object *ctx TSRMLS_DC) {
-			// open stream
-		struct timeval tv;
-		tv.tv_sec = TARANTOOL_TIMEOUT;
-		tv.tv_usec = 0;
+/* reserv I/O buffer space */
+inline static bool
+io_buf_reserve(struct io_buf *buf, size_t n);
 
-		char * errstr = NULL, *hostname = NULL;
-		int   err = 0, hostname_len;
+/* resize I/O buffer */
+inline static bool
+io_buf_resize(struct io_buf *buf, size_t n);
 
-		if (ctx->admin_port) {
-			hostname_len = spprintf(&hostname, 0, "tcp://%s:%d", ctx->host, ctx->admin_port);
-		} else {
-			php_printf("admin port undefined\n");
-		}
+/* calculate next capacity for I/O buffer */
+inline static size_t
+io_buf_next_capacity(size_t n);
 
-		ctx->admin_stream = php_stream_xport_create( hostname, hostname_len,
-											   ENFORCE_SAFE_MODE | REPORT_ERRORS,
-											   STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT,
-											   NULL, &tv, NULL, &errstr, &err);
+/* clean I/O buffer */
+static void
+io_buf_clean(struct io_buf *buf);
 
-		efree(hostname);
+/* read struct from buffer */
+static bool
+read_struct_io_buf(struct io_buf *buf, void **ptr, size_t n);
 
-		if (err && errstr) {
-			php_printf("stream error: %s\n", errstr);
-			ctx->admin_stream = NULL;
-			efree(errstr);
-		}
+/* read integer from buffer */
+static bool
+read_int_io_buf(struct io_buf *buf, int32_t *val);
 
-		if (!ctx->admin_stream) {
-			return 1;
-		}
+/* read var integer from buffer */
+static bool
+read_varint_io_buf(struct io_buf *buf, int32_t *val);
 
-		return 0;
-}
+/* read string from buffer */
+static bool
+read_str_io_buf(struct io_buf *buf, char **str, size_t len);
 
-/* {{{ proto tarantool::__construct( string string host=localhost, int port=PORT, int admin_port=ADMIN_PORT)
-   tarantool constructor */
-PHP_METHOD(tarantool_class, __construct)
-{
-	zval *id;
-	tarantool_object *ctx;
+/* read fied from buffer */
+static bool
+read_field_io_buf(struct io_buf *buf, zval *tuple);
 
+/* read tuple from buffer */
+static bool
+read_tuple_io_buf(struct io_buf *buf, zval **tuple);
 
-	zval** zdata; //??????
+/*
+ * Write to I/O buffer functions
+ */
 
-	char * host = NULL;
-	int host_len = 0;
-	long port=0, admin_port=0;
+/* write struct to I/O buffer */
+static void *
+io_buf_write_struct(struct io_buf *buf, size_t n);
 
-	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|sll",
-			&id, tarantool_class_entry, &host, &host_len, &port, &admin_port) == FAILURE) {
-		return;
-	}
+/* write byte to I/O buffer */
+static bool
+io_buf_write_byte(struct io_buf *buf, int8_t value);
 
-	ctx = (tarantool_object *)zend_object_store_get_object(id TSRMLS_CC);
-	ctx->host = NULL;
-	ctx->port = 0;
-	ctx->admin_port = 0;
-	ctx->stream = NULL;
-	ctx->bodyLen = 0;
-	ctx->errorcode = 0;
+/* write int32 to I/O buffer */
+static bool
+io_buf_write_int32(struct io_buf *buf, int32_t value);
 
-	if (host_len > 0)
-		ctx->host = estrdup(host);
-	else
-		ctx->host = estrdup(TARANTOOL_DEF_HOST);
+/* write varint to I/O buffer */
+static bool
+io_buf_write_varint(struct io_buf *buf, int32_t value);
 
-	if (port)
-		ctx->port = port;
-	else
-		ctx->port = TARANTOOL_DEF_PORT;
+/* write string to I/O buffer */
+static bool
+io_buf_write_str(struct io_buf *buf, uint8_t *str, size_t len);
 
-	if (admin_port)
-		ctx->admin_port = admin_port;
-	else
-		ctx->admin_port = TARANTOOL_ADMIN_PORT;
+/* write tuple to I/O buffer */
+static bool
+io_buf_write_tuple_int(struct io_buf *buf, zval *tuple);
 
-}
-/* }}} */
+/* write tuple's field to I/O buffer */
+static bool
+io_buf_write_field(struct io_buf *buf, uint8_t *val, size_t len);
 
+/* write tuple (string) to I/O buffer */
+static bool
+io_buf_write_tuple_str(struct io_buf *buf, zval *tuple);
 
+/* write tuple (array) to I/O buffer */
+static bool
+io_buf_write_tuple_array(struct io_buf *buf, zval *tuple);
 
-/* {{{ proto int tarantool::insert(int space, int index, zval tuple);
-insert tuple
-*/
-PHP_METHOD(tarantool_class, insert )
-{
-	zval *id;
-	tarantool_object *ctx;
-	long space;
-	zval * tuple;
-	HashTable *pht;
-	HashPosition pos;
-	zval **curr;
-
-	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ola", &id,
-		tarantool_class_entry, &space, &tuple) == FAILURE) {
-		return;
-	}
+/* write tuple to I/O buffer */
+static bool
+io_buf_write_tuple(struct io_buf *buf, zval *tuple);
 
-	ctx = (tarantool_object *)zend_object_store_get_object(id TSRMLS_CC);
+/* write array of tuples to I/O buffer */
+static bool
+io_buf_write_tuples_list_array(struct io_buf *buf, zval *tuples_list);
 
-	if (!ctx->stream) {
-		if (php_tnt_connect(ctx TSRMLS_CC)) {
-			zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-				"the can't open remote host " ,0 TSRMLS_DC);
-			return;
-		}
-	}
+/* write tuples list to I/O buffer */
+static bool
+io_buf_write_tuples_list(struct io_buf *buf, zval *tuples_list);
 
-	pht = Z_ARRVAL_P(tuple);
-	int num = zend_hash_num_elements(pht);
 
-	char * out_buf = emalloc(TARANTOOL_BUFSIZE);
-	bzero(out_buf, TARANTOOL_BUFSIZE);
+/*----------------------------------------------------------------------------*
+ * alloc/free classes functions
+ *----------------------------------------------------------------------------*/
 
-	Header * header = (Header *) out_buf;
-	InsertRequest * insert = (InsertRequest *) (out_buf + HEADER_SIZE);
+/* tarantool class instance allocator */
+static zend_object_value
+alloc_tarantool_object(zend_class_entry *entry TSRMLS_DC);
 
-	header->type		= TARANTOOL_INSERT;
-	header->request_id	= TARANTOOL_REQUEST_ID;
+/* free tarantool class instance */
+static void
+free_tarantool_object(tarantool_object *tnt TSRMLS_DC);
 
-	insert->spaceNo = space;
-	insert->tuple.count = num; // count Tuples
 
-	u_char * p = (u_char *) insert->tuple.data;
+/*----------------------------------------------------------------------------*
+ * raise exceation functions
+ *----------------------------------------------------------------------------*/
 
-    for(zend_hash_internal_pointer_reset_ex(pht, &pos);
-          zend_hash_get_current_data_ex(pht, (void **) &curr, &pos) == SUCCESS;
-          zend_hash_move_forward_ex(pht, &pos)) {
+/* raise exception */
+static void
+raise_exception(const char *format, ...);
 
-		if (Z_TYPE_PP(curr) == IS_STRING)  {
-			char * strval = Z_STRVAL_PP(curr);
-			int str_len = Z_STRLEN_PP(curr);
 
-			u_char str_shortlen = (u_char)str_len;
+/*----------------------------------------------------------------------------*
+ * php stream functions
+ *----------------------------------------------------------------------------*/
 
-			*(p++) = str_shortlen;
-			memcpy(p, strval, str_len);
-			p += str_len;
-		}
-		if (Z_TYPE_PP(curr) == IS_LONG)  {
-		   unsigned long val = Z_LVAL_PP(curr);
-
-//		   u_char leb_size = (u_char)leb128_size( val);
-//		   *(p++) = leb_size;
-//		   leb128_write( (char *)p, val);
-//		   p += leb_size;
-			u_char leb_size = 4;
-			*(p++) = leb_size;
-			b2i * pval = (b2i*) p;
-			pval->i = (int) val;
-			p += leb_size;
-		}
-    }
+/* establic connection */
+static php_stream *
+establish_connection(char *host, int port);
 
-	header->len = INSERT_REQUEST_SIZE + (p-insert->tuple.data); // 12 = 3 * sizeof(int32) :ns, flag & cardinality
+/* send administation command request */
+static bool
+send_admin_request(php_stream *stream, struct io_buf *buf);
 
-	// write header
-	int len = php_stream_write(ctx->stream, out_buf , sizeof(Header)); // 12
+/* receive administration command response */
+static bool
+recv_admin_response(php_stream *stream, struct io_buf *buf);
 
-	// write tuple
-	p = (u_char*)insert;
-	len = php_stream_write(ctx->stream, (char*)p , header->len );
+/* send request by iproto */
+static bool
+send_iproto_request(php_stream *stream, int32_t type, int32_t request_id, struct io_buf *buf);
 
-	bzero(out_buf, header->len + INSERT_REQUEST_SIZE);
+/* receive response by iproto */
+static bool
+recv_iproto_response(php_stream *stream, struct io_buf *buf);
 
-	len = php_stream_read(ctx->stream, out_buf, TARANTOOL_BUFSIZE);
 
-	if ( *(out_buf+HEADER_SIZE) == '\0') {
-		efree(out_buf);
-		RETURN_TRUE;
-	}
+/*----------------------------------------------------------------------------*
+ * php hash functions
+ *----------------------------------------------------------------------------*/
 
+/* find long by key in the hash table */
+static bool
+hash_fing_long(HashTable *hash, char *key, long *value);
+
+/* find string by key in the hash table */
+static bool
+hash_fing_str(HashTable *hash, char *key, char **value, int *value_length);
+
+/* find scalar by key in the hash table */
+static bool
+hash_fing_scalar(HashTable *hash, char *key, zval ***value);
+
+
+/*============================================================================*
+ * Interface definition
+ *============================================================================*/
+
+
+/*----------------------------------------------------------------------------*
+ * Tarantool main module interface
+ *----------------------------------------------------------------------------*/
+
+/* initialize module function */
+PHP_MINIT_FUNCTION(tarantool)
+{
+	/* register constants */
+
+	/* register tarantool flags */
+	REGISTER_LONG_CONSTANT("TARANTOOL_FLAGS_RETURN_TUPLE",
+						   TARANTOOL_FLAGS_RETURN_TUPLE,
+						   CONST_CS | CONST_PERSISTENT);
+	REGISTER_LONG_CONSTANT("TARANTOOL_FLAGS_ADD",
+						   TARANTOOL_FLAGS_ADD,
+						   CONST_CS | CONST_PERSISTENT);
+	REGISTER_LONG_CONSTANT("TARANTOOL_FLAGS_REPLACE",
+						   TARANTOOL_FLAGS_REPLACE,
+						   CONST_CS | CONST_PERSISTENT);
+	REGISTER_LONG_CONSTANT("TARANTOOL_FLAGS_NOT_STORE",
+						   TARANTOOL_FLAGS_NOT_STORE,
+						   CONST_CS | CONST_PERSISTENT);
+
+	/* register tarantool update fields operations */
+	REGISTER_LONG_CONSTANT("TARANTOOL_OP_ASSIGN",
+						   TARANTOOL_OP_ASSIGN,
+						   CONST_CS | CONST_PERSISTENT);
+	REGISTER_LONG_CONSTANT("TARANTOOL_OP_ADD",
+						   TARANTOOL_OP_ADD,
+						   CONST_CS | CONST_PERSISTENT);
+	REGISTER_LONG_CONSTANT("TARANTOOL_OP_AND",
+						   TARANTOOL_OP_AND,
+						   CONST_CS | CONST_PERSISTENT);
+	REGISTER_LONG_CONSTANT("TARANTOOL_OP_XOR",
+						   TARANTOOL_OP_XOR,
+						   CONST_CS | CONST_PERSISTENT);
+	REGISTER_LONG_CONSTANT("TARANTOOL_OP_OR",
+						   TARANTOOL_OP_OR,
+						   CONST_CS | CONST_PERSISTENT);
+	REGISTER_LONG_CONSTANT("TARANTOOL_OP_SPLICE",
+						   TARANTOOL_OP_SPLICE,
+						   CONST_CS | CONST_PERSISTENT);
+
+	/* register classes */
+
+	/* register tarantool class */
+	zend_class_entry tarantool_class;
+	INIT_CLASS_ENTRY(tarantool_class, "Tarantool", tarantool_class_methods);
+	tarantool_class.create_object = alloc_tarantool_object;
+	tarantool_class_ptr = zend_register_internal_class(&tarantool_class TSRMLS_CC);
 
-	b2i* bb = (b2i*)(out_buf+HEADER_SIZE);
-	ctx->errorcode = bb->i;
+	return SUCCESS;
+}
 
-	efree(out_buf);
+/* shutdown module function */
+PHP_MSHUTDOWN_FUNCTION(tarantool)
+{
+	return SUCCESS;
+}
 
-	RETURN_FALSE;
+/* show information about this module */
+PHP_MINFO_FUNCTION(tarantool)
+{
+	php_info_print_table_start();
+	php_info_print_table_header(2, "Tarantool/Box support", "enabled");
+	php_info_print_table_row(2, "default host", TARANTOOL_DEFAULT_HOST);
+	php_info_print_table_row(2, "default primary port", TARANTOOL_DEFAULT_PORT);
+	php_info_print_table_row(2, "default read-only port", TARANTOOL_DEFAULT_RO_PORT);
+	php_info_print_table_row(2, "default admin port", TARANTOOL_DEFAULT_ADMIN_PORT);
+	php_info_print_table_end();
 }
-/* }}} */
 
 
+/*----------------------------------------------------------------------------*
+ * Tarantool class interface
+ *----------------------------------------------------------------------------*/
 
-/* {{{ proto int tarantool::select(space, index, tuple [, limit=all, offset=0]);
-	select tuple use php_streams
-*/
-PHP_METHOD(tarantool_class, select )
+PHP_METHOD(tarantool_class, __construct)
 {
-	zval *id, * tuple;
-	tarantool_object *ctx;
-	long ns		= 0;
-	long idx	= 0;
-	long limit	= 0xffffffff;
-	long offset	= 0;
-
-	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ollz|ll", &id,
-		tarantool_class_entry, &ns, &idx, &tuple, &limit, &offset) == FAILURE) {
+	/*
+	 * parse method's parameters
+	 */
+	zval *id;
+	char *host = NULL;
+	int host_len = 0;
+	long port = 0;
+	long admin_port = 0;
+	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
+									 getThis(),
+									 "Osl|l",
+									 &id,
+									 tarantool_class_ptr,
+									 &host,
+									 &host_len,
+									 &port,
+									 &admin_port) == FAILURE) {
 		return;
 	}
+	
+	/*
+	 * validate parameters
+	 */
+
+	/* check host name */
+	if (host == NULL || host_len == 0)
+		raise_exception("invalid tarantool's hostname");
 
-	ctx = (tarantool_object *)zend_object_store_get_object(id TSRMLS_CC);
-	if (!ctx)
-		zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"the context is null" ,0 TSRMLS_CC);
+	/* validate port value */
+	if (port <= 0 || port >= 65536) {
+		raise_exception("invalid primary port value: %li", port);
+		return;
+	}
 
-	if (!ctx->stream) {
-		if (php_tnt_connect(ctx TSRMLS_CC)) {
-			zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-				"the can't open remote host " ,0 TSRMLS_DC);
+	/* check admin port */
+	if (admin_port) {
+		/* validate port value */
+		if (admin_port < 0 || admin_port >= 65536) {
+			raise_exception("invalid admin port value: %li", admin_port);
 			return;
 		}
-
 	}
 
-	ctx->bodyLen = 0;
-	ctx->countTuples = 0;
-	ctx->readedTuples = 0;
-	ctx->readed	= 0;
-	ctx->errorcode	= 0;
-
-	char * out_buf = emalloc(TARANTOOL_BUFSIZE);
-	bzero(out_buf, TARANTOOL_BUFSIZE);
+	/* initialzie object structure */
+	tarantool_object *object = (tarantool_object *) zend_object_store_get_object(
+		id TSRMLS_CC);
+	object->host = estrdup(host);
+	object->port = port;
+	object->admin_port = admin_port;
+	object->stream = NULL;
+	object->admin_stream = NULL;
+	object->io_buf = io_buf_create();
+	if (!object->io_buf) {
+		return;
+	}
+	object->splice_field = io_buf_create();
+	if (!object->splice_field) {
+		return;
+	}
 
-	Header * header = (Header *) out_buf;
-	SelectRequest * select = (SelectRequest *) out_buf + HEADER_SIZE;
+	return;
+}
 
-	header->type		= TARANTOOL_SELECT;
-	header->request_id	= TARANTOOL_REQUEST_ID;
+PHP_METHOD(tarantool_class, select)
+{
+	/* 
+	 * parse methods parameters 
+	 */
+	zval *id;
+	long space_no = 0;
+	long index_no = 0;
+	zval *keys_list = NULL;
+	long limit = -1;
+	long offset = 0;
+	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
+									 getThis(),
+									 "Ollz|ll",
+									 &id,
+									 tarantool_class_ptr,
+									 &space_no,
+									 &index_no,
+									 &keys_list,
+									 &limit,
+									 &offset) == FAILURE) {
+		return;
+	}
 
-	select->spaceNo = ns;
-	select->indexNo		= idx;
-	select->limit		= limit;
-	select->offset		= offset;
-	select->count		= 1;			// âðåìåííî îòëàæèâàåì - îäèí êîðòåæ
+	tarantool_object *tnt = (tarantool_object *) zend_object_store_get_object(
+		id TSRMLS_CC);
 
-	u_char * p = (u_char *)select->tuples ;
+	/* check connection */
+	if (!tnt->stream) {
+		/* establis connection */
+		tnt->stream = establish_connection(tnt->host, tnt->port);
+		if (!tnt->stream)
+			return;
+	}
 
-	int * count_elements = (int *)p;
+	/*
+	 * send request
+	 */
 
-	switch (Z_TYPE_P(tuple)) {
-		case IS_STRING: {
-			*count_elements  = 1;	//!!!! <------- êîë-âî ýëåìåíòîâ â  êîðòåæå
-			p += sizeof(uint32_t);
+	/* clean-up buffer */
+	io_buf_clean(tnt->io_buf);
 
-				char * strval = Z_STRVAL_P(tuple);
-				int str_len = Z_STRLEN_P(tuple);
-				u_char str_shortlen = (u_char)str_len;
+	/* fill select command */
+	/* fill command header */
+	struct tnt_select_request *request = (struct tnt_select_request *) io_buf_write_struct(
+		tnt->io_buf, sizeof(struct tnt_select_request));
+	if (request == NULL)
+		return;
+	request->space_no = space_no;
+	request->index_no = index_no;
+	request->offset = offset;
+	request->limit = limit;
+	/* fill keys */
+	if (!io_buf_write_tuples_list(tnt->io_buf, keys_list))
+		return;
 
-				*(p++) = str_shortlen;
-				memcpy(p, strval, str_len);
-				p += str_len;
+	/* send iproto request */
+	if (!send_iproto_request(tnt->stream, TARANTOOL_COMMAND_SELECT, 0, tnt->io_buf))
+	  return;
 
-//				printf("tuple: len=%d [%s]\n", str_len, strval );
-			}
-			break;
+	/*
+	 * receive response
+	 */
 
-		case IS_LONG: {
-			*count_elements  = 1;	//!!!! <------- êîë-âî ýëåìåíòîâ â  êîðòåæå
-			p += sizeof(uint32_t);
+	/* clean-up buffer */
+	io_buf_clean(tnt->io_buf);
 
-			unsigned long val = Z_LVAL_P(tuple);
-//		    u_char leb_size = (u_char)leb128_size( val);
-//		    *(p++) = leb_size;
-//		    leb128_write( (char *)p, val);
+	/* receive */
+	if (!recv_iproto_response(tnt->stream, tnt->io_buf))
+		return;
 
-			u_char leb_size = 4;
-			*(p++) = leb_size;
-			b2i * pval = (b2i*) p;
-			pval->i = (int) val;
-			p += leb_size;
+	/* read response */
+	struct tnt_response *response;
+	if (!read_struct_io_buf(tnt->io_buf,
+						  (void **) &response,
+						  sizeof(struct tnt_response))) {
+		raise_exception("select failed: invalid response was received");
+		return;
+	}
 
-//			printf("tuple: int %d\n", val );
-			}
-			break;
+	/* check return code */
+	if (response->return_code) {
+		/* error happen, throw exceprion */
+		raise_exception("select failed: %"PRIi32, response->return_code);
+		return;
+	}
 
+	if (array_init(return_value) != SUCCESS) {
+		raise_exception("select failed: create array failed");
+		return;
+	}
 
-		case IS_ARRAY: {
-			HashTable *pht;
-			HashPosition pos;
-			zval **curr;
-
-			*count_elements  = zend_hash_num_elements(Z_ARRVAL_P(tuple));
-			p += sizeof(uint32_t);
-
-			pht = Z_ARRVAL_P(tuple);
-			for(zend_hash_internal_pointer_reset_ex(pht, &pos);
-				  zend_hash_get_current_data_ex(pht, (void **)&curr, &pos) == SUCCESS;
-				  zend_hash_move_forward_ex(pht, &pos)) {
-
-				if (Z_TYPE_PP(curr) == IS_STRING)  {
-					char * strval = Z_STRVAL_PP(curr);
-					int str_len = Z_STRLEN_PP(curr);
-		//			printf("tuple: len=%d [%s]", str_len, strval );
-					u_char str_shortlen = (u_char)str_len;
-
-					*(p++) = str_shortlen;
-					memcpy(p, strval, str_len);
-					p += str_len;
-				}
-				if (Z_TYPE_PP(curr) == IS_LONG)  {
-					unsigned long val = Z_LVAL_PP(curr);
-
-//					u_char leb_size = (u_char)leb128_size( val);
-//					*(p++) = leb_size;
-//					leb128_write( (char *)p, val);
-					u_char leb_size = 4;
-					*(p++) = leb_size;
-					b2i * pval = (b2i*) p;
-					pval->i = (int) val;
-
-					p += leb_size;
-				}
-			}
+	/* put count to result array */
+	add_assoc_long(return_value, "count", response->count);
 
-		}
-		break;
-		default :
-			zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"tuple: unsuport tuple type" ,0 TSRMLS_CC);
-			return;
+	/* put tuple list to result array */
+	zval *tuples_list;
+	MAKE_STD_ZVAL(tuples_list);
+	if (array_init(tuples_list) == FAILURE) {
+		raise_exception("select failed: create array failed");
+		return;
 	}
 
-	u_char * p_end = (u_char *)select->tuples ;
-	header->len = (p - p_end)  +  SELECT_REQUEST_SIZE; //+ HEADER_SIZE ; // 12 = 3 * sizeof(int32) :ns, flag & cardinality
-
-	// write header
-	int len = php_stream_write(ctx->stream, out_buf, HEADER_SIZE); // 12
-	if (len != HEADER_SIZE) {
-			zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"write header error" ,0 TSRMLS_CC);
-			efree(out_buf);
+	/* read tuples for responce */
+	int i;
+	for (i = 0; i < response->count; ++i) {
+		zval *tuple;
+		if (!read_tuple_io_buf(tnt->io_buf, &tuple)) {
+			raise_exception("select failed: invalid response was received");
 			return;
+		}
+		add_next_index_zval(tuples_list, tuple);
 	}
 
-	len = php_stream_write(ctx->stream, (void*)select , header->len );
-	if (len != header->len) {
-			zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"write request error" ,0 TSRMLS_CC);
-			efree(out_buf);
-			return;
+	add_assoc_zval(return_value, "tuples_list", tuples_list);
+}
+
+PHP_METHOD(tarantool_class, insert)
+{
+	/* 
+	 * parse methods parameters 
+	 */
+	zval *id;
+	long space_no = 0;
+	long flags = 0;
+	zval *tuple = NULL;
+	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
+									 getThis(),
+									 "Ola|l",
+									 &id,
+									 tarantool_class_ptr,
+									 &space_no,
+									 &tuple,
+									 &flags) == FAILURE) {
+		return;
 	}
 
-	Header responseHeader;
-	bzero(&responseHeader, HEADER_SIZE);
+	tarantool_object *tnt = (tarantool_object *) zend_object_store_get_object(
+		id TSRMLS_CC);
 
-	len = php_stream_read(ctx->stream, (void *)&responseHeader, HEADER_SIZE);
-	if (len != HEADER_SIZE) {
-			zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"read header error" ,0 TSRMLS_CC);
-			efree(out_buf);
+	/* check connection */
+	if (!tnt->stream) {
+		/* establis connection */
+		tnt->stream = establish_connection(tnt->host, tnt->port);
+		if (!tnt->stream)
 			return;
 	}
 
-	ctx->bodyLen = responseHeader.len;
+	/*
+	 * send request
+	 */
 
-	uint32_t code;
+	/* clean-up buffer */
+	io_buf_clean(tnt->io_buf);
 
-	len = php_stream_read(ctx->stream, (void *) &code,sizeof(uint32_t));
-	ctx->readed += len;
-	if (code > 0 || len != sizeof(uint32_t)) {
-		ctx->errorcode = code;					///  need test
-		efree(out_buf);
-		RETURN_FALSE;
-	}
-//
-	uint32_t tuples_count=0;
-	len = php_stream_read(ctx->stream, (void *) &tuples_count,sizeof(uint32_t));
-	ctx->readed += len;
-	if (len != sizeof(uint32_t)) {
-			zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C),
-			0 TSRMLS_CC,"read body error");
-		efree(out_buf);
+	/* fill insert command */
+	struct tnt_insert_request *request = (struct tnt_insert_request *) io_buf_write_struct(
+		tnt->io_buf, sizeof(struct tnt_insert_request));
+	if (request == NULL)
 		return;
-	}
-
-	ctx->errorcode	= code;
-	ctx->countTuples = tuples_count;
-	efree(out_buf);
 
-	RETURN_LONG(ctx->countTuples);
+	/* space number */
+	request->space_no = space_no;
+	/* flags */
+	request->flags = flags;
+	/* tuple */
+	if (!io_buf_write_tuple(tnt->io_buf, tuple))
+		return;
 
-}
-/* }}} */
+	/* send iproto request */
+	if (!send_iproto_request(tnt->stream, TARANTOOL_COMMAND_INSERT, 0, tnt->io_buf))
+	  return;
 
-/* {{{ proto int tarantool::mselect(space, index, tuples [, limit=all, offset=0]);
-	select some tuples tuples = array(key1,key2,key3);
-	use only simple key
-*/
-PHP_METHOD(tarantool_class, mselect )
-{
-	zval *id, * tuple;
-	tarantool_object *ctx;
-	long ns		= 0;
-	long idx	= 0;
-	long limit	= 0xffffffff;
-	long offset	= 0;
-
-	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Olla|ll", &id,
-		tarantool_class_entry, &ns, &idx, &tuple, &limit, &offset) == FAILURE) {
-		return;
-	}
+	/*
+	 * receive response
+	 */
 
-	ctx = (tarantool_object *)zend_object_store_get_object(id TSRMLS_CC);
-	if (!ctx)
-		zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"the context is null" ,0 TSRMLS_CC);
+	/* clean-up buffer */
+	io_buf_clean(tnt->io_buf);
 
-	if (!ctx->stream) {
-		if (php_tnt_connect(ctx TSRMLS_CC)) {
-			zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-				"the can't open remote host " ,0 TSRMLS_DC);
-			return;
-		}
+	/* receive */
+	if (!recv_iproto_response(tnt->stream, tnt->io_buf))
+		return;
 
+	/* read response */
+	struct tnt_response *response;
+	if (!read_struct_io_buf(tnt->io_buf,
+						  (void **) &response,
+						  sizeof(struct tnt_response))) {
+		raise_exception("insert failed: invalid response was received");
+		return;
 	}
 
-	ctx->bodyLen = 0;
-	ctx->countTuples = 0;
-	ctx->readedTuples = 0;
-	ctx->readed	= 0;
-	ctx->errorcode	= 0;
-
-	char * out_buf = emalloc(TARANTOOL_BUFSIZE);
-	bzero(out_buf, TARANTOOL_BUFSIZE);
+	/* check return code */
+	if (response->return_code) {
+		/* error happen, throw exceprion */
+		raise_exception("insert failed: %"PRIi32, response->return_code);
+		return;
+	}
+	
+	/*
+	 * fill return value
+	 */
 
-	Header * header = (Header *) out_buf;
-	SelectRequest * select = (SelectRequest *) out_buf + HEADER_SIZE;
+	if (array_init(return_value) != SUCCESS) {
+		raise_exception("insert failed: create array failed");
+		return;
+	}
 
-	header->type		= TARANTOOL_SELECT;
-	header->request_id	= TARANTOOL_REQUEST_ID;
+	/* put count to result array */
+	add_assoc_long(return_value, "count", response->count);	
 
-	select->spaceNo = ns;
-	select->indexNo		= idx;
-	select->limit		= limit;
-	select->offset		= offset;
+	/* check "return tuple" flag */
+	if (flags & TARANTOOL_FLAGS_RETURN_TUPLE) {
+		/* ok, the responce should contain inserted tuple */
+		if (!read_tuple_io_buf(tnt->io_buf, &tuple)) {
+			raise_exception("insert failed: invalid response was received");
+			return;
+		}
 
+		/* put returned tuple to result array */
+		add_assoc_zval(return_value, "tuple", tuple);
+	}
+}
 
-	u_char * p = (u_char *)select->tuples ;
-	select->count = zend_hash_num_elements(Z_ARRVAL_P(tuple));
+PHP_METHOD(tarantool_class, update_fields)
+{
+	/* 
+	 * parse methods parameters 
+	 */
+	zval *id;
+	long space_no = 0;
+	long flags = 0;
+	zval *tuple = NULL;
+	zval *op_list = NULL;
+	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
+									 getThis(),
+									 "Olza|l",
+									 &id,
+									 tarantool_class_ptr,
+									 &space_no,
+									 &tuple,
+									 &op_list,
+									 &flags) == FAILURE) {
+		return;
+	}
 
-	// ôîðìèðóåì òàê êàê íàäî!
+	tarantool_object *tnt = (tarantool_object *) zend_object_store_get_object(
+		id TSRMLS_CC);
 
-	HashTable *pht;
-	HashPosition pos;
-	zval **curr;
+	/* check connection */
+	if (!tnt->stream) {
+		/* establis connection */
+		tnt->stream = establish_connection(tnt->host, tnt->port);
+		if (!tnt->stream)
+			return;
+	}
 
+	/*
+	 * send request
+	 */
 
-	pht = Z_ARRVAL_P(tuple);
-	for(zend_hash_internal_pointer_reset_ex(pht, &pos);
-		  zend_hash_get_current_data_ex(pht, (void **)&curr, &pos) == SUCCESS;
-		  zend_hash_move_forward_ex(pht, &pos)) {
+	/* clean-up buffer */
+	io_buf_clean(tnt->io_buf);
 
-			int32_t * count = (int32_t *)p;
-			*count = 1;
-			p += sizeof(int32_t);
+	/* fill insert command */
+	struct tnt_update_fields_request *request = (struct tnt_update_fields_request *) io_buf_write_struct(
+		tnt->io_buf, sizeof(struct tnt_update_fields_request));
+	if (request == NULL)
+		return;
 
+	/* space number */
+	request->space_no = space_no;
+	/* flags */
+	request->flags = flags;
+	/* tuple */
+	if (!io_buf_write_tuple(tnt->io_buf, tuple))
+		return;
 
-		if (Z_TYPE_PP(curr) == IS_STRING)  {
-			char * strval = Z_STRVAL_PP(curr);
-			int str_len = Z_STRLEN_PP(curr);
-//			printf("tuple: len=%d [%s]", str_len, strval );
-			u_char str_shortlen = (u_char)str_len;
+	HashTable *op_list_array = Z_ARRVAL_P(op_list);
+	int op_count = zend_hash_num_elements(op_list_array);
 
-			*(p++) = str_shortlen;
-			memcpy(p, strval, str_len);
-			p += str_len;
+	/* write number of update fields operaion */
+	if (!io_buf_write_int32(tnt->io_buf, op_count))
+		return;
+	php_printf("ops count = %i\n", op_count);
+
+	HashPosition itr;
+	zval **op;
+	for (zend_hash_internal_pointer_reset_ex(op_list_array, &itr);
+		 zend_hash_get_current_data_ex(op_list_array, (void **) &op, &itr) == SUCCESS;
+		 zend_hash_move_forward_ex(op_list_array, &itr)) {
+		/* check operation type */
+		if (Z_TYPE_PP(op) != IS_ARRAY) {
+			raise_exception("invalid operations list");
+			return;
 		}
-		if (Z_TYPE_PP(curr) == IS_LONG)  {
-			unsigned long val = Z_LVAL_PP(curr);
 
-			u_char leb_size = 4;
-			*(p++) = leb_size;
-			b2i * pval = (b2i*) p;
-			pval->i = (int) val;
+		HashTable *op_array = Z_ARRVAL_PP(op);
+		long field_no;
+		long opcode;
 
-			p += leb_size;
+		if (!hash_fing_long(op_array, "field", &field_no)) {
+			raise_exception("can't find 'field' in the update field operation");
+			return;
 		}
-	} // end array
 
+		if (!hash_fing_long(op_array, "op", &opcode)) {
+			raise_exception("can't find 'op' in the update field operation");
+			return;
+		}
 
+		/* write field number */
+		if (!io_buf_write_int32(tnt->io_buf, field_no))
+			return;
 
-	u_char * p_end = (u_char *)select->tuples ;
-	header->len = (p - p_end)  +  SELECT_REQUEST_SIZE; //+ HEADER_SIZE ; // 12 = 3 * sizeof(int32) :ns, flag & cardinality
+		/* write operation code */
+		if (!io_buf_write_byte(tnt->io_buf, opcode))
+			return;
 
+		zval **assing_arg = NULL;
+		long arith_arg;
+		long splice_offset;
+		long splice_length;
+		char *splice_list;
+		int splice_list_len;
+		switch (opcode) {
+		case TARANTOOL_OP_ASSIGN:
+			if (!hash_fing_scalar(op_array, "arg", &assing_arg)) {
+				raise_exception("can't find 'arg' in the update field operation");
+				return;
+			}
+			if (Z_TYPE_PP(assing_arg) == IS_LONG) {
+				/* write as interger */
+				if (!io_buf_write_field(tnt->io_buf, (uint8_t *) &Z_LVAL_PP(assing_arg), sizeof(int32_t)))
+					return;
+			} else {
+				/* write as string */
+				if (!io_buf_write_field(tnt->io_buf, (uint8_t *) Z_STRVAL_PP(assing_arg), Z_STRLEN_PP(assing_arg)))
+					return;
+			}
+			break;
+		case TARANTOOL_OP_ADD:
+		case TARANTOOL_OP_AND:
+		case TARANTOOL_OP_XOR:
+		case TARANTOOL_OP_OR:
+			if (!hash_fing_long(op_array, "arg", &arith_arg)) {
+				raise_exception("can't find 'arg' in the update field operation");
+				return;
+			}
+			/* write arith arg */
+			if (!io_buf_write_field(tnt->io_buf, (uint8_t *) &arith_arg, sizeof(int32_t)))
+				return;
+			break;
+		case TARANTOOL_OP_SPLICE:
+			/*
+			 * read splice args
+			 */
+
+			/* read offset */
+			if (!hash_fing_long(op_array, "offset", &splice_offset)) {
+				raise_exception("can't find 'offset' in the update field operation");
+				return;
+			}
+			/* read length */
+			if (!hash_fing_long(op_array, "length", &splice_length)) {
+				raise_exception("can't find 'length' in the update field operation");
+				return;
+			}
+			/* read list */
+			if (!hash_fing_str(op_array, "list", &splice_list, &splice_list_len)) {
+				raise_exception("can't find 'list' in the update field operation");
+				return;
+			}
 
-//	printf("body len %d\n", header->len);
-//
-//			p = (u_char *)select;
-//			printLine3(p);
-//			printLine3(p+12);
-//			printLine3(p+24);
-//			printLine3(p+36);
-//
-//		efree(out_buf);
-//		RETURN_FALSE;
+			/*
+			 * write splice args
+			 */
+			io_buf_clean(tnt->splice_field);
+
+			/* write offset to separate buffer */
+			if (!io_buf_write_field(tnt->splice_field, (uint8_t *) &splice_offset, sizeof(int32_t)))
+				return;
+			/* write length to separate buffer */
+			if (!io_buf_write_field(tnt->splice_field, (uint8_t *) &splice_length, sizeof(int32_t)))
+				return;
+			/* write list to separate buffer */
+			if (!io_buf_write_field(tnt->splice_field, (uint8_t *) splice_list, splice_list_len))
+				return;
+
+			/* write splice args as alone field */
+			if (!io_buf_write_field(tnt->io_buf, tnt->splice_field->value, tnt->splice_field->size))
+				return;
 
-	// write header
-	int len = php_stream_write(ctx->stream, out_buf, HEADER_SIZE); // 12
-	if (len != HEADER_SIZE) {
-			zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"write header error" ,0 TSRMLS_CC);
-			efree(out_buf);
+			break;
+		default:
+			raise_exception("invalid operaion code %i", opcode);
 			return;
+		}
 	}
 
-	len = php_stream_write(ctx->stream, (void*)select , header->len );
-	if (len != header->len) {
-			zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"write request error" ,0 TSRMLS_CC);
-			efree(out_buf);
-			return;
-	}
+	/* send iproto request */
+	if (!send_iproto_request(tnt->stream, TARANTOOL_COMMAND_UPDATE, 0, tnt->io_buf))
+	  return;
 
-	Header responseHeader;
-	bzero(&responseHeader, HEADER_SIZE);
+	/*
+	 * receive response
+	 */
 
-	len = php_stream_read(ctx->stream, (void *)&responseHeader, HEADER_SIZE);
-	if (len != HEADER_SIZE) {
-			zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"read header error" ,0 TSRMLS_CC);
-			efree(out_buf);
-			return;
-	}
+	/* clean-up buffer */
+	io_buf_clean(tnt->io_buf);
 
-	ctx->bodyLen = responseHeader.len;
+	/* receive */
+	if (!recv_iproto_response(tnt->stream, tnt->io_buf))
+		return;
 
-	uint32_t code;
+	/* read response */
+	struct tnt_response *response;
+	if (!read_struct_io_buf(tnt->io_buf,
+						  (void **) &response,
+						  sizeof(struct tnt_response))) {
+		raise_exception("update fields failed: invalid response was received");
+		return;
+	}
 
-	len = php_stream_read(ctx->stream, (void *) &code,sizeof(uint32_t));
-	ctx->readed += len;
-	if (code > 0 || len != sizeof(uint32_t)) {
-		ctx->errorcode = code;					///  need test
-		efree(out_buf);
-		RETURN_FALSE;
+	/* check return code */
+	if (response->return_code) {
+		/* error happen, throw exceprion */
+		raise_exception("update fields failed: %"PRIi32, response->return_code);
+		return;
 	}
-//
-	uint32_t tuples_count=0;
-	len = php_stream_read(ctx->stream, (void *) &tuples_count,sizeof(uint32_t));
-	ctx->readed += len;
-	if (len != sizeof(uint32_t)) {
-			zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C),
-			0 TSRMLS_CC,"read body error");
-		efree(out_buf);
+	
+	/*
+	 * fill return value
+	 */
+
+	if (array_init(return_value) != SUCCESS) {
+		raise_exception("update fields failed: create array failed");
 		return;
 	}
 
-	ctx->errorcode	= code;
-	ctx->countTuples = tuples_count;
-	efree(out_buf);
+	/* put count to result array */
+	add_assoc_long(return_value, "count", response->count);	
 
-	RETURN_LONG(ctx->countTuples);
+	/* check "return tuple" flag */
+	if (flags & TARANTOOL_FLAGS_RETURN_TUPLE) {
+		/* ok, the responce should contain inserted tuple */
+		if (!read_tuple_io_buf(tnt->io_buf, &tuple)) {
+			raise_exception("update fields failed: invalid response was received");
+			return;
+		}
 
+		/* put returned tuple to result array */
+		add_assoc_zval(return_value, "tuple", tuple);
+	}
 }
-/* }}} */
 
-/* {{{ proto int tarantool::call(procname, tuple);
-	call a stored procedure by  name
-*/
-PHP_METHOD(tarantool_class, call)
+PHP_METHOD(tarantool_class, delete)
 {
-	zval *id, * tuple;
-	tarantool_object *ctx;
-	const char *procname = NULL;
-	long procname_len = 0;
-
-	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Osz", &id,
-		tarantool_class_entry, &procname, &procname_len, &tuple) == FAILURE) {
+	/* 
+	 * parse methods parameters 
+	 */
+	zval *id;
+	long space_no = 0;
+	long flags = 0;
+	zval *tuple = NULL;
+	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
+									 getThis(),
+									 "Olz|l",
+									 &id,
+									 tarantool_class_ptr,
+									 &space_no,
+									 &tuple,
+									 &flags) == FAILURE) {
 		return;
 	}
 
-	ctx = (tarantool_object *)zend_object_store_get_object(id TSRMLS_CC);
-	if (!ctx)
-		zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"the context is null" ,0 TSRMLS_CC);
+	tarantool_object *tnt = (tarantool_object *) zend_object_store_get_object(
+		id TSRMLS_CC);
 
-	if (!ctx->stream) {
-		if (php_tnt_connect(ctx TSRMLS_CC)) {
-			zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-				"can't connect to remote host " ,0 TSRMLS_DC);
+	/* check connection */
+	if (!tnt->stream) {
+		/* establis connection */
+		tnt->stream = establish_connection(tnt->host, tnt->port);
+		if (!tnt->stream)
 			return;
-		}
 	}
 
-	ctx->bodyLen = 0;
-	ctx->countTuples = 0;
-	ctx->readedTuples = 0;
-	ctx->readed	= 0;
-	ctx->errorcode	= 0;
-
-	char *out_buf = emalloc(TARANTOOL_BUFSIZE);
-	bzero(out_buf, TARANTOOL_BUFSIZE);
-
-	Header *header = (Header *) out_buf;
-
-	header->type		= TARANTOOL_CALL;
-	header->request_id	= TARANTOOL_REQUEST_ID;
-
-	u_char *call = (char *) out_buf + HEADER_SIZE;
-	u_char *p = call;
+	/*
+	 * send request
+	 */
 
-	p+= 4; /* flags */
-	*p++ = (u_char) procname_len;
+	/* clean-up buffer */
+	io_buf_clean(tnt->io_buf);
 
-	memcpy(p, procname, procname_len);
-	p += procname_len;
-
-	int * count_elements = (int *)p;
-
-	switch (Z_TYPE_P(tuple)) {
-		case IS_STRING: {
-			*count_elements  = 1;
-			p += sizeof(uint32_t);
-
-			char * strval = Z_STRVAL_P(tuple);
-			int str_len = Z_STRLEN_P(tuple);
-			u_char str_shortlen = (u_char)str_len;
+	/* fill delete command */
+	struct tnt_delete_request *request = (struct tnt_delete_request *) io_buf_write_struct(
+		tnt->io_buf, sizeof(struct tnt_delete_request));
+	if (request == NULL)
+		return;
 
-			*(p++) = str_shortlen;
-			memcpy(p, strval, str_len);
-			p += str_len;
-		}
-		break;
+	/* space number */
+	request->space_no = space_no;
+	/* flags */
+	request->flags = flags;
+	/* tuple */
+	if (!io_buf_write_tuple(tnt->io_buf, tuple))
+		return;
 
-		case IS_LONG: {
-			*count_elements  = 1;
-			p += sizeof(uint32_t);
+	/* send iproto request */
+	if (!send_iproto_request(tnt->stream, TARANTOOL_COMMAND_DELETE, 0, tnt->io_buf))
+		return;
 
-			unsigned long val = Z_LVAL_P(tuple);
+	/*
+	 * receive response
+	 */
 
-			u_char leb_size = 4;
-			*(p++) = leb_size;
-			b2i * pval = (b2i*) p;
-			pval->i = (int) val;
-			p += leb_size;
+	/* clean-up buffer */
+	io_buf_clean(tnt->io_buf);
 
-			}
-			break;
+	/* receive */
+	if (!recv_iproto_response(tnt->stream, tnt->io_buf))
+		return;
 
+	/* read response */
+	struct tnt_response *response;
+	if (!read_struct_io_buf(tnt->io_buf,
+						  (void **) &response,
+						  sizeof(struct tnt_response))) {
+		raise_exception("delete failed: invalid response was received");
+		return;
+	}
 
-		case IS_ARRAY: {
-			HashTable *pht;
-			HashPosition pos;
-			zval **curr;
-
-			*count_elements  = zend_hash_num_elements(Z_ARRVAL_P(tuple));
-			p += sizeof(uint32_t);
-
-			pht = Z_ARRVAL_P(tuple);
-			for(zend_hash_internal_pointer_reset_ex(pht, &pos);
-				  zend_hash_get_current_data_ex(pht, (void **)&curr, &pos) == SUCCESS;
-				  zend_hash_move_forward_ex(pht, &pos)) {
-
-				if (Z_TYPE_PP(curr) == IS_STRING)  {
-					char * strval = Z_STRVAL_PP(curr);
-					int str_len = Z_STRLEN_PP(curr);
-		//			printf("tuple: len=%d [%s]", str_len, strval );
-					u_char str_shortlen = (u_char)str_len;
-
-					*(p++) = str_shortlen;
-					memcpy(p, strval, str_len);
-					p += str_len;
-				}
-				if (Z_TYPE_PP(curr) == IS_LONG)  {
-					unsigned long val = Z_LVAL_PP(curr);
-
-//					u_char leb_size = (u_char)leb128_size( val);
-//					*(p++) = leb_size;
-//					leb128_write( (char *)p, val);
-					u_char leb_size = 4;
-					*(p++) = leb_size;
-					b2i * pval = (b2i*) p;
-					pval->i = (int) val;
-
-					p += leb_size;
-				}
-			}
+	/* check return code */
+	if (response->return_code) {
+		/* error happen, throw exceprion */
+		raise_exception("delete failed: %"PRIi32, response->return_code);
+		return;
+	}
+	
+	/*
+	 * fill return value
+	 */
 
-		}
-		break;
-		default :
-			zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"tuple: unsuport tuple type" ,0 TSRMLS_CC);
-			return;
+	if (array_init(return_value) != SUCCESS) {
+		raise_exception("delete failed: create array failed");
+		return;
 	}
 
-	header->len = p - call;
+	/* put count to result array */
+	add_assoc_long(return_value, "count", response->count);
 
-	// write header
-	int len = php_stream_write(ctx->stream, out_buf, HEADER_SIZE); // 12
-	if (len != HEADER_SIZE) {
-			zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"write header error" ,0 TSRMLS_CC);
-			efree(out_buf);
+	/* check "return tuple" flag */
+	if (flags & TARANTOOL_FLAGS_RETURN_TUPLE) {
+		/* ok, the responce should contain inserted tuple */
+		if (!read_tuple_io_buf(tnt->io_buf, &tuple)) {
+			raise_exception("delete failed: invalid response was received");
 			return;
+		}
+
+		/* put returned tuple to result array */
+		add_assoc_zval(return_value, "tuple", tuple);
 	}
+}
 
-	len = php_stream_write(ctx->stream, call, header->len );
-	if (len != header->len) {
-			zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"write request error" ,0 TSRMLS_CC);
-			efree(out_buf);
-			return;
+PHP_METHOD(tarantool_class, call)
+{
+	/* 
+	 * parse methods parameters 
+	 */
+	zval *id;
+	char *proc_name = NULL;
+	int proc_name_len = 0;
+	zval *tuple = NULL;
+	long flags = 0;
+	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
+									 getThis(),
+									 "Osz|l",
+									 &id,
+									 tarantool_class_ptr,
+									 &proc_name, &proc_name_len,
+									 &tuple,
+									 &flags) == FAILURE) {
+		return;
 	}
 
-	Header responseHeader;
-	bzero(&responseHeader, HEADER_SIZE);
+	tarantool_object *tnt = (tarantool_object *) zend_object_store_get_object(
+		id TSRMLS_CC);
 
-	len = php_stream_read(ctx->stream, (void *)&responseHeader, HEADER_SIZE);
-	if (len != HEADER_SIZE) {
-			zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"read header error" ,0 TSRMLS_CC);
-			efree(out_buf);
+	/* check connection */
+	if (!tnt->stream) {
+		/* establis connection */
+		tnt->stream = establish_connection(tnt->host, tnt->port);
+		if (!tnt->stream)
 			return;
 	}
 
-	ctx->bodyLen = responseHeader.len;
+	/*
+	 * send request
+	 */
 
-	uint32_t code;
+	/* clean-up buffer */
+	io_buf_clean(tnt->io_buf);
 
-	len = php_stream_read(ctx->stream, (void *) &code,sizeof(uint32_t));
-	ctx->readed += len;
-	if (code > 0 || len != sizeof(uint32_t)) {
-		ctx->errorcode = code;					///  need test
-		efree(out_buf);
-		RETURN_FALSE;
-	}
-//
-	uint32_t tuples_count=0;
-	len = php_stream_read(ctx->stream, (void *) &tuples_count,sizeof(uint32_t));
-	ctx->readed += len;
-	if (len != sizeof(uint32_t)) {
-			zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C),
-			0 TSRMLS_CC,"read body error");
-		efree(out_buf);
+	/* fill insert command */
+	struct tnt_call_request *request = (struct tnt_call_request *) io_buf_write_struct(
+		tnt->io_buf, sizeof(struct tnt_call_request));
+	if (request == NULL)
 		return;
-	}
 
-	ctx->errorcode	= code;
-	ctx->countTuples = tuples_count;
-	efree(out_buf);
+	/* flags */
+	request->flags = flags;
+	/* proc name */
+	if (!io_buf_write_field(tnt->io_buf, proc_name, proc_name_len))
+		return;
+	/* tuple */
+	if (!io_buf_write_tuple(tnt->io_buf, tuple))
+		return;
 
-	RETURN_LONG(ctx->countTuples);
+	/* send iproto request */
+	if (!send_iproto_request(tnt->stream, TARANTOOL_COMMAND_CALL, 0, tnt->io_buf))
+	  return;
 
-}
-/* }}} */
 
+	/*
+	 * receive response
+	 */
 
-/* {{{ proto array tarantool::getTuple()
-   return one tuple */
-PHP_METHOD(tarantool_class, getTuple )
-{
-	zval *id;
-	tarantool_object *ctx;
+	/* clean-up buffer */
+	io_buf_clean(tnt->io_buf);
 
-	int len;
+	/* receive */
+	if (!recv_iproto_response(tnt->stream, tnt->io_buf))
+		return;
 
-	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id,
-		tarantool_class_entry) == FAILURE) {
+	/* read response */
+	struct tnt_response *response;
+	if (!read_struct_io_buf(tnt->io_buf,
+						  (void **) &response,
+						  sizeof(struct tnt_response))) {
+		raise_exception("call failed: invalid response was received");
 		return;
 	}
 
-	ctx = (tarantool_object *)zend_object_store_get_object(id TSRMLS_CC);
-	if (!ctx) {
-		zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"the context is null" ,0 TSRMLS_CC);
+	/* check return code */
+	if (response->return_code) {
+		/* error happen, throw exceprion */
+		raise_exception("call failed: %"PRIi32, response->return_code);
 		return;
 	}
 
-	if (!ctx->bodyLen) {
-		zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"the response body is null" ,0 TSRMLS_CC);
+	if (array_init(return_value) != SUCCESS) {
+		raise_exception("call failed: create array failed");
 		return;
 	}
 
-	if (++ctx->readedTuples > ctx->countTuples) {
-		RETURN_FALSE;
-	}
+	/* put count to result array */
+	add_assoc_long(return_value, "count", response->count);
 
-	if (ctx->readed >= ctx->bodyLen) {
-		RETURN_FALSE;
+	/* put tuple list to result array */
+	zval *tuples_list;
+	MAKE_STD_ZVAL(tuples_list);
+	if (array_init(tuples_list) == FAILURE) {
+		raise_exception("call failed: create array failed");
+		return;
 	}
 
+	/* read tuples for responce */
+	int i;
+	for (i = 0; i < response->count; ++i) {
+		zval *tuple;
+		if (!read_tuple_io_buf(tnt->io_buf, &tuple)) {
+			raise_exception("call failed: invalid response was received");
+			return;
+		}
+		add_next_index_zval(tuples_list, tuple);
+	}
 
-	SelectResponseTuple responseBody;
+	add_assoc_zval(return_value, "tuples_list", tuples_list);
+}
 
-	if (php_stream_read(ctx->stream, (void*)&responseBody, sizeof(SelectResponseTuple)) !=sizeof(SelectResponseTuple)) {
-		zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"the read body error" ,0 TSRMLS_CC);
+PHP_METHOD(tarantool_class, admin)
+{
+	/* parse methods parameters */
+	zval *id;
+	char *cmd = NULL;
+	int cmd_len = 0;
+	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
+									 getThis(),
+									 "Os",
+									 &id,
+									 tarantool_class_ptr,
+									 &cmd, &cmd_len) == FAILURE) {
 		return;
 	}
 
-	ctx->readed += sizeof(SelectResponseTuple);
+	tarantool_object *tnt = (tarantool_object *) zend_object_store_get_object(
+		id TSRMLS_CC);
 
-	u_char * buf = emalloc(responseBody.size);
-
-	if (php_stream_read(ctx->stream, (char*) buf, responseBody.size) != responseBody.size) {
-		efree(buf);
-		zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"the read tuple error" ,0 TSRMLS_CC);
+	/* check admin port */
+	if (!tnt->admin_port) {
+		raise_exception("admin command not allowed for this commection");
 		return;
 	}
 
-	ctx->readed += responseBody.size;
-
-	array_init(return_value);
-
-	char bb2[16];
-	int i;
-	unsigned long value;
-	b2i b;
-	b2i * pb;
-	u_char* p = buf;
-	int is_string = 0;
-
-	for(i=0; i < responseBody.count; i++) { //
-		b.i=0;
-		b.b = *p;
-		bzero(bb2,16);
-		len = b.i;
-		memcpy(bb2, p+1, len);
-
-		switch (len) {
-			case 1 : {
-				if ( isprint(*bb2) ) {
-//					printf("tuple element '%s' len=%d\n",bb2, len);
-					is_string = 1;
-				} else {
-					is_string = 0;
-					leb128_read(bb2, len, &value);
-//					printf("tuple element(int) %d len=%d\n",value, len);
-				}
-				break;
-			}
-			case 2 : {
-				if ( isprint(*bb2) && isprint(*(bb2+1))) {
-//					printf("tuple element '%s' len=%d\n",bb2, len);
-					is_string = 1;
-				} else {
-					is_string = 0;
-					leb128_read(bb2, len, &value);
-//					printf("tuple element(int) %d len=%d\n",value, len);
-				}
-				break;
-			}
-
-			case 3 : {
-				if ( isprint(*bb2) && isprint(*(bb2+1)) && isprint(*(bb2+2)) ) {
-//					printf("tuple element '%s' len=%d\n",bb2, len);
-					is_string = 1;
-				} else {
-					is_string = 0;
-					leb128_read(bb2, len, &value);
-//					printf("tuple element(int) %d len=%d\n",value, len);
-				}
-				break;
-			}
-
-			case 4 : {
-				if ( isprint(*bb2) && isprint(*(bb2+1)) && isprint(*(bb2+2)) && isprint(*(bb2+3)) ) {
-					is_string = 1;
-				} else {
-
-					pb = (b2i*) bb2;
-					value = (unsigned long) pb->i;
-//				php_printf("tuple element(int) %d len=%d\n",value, len);
-					is_string = 0;
-				}
-				break;
-			}
-			default :  {
-				is_string = 0;
-//				printf("tuple element %s len=%d\n",bb2, len);
-			}
-		} // end switch
-
-
-		if (is_string) {
-//			php_printf("tuple element '%s' len=%d\n",bb2, len);
-			add_next_index_stringl( return_value, bb2 , len , 1);
-		} else
-//			php_printf("tuple element %d\n",bb2, value);
-			add_next_index_long( return_value, value);
+	/* check connection */
+	if (!tnt->admin_stream) {
+		/* establis connection */
+		tnt->admin_stream = establish_connection(tnt->host, tnt->admin_port);
+		if (!tnt->admin_stream)
+			return;
 
-		p += len+1;
+		/* set string eol */
+		php_stream_locate_eol(tnt->admin_stream,
+							  ADMIN_SEPARATOR,
+							  strlen(ADMIN_SEPARATOR) TSRMLS_DC);
 	}
 
-	efree(buf);
-}
-/* }}} */
-
-/* {{{ proto int tarantool::delete(key)
-   tarantool delete tuple */
-PHP_METHOD(tarantool_class, delete)
-{
-	zval *id;
-	tarantool_object *ctx;
-	long space;
-
-	zval* data;
-
-	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Olz",
-			&id, tarantool_class_entry, &space, &data) == FAILURE) {
+	/* send request */
+	io_buf_clean(tnt->io_buf);
+	if (!io_buf_write_str(tnt->io_buf, cmd, cmd_len))
 		return;
-	}
-
-	ctx = (tarantool_object *)zend_object_store_get_object(id TSRMLS_CC);
-	if (!ctx) {
-		zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"the context is null" ,0 TSRMLS_CC);
+	if (!io_buf_write_str(tnt->io_buf, ADMIN_SEPARATOR, strlen(ADMIN_SEPARATOR)))
+		return;
+	if (!send_admin_request(tnt->admin_stream, tnt->io_buf))
 		return;
-	}
-
-	ctx->bodyLen = 0;
-	ctx->countTuples = 0;
-	ctx->readedTuples = 0;
-	ctx->readed	= 0;
-
-	if (!ctx->stream) {
-		if (php_tnt_connect(ctx TSRMLS_CC)) {
-			zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-				"the can't open remote host " ,0 TSRMLS_DC);
-			return;
-		}
-	}
-
-	char * buf = emalloc(TARANTOOL_BUFSIZE);
-	bzero(buf, TARANTOOL_BUFSIZE);
-
-	Header * header = (Header *) buf;
-	DeleteRequest * delRequest = (DeleteRequest *) buf + HEADER_SIZE;
-
-	header->type		= TARANTOOL_DELETE;
-	header->request_id	= TARANTOOL_REQUEST_ID;
-
-	delRequest->spaceNo = space;
-	delRequest->tuple.count = 1; // count in the Tuples
-
-	u_char * p = (u_char *) delRequest->tuple.data;
-
-	int * count_elements = (int *)p;
-
-	switch (Z_TYPE_P(data)) {
-		case IS_STRING: {
 
-			char * strval = Z_STRVAL_P(data);
-			int str_len = Z_STRLEN_P(data);
-			u_char str_shortlen = (u_char)str_len;
+	/* recv response */
+	io_buf_clean(tnt->io_buf);
+	if (!recv_admin_response(tnt->admin_stream, tnt->io_buf))
+		return;
 
-			*(p++) = str_shortlen;
-			memcpy(p, strval, str_len);
-			p += str_len;
-		}
-			break;
+	char *response = estrndup(tnt->io_buf->value, tnt->io_buf->size);
+	RETURN_STRING(response, 0);
+}
 
-		case IS_LONG: {
 
-			unsigned long val = Z_LVAL_P(data);
-		    u_char leb_size = (u_char)leb128_size( val);
-		    *(p++) = leb_size;
-		    leb128_write( (char *)p, val);
-		    p += leb_size;
+/*============================================================================*
+ * local functions definition
+ *============================================================================*/
 
-//			printf("tuple: int %d\n", val );
-			}
-			break;
 
-		case IS_ARRAY: {
-			HashTable *pht;
-			HashPosition pos;
-			zval **curr;
-
-			delRequest->tuple.count = zend_hash_num_elements(Z_ARRVAL_P(data));
-			pht = Z_ARRVAL_P(data);
-			for(zend_hash_internal_pointer_reset_ex(pht, &pos);
-				  zend_hash_get_current_data_ex(pht, (void **)&curr, &pos) == SUCCESS;
-				  zend_hash_move_forward_ex(pht, &pos)) {
-
-				if (Z_TYPE_PP(curr) == IS_STRING)  {
-					char * strval = Z_STRVAL_PP(curr);
-					int str_len = Z_STRLEN_PP(curr);
-					u_char str_shortlen = (u_char)str_len;
-
-					*(p++) = str_shortlen;
-					memcpy(p, strval, str_len);
-					p += str_len;
-				}
-				if (Z_TYPE_PP(curr) == IS_LONG)  {
-				   unsigned long val = Z_LVAL_PP(curr);
-
-				   u_char leb_size = (u_char)leb128_size( val);
-				   *(p++) = leb_size;
-				   leb128_write( (char *)p, val);
-				   p += leb_size;
-				}
-			}
+/*----------------------------------------------------------------------------*
+ * Buffer interface
+ *----------------------------------------------------------------------------*/
 
-		}
-		break;
-		default :
-			efree(buf);
-			zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"tuple: unsuport tuple type" ,0 TSRMLS_CC);
-			return;
+static struct io_buf *
+io_buf_create()
+{
+	struct io_buf *buf = (struct io_buf *) emalloc(sizeof(struct io_buf));
+	if (!buf) {
+		raise_exception("allocation memory fail: %s (%i)", strerror(errno), errno);
+		goto failure;
 	}
 
-	header->len = (p-delRequest->tuple.data) + sizeof(uint32_t) *2 ; // sizeof(int) + sizeof(int)
-
-	// write header
-	int len = php_stream_write(ctx->stream, buf , HEADER_SIZE); // 12
-
-	// write tuple
-	p = (u_char*)delRequest;
-	len = php_stream_write(ctx->stream, (char*)p , header->len );
-
-	if (header->len + HEADER_SIZE > TARANTOOL_BUFSIZE) {
-			efree(buf);
-			zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"out of memory: the tuple is very big" ,0 TSRMLS_CC);
-			return;
+	buf->size = 0;
+	buf->capacity = io_buf_next_capacity(buf->size);
+	buf->readed = 0;
+	buf->value = (uint8_t *) emalloc(buf->capacity);
+	if (!buf->value) {
+		raise_exception("allocation memory fail: %s (%i)", strerror(errno), errno);
+		goto failure;
 	}
 
-	bzero(buf, header->len + HEADER_SIZE);
+	return buf;
 
-	len = php_stream_read(ctx->stream, buf, TARANTOOL_BUFSIZE);
+failure:
+	if (buf) {
+		if (buf->value)
+			efree(buf->value);
 
-	if ( *(buf+HEADER_SIZE) == '\0') {
-		int deleted = *(buf+HEADER_SIZE + sizeof(uint32_t));
 		efree(buf);
-		RETURN_LONG(deleted);
 	}
 
-
-	b2i* bb =(b2i*)(buf+HEADER_SIZE);
-	ctx->errorcode = bb->i;
-
-	efree(buf);
-	RETURN_FALSE;
-
+	return NULL;
 }
-/* }}} */
 
-/* {{{ proto int tarantool::update(int space, mixed key, array data);
-   tarantool update tuple */
-PHP_METHOD(tarantool_class, update)
+static void
+io_buf_destroy(struct io_buf *buf)
 {
-	zval *id;
-	tarantool_object *ctx;
-	long space;
-
-	zval* key;
-	zval* data;
-
-	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Olza",
-			&id, tarantool_class_entry, &space, &key, &data) == FAILURE) {
-		return;
-	}
-
-	ctx = (tarantool_object *)zend_object_store_get_object(id TSRMLS_CC);
-	if (!ctx) {
-		zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"the context is null" ,0 TSRMLS_CC);
-		return;
-	}
-
-	ctx->bodyLen = 0;
-	ctx->countTuples = 0;
-	ctx->readedTuples = 0;
-	ctx->readed	= 0;
-	ctx->errorcode = 0;
-
-	if (!ctx->stream) {
-		if (php_tnt_connect(ctx TSRMLS_CC)) {
-			zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-				"the can't open remote host " ,0 TSRMLS_DC);
-			return;
-		}
-	}
-
-// <insert_request_body> ::= <space_no><flags><tuple>
-// <update_request_body> ::= <space_no><flags><tuple><count><operation>+
-// <operation> ::= <field_no><op_code><op_arg>
-
-	char * out_buf = emalloc(TARANTOOL_BUFSIZE);
-	bzero(out_buf, TARANTOOL_BUFSIZE);
-
-	Header * header = (Header *) out_buf;
-
-	header->type		= TARANTOOL_UPDATE;
-	header->request_id	= TARANTOOL_REQUEST_ID;
-
-	InsertRequest * insert = (InsertRequest *) (out_buf + HEADER_SIZE);
-
-	insert->spaceNo = space;
-	insert->tuple.count = 1;
-
-	u_char * p = (u_char *) insert->tuple.data;
-
-	switch (Z_TYPE_P(key)) {
-		case IS_STRING: {
-//			*count_elements  = 1;	//!!!! <------- êîë-âî ýëåìåíòîâ â  êîðòåæå
-//			p += sizeof(uint32_t);
-
-				char * strval = Z_STRVAL_P(key);
-				int str_len = Z_STRLEN_P(key);
-				u_char str_shortlen = (u_char)str_len;
-
-				*(p++) = str_shortlen;
-				memcpy(p, strval, str_len);
-				p += str_len;
-
-//				printf("tuple: len=%d [%s]\n", str_len, strval );
-			}
-			break;
-
-		case IS_LONG: {
-//			*count_elements  = 1;	//!!!! <------- êîë-âî ýëåìåíòîâ â  êîðòåæå
-//			p += sizeof(uint32_t);
-
-			unsigned long val = Z_LVAL_P(key);
-
-		    u_char leb_size = 4; //(u_char)leb128_size( val);
-		    *(p++) = leb_size;
-
-			b2i * pb = (b2i*) p;
-			pb->i = (uint32_t) val;
-//		    leb128_write( (char *)p, val);
-		    p += leb_size;
-
-//			printf("tuple: int %d\n", val );
-			}
-			break;
-
-		default :
-			zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"unsupport key type" ,0 TSRMLS_CC);
-			return;
-	}
-
-	const int insertLen = p-insert->tuple.data;
-
-
-	HashTable *pht = Z_ARRVAL_P(data);
-
-	UpdateRequest  * updateRequest = (UpdateRequest*) p;
-	updateRequest->count = zend_hash_num_elements(pht);;
-
-	HashPosition pos;
-	zval** curr;
-
-	char *ht_key;
-	ulong index;
-	uint ht_key_len;
-
-	Operation * operation = &(updateRequest->operation);
-
-    for(zend_hash_internal_pointer_reset_ex(pht, &pos);
-          zend_hash_get_current_data_ex(pht, (void **) &curr, &pos) == SUCCESS;
-          zend_hash_move_forward_ex(pht,&pos)) {
-
-		if (HASH_KEY_IS_LONG != zend_hash_get_current_key_ex(pht, &ht_key, &ht_key_len, &index, 0, &pos)) {
-			efree(out_buf);
-			zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"key type error" ,0 TSRMLS_CC);
-			return;
-		}
-
-		operation->code = TARANTOOL_OP_ASSIGN;
-		operation->fieldNo = index;
-		p = operation->arg;
-
-		if (Z_TYPE_PP(curr) == IS_STRING)  {
-			char * strval = Z_STRVAL_PP(curr);
-			int str_len = Z_STRLEN_PP(curr);
-
-			u_char str_shortlen = (u_char)str_len;
-
-			*(p++) = str_shortlen;
-			memcpy(p, strval, str_len);
-			p += str_len;
-		}
-		if (Z_TYPE_PP(curr) == IS_LONG)  {
-		   unsigned long val = Z_LVAL_PP(curr);
-
-		    u_char leb_size = 4;
-		    *(p++) = leb_size;
-			b2i * pb = (b2i*) p;
-			pb->i = (uint32_t) val;
-		    p += leb_size;
-		}
-
-		operation = (Operation*)p;
-    }
-
-	u_char * p2 = (u_char *) insert;
-	header->len = (uint32_t) (p-p2);
-
-	// write header
-	int len = php_stream_write(ctx->stream, out_buf , HEADER_SIZE); // 12
-	if (len!=HEADER_SIZE) {
-		zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"error write header" ,0 TSRMLS_CC);
+	if (!buf)
 		return;
-	}
 
-//	write tuple
-	p = (u_char*) out_buf+HEADER_SIZE;
-	len = php_stream_write(ctx->stream, (char*)p , header->len ); //
-	if (len != header->len) {
-		zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"error write body" ,0 TSRMLS_CC);
-		return;
-	}
-
-	bzero(out_buf, header->len + HEADER_SIZE);
-//
-	len = php_stream_read(ctx->stream, out_buf, TARANTOOL_BUFSIZE);
-
-	if ( *(out_buf+HEADER_SIZE) == '\0') {
-		efree(out_buf);
-		RETURN_TRUE;
-	}
-
-	b2i* bb = (b2i*) out_buf+HEADER_SIZE;
-	ctx->errorcode = bb->i;
-
-	efree(out_buf);
-	RETURN_FALSE;
+	if (buf->value)
+		efree(buf->value);
 
+	efree(buf);
 }
-/* }}} */
-
 
-/* {{{ proto int tarantool::inc(int space, mixed key, int fieldNo, [data = 1, flag=0]);
-		$tnt->inc($NS,$key, $fieldNo , $inc=1;  );
-   tarantool incremental tuple */
-PHP_METHOD(tarantool_class, inc)
+inline static bool
+io_buf_reserve(struct io_buf *buf, size_t n)
 {
-	zval *id;
-	tarantool_object *ctx;
-	long space, fieldNo ;
-	zval* key;
-	long data = 1;
-	long flag = 0;
-
-	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Olzl|lb",
-			&id, tarantool_class_entry, &space, &key, &fieldNo, &data, &flag) == FAILURE) {
-		return;
-	}
+	if (buf->capacity > n)
+		return true;
 
-	ctx = (tarantool_object *)zend_object_store_get_object(id TSRMLS_CC);
-	if (!ctx) {
-		zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"the context is null" ,0 TSRMLS_CC);
-		return;
-	}
-
-	ctx->bodyLen = 0;
-	ctx->countTuples = 0;
-	ctx->readedTuples = 0;
-	ctx->readed	= 0;
-	ctx->errorcode = 0;
-
-	if (!ctx->stream) {
-		if (php_tnt_connect(ctx TSRMLS_CC)) {
-			zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-				"the can't open remote host " ,0 TSRMLS_DC);
-			return;
-		}
+	size_t new_capacity = io_buf_next_capacity(n);
+	uint8_t *new_value = (uint8_t *) erealloc(buf->value, new_capacity);
+	if (!new_value) {
+		raise_exception("allocation memory fail: %s (%i)", strerror(errno), errno);
+		return false;
 	}
 
-// <insert_request_body> ::= <space_no><flags><tuple>
-// <update_request_body> ::= <space_no><flags><tuple><count><operation>+
-
-// <operation> ::= <field_no><op_code><op_arg>
-
-	char * out_buf = emalloc(TARANTOOL_BUFSIZE);
-	bzero(out_buf, TARANTOOL_BUFSIZE);
-
-
-	Header * header = (Header *) out_buf;
-
-
-	header->type		= TARANTOOL_UPDATE;
-	header->request_id	= TARANTOOL_REQUEST_ID;
-
-	InsertRequest * insert = (InsertRequest *) (out_buf + HEADER_SIZE);
-
-	insert->spaceNo = space;
-	insert->tuple.count = 1;
-	insert->flag = flag;
-
-	u_char * p = (u_char *) insert->tuple.data;
-
-	switch (Z_TYPE_P(key)) {
-		case IS_STRING: {
-//			*count_elements  = 1;	//!!!! <------- êîë-âî ýëåìåíòîâ â  êîðòåæå
-//			p += sizeof(uint32_t);
-
-				char * strval = Z_STRVAL_P(key);
-				int str_len = Z_STRLEN_P(key);
-				u_char str_shortlen = (u_char)str_len;
+	buf->capacity = new_capacity;
+	buf->value = new_value;
+	return true;
+}
 
-				*(p++) = str_shortlen;
-				memcpy(p, strval, str_len);
-				p += str_len;
+inline static bool
+io_buf_resize(struct io_buf *buf, size_t n)
+{
+	io_buf_reserve(buf, n);
+	buf->size = n;
+	return true;
+}
 
-//				printf("tuple: len=%d [%s]\n", str_len, strval );
-			}
-			break;
+inline static size_t
+io_buf_next_capacity(size_t n)
+{
+	size_t capacity = IO_BUF_CAPACITY_MIN;
+	while (capacity < n)
+		capacity *= IO_BUF_CAPACITY_FACTOR;
+	return capacity;
+}
 
-		case IS_LONG: {
-//			*count_elements  = 1;	//!!!! <------- êîë-âî ýëåìåíòîâ â  êîðòåæå
-//			p += sizeof(uint32_t);
+static void
+io_buf_clean(struct io_buf *buf)
+{
+	buf->size = 0;
+	buf->readed = 0;
+}
 
-			unsigned long val = Z_LVAL_P(key);
+static bool
+read_struct_io_buf(struct io_buf *buf, void **ptr, size_t n)
+{
+	size_t last = buf->size - buf->readed;
+	if (last < n)
+		return false;
+	*ptr = buf->value + buf->readed;
+	buf->readed += n;
+	return true;
+}
 
-		    u_char leb_size = 4; //(u_char)leb128_size( val);
-		    *(p++) = leb_size;
+static bool
+read_int_io_buf(struct io_buf *buf, int32_t *val)
+{
+	size_t last = buf->size - buf->readed;
+	if (last < sizeof(int32_t))
+		return false;
+	*val = *(int32_t *)(buf->value + buf->readed);
+	buf->readed += sizeof(int32_t);
+	return true;
+}
 
-			b2i * pb = (b2i*) p;
-			pb->i = (uint32_t) val;
-//		    leb128_write( (char *)p, val);
-		    p += leb_size;
+static bool
+read_varint_io_buf(struct io_buf *buf, int32_t *val)
+{
+	uint8_t *b = buf->value + buf->readed;
+	size_t size = buf->size - buf->readed;
 
-//			printf("tuple: int %d\n", val );
-			}
-			break;
+	if (size < 1)
+		return false;
 
-		default :
-			zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"unsupport key type" ,0 TSRMLS_CC);
-			return;
+	if (!(b[0] & 0x80)) {
+		buf->readed += 1;
+		*val = (b[0] & 0x7f);
+		return true;
 	}
 
-	const int insertLen = p-insert->tuple.data;
-
-	UpdateRequest  * incRequest = (UpdateRequest*) p;
-	incRequest->count = 1;
-	incRequest->operation.code = TARANTOOL_OP_ADD;
-	incRequest->operation.fieldNo = fieldNo;
-
-	u_char leb_size = '\4';
-	if (data == 1) {
-		incRequest->operation.arg[0] = leb_size;
-		incRequest->operation.arg[1] = '\1';
-		incRequest->operation.arg[2] = '\0';
-		incRequest->operation.arg[3] = '\0';
-		incRequest->operation.arg[4] = '\0';
+	if (size < 2)
+		return false;
 
-	} else {
-		p = incRequest->operation.arg;
-		*(p++) = leb_size;
-		b2i * pb = (b2i*) p;
-		pb->i = (int) data;
-		p += leb_size;
+	if (!(b[1] & 0x80)) {
+		buf->readed += 2;
+		*val = (b[0] & 0x7f) << 7 | (b[1] & 0x7f);
+		return true;
 	}
 
-	header->len = INSERT_REQUEST_SIZE + insertLen + UPDATE_REQUEST_SIZE + (int)leb_size;
-
-	// write header
-	int len = php_stream_write(ctx->stream, out_buf , HEADER_SIZE); // 12
-	if (len!=HEADER_SIZE) {
-		efree(out_buf);
-		zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"error write header" ,0 TSRMLS_CC);
-		return;
-	}
+	if (size < 3)
+		return false;
 
-//	write tuple
-	p = (u_char*) out_buf+HEADER_SIZE;
-	len = php_stream_write(ctx->stream, (char*)p , header->len ); //
-	if (len != header->len) {
-		efree(out_buf);
-		zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"error write body" ,0 TSRMLS_CC);
-		return;
+	if (!(b[2] & 0x80)) {
+		buf->readed += 3;
+		*val = (b[0] & 0x7f) << 14 | (b[1] & 0x7f) << 7 | (b[2] & 0x7f);
+		return true;
 	}
 
+	if (size < 4)
+		return false;
 
-	bzero(out_buf, header->len + HEADER_SIZE);
-//
-	len = php_stream_read(ctx->stream, out_buf, TARANTOOL_BUFSIZE);
-
-	if ( *(out_buf+HEADER_SIZE) != '\0') {
-		b2i* bb = (b2i*)(out_buf+HEADER_SIZE);
-		ctx->errorcode = bb->i;
-		efree(out_buf);
-		RETURN_FALSE;
+	if (!(b[3] & 0x80)) {
+		buf->readed += 4; 
+		*val = (b[0] & 0x7f) << 21 | (b[1] & 0x7f) << 14 |
+			(b[2] & 0x7f) << 7 | (b[3] & 0x7f);
+		return true;
 	}
 
-	if( !flag)
-		RETURN_TRUE;
-
-	Response * responseBody = (Response*) (out_buf+HEADER_SIZE);
-	SelectResponseTuple * responseTuple = (SelectResponseTuple*) responseBody->data;
-
-	p = responseBody->data + SELECT_RESPONSE_SIZE;
+	if (size < 5)
+		return false;
 
-	int i=0;
-	int8_t * size;
-	while (i < fieldNo) {
-		size = (int8_t*) p;
-		p += *size+1;
-		i++;
+	if (!(b[4] & 0x80)) {
+		buf->readed += 5;
+		*val = (b[0] & 0x7f) << 28 | (b[1] & 0x7f) << 21 |
+			(b[2] & 0x7f) << 14 | (b[3] & 0x7f) << 7 | (b[4] & 0x7f);
+		return true;
 	}
 
-	b2i* bb = (b2i*)(p+1);
-
-	efree(out_buf);
-	RETURN_LONG(bb->i);
-
-
+	return false;
 }
-/* }}} */
-
 
-/* {{{ proto string tarantool::getError();
-   returb tarantool error string */
-
-PHP_METHOD(tarantool_class, getError)
+static bool
+read_str_io_buf(struct io_buf *buf, char **str, size_t len)
 {
-	zval *id;
-	tarantool_object *ctx;
-
-	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id,
-		tarantool_class_entry) == FAILURE) {
-		return;
-	}
-
-	ctx = (tarantool_object *)zend_object_store_get_object(id TSRMLS_CC);
-	if (!ctx) {
-		zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"the context is null" ,0 TSRMLS_CC);
-		return;
-	}
-
-	switch(ctx->errorcode) {
-		case 0: { RETURN_STRING("Result Ok",1); break; }
-		case 258: {RETURN_STRING("Non master connection, but it should be",1); break; }
-		case 514: {RETURN_STRING("Illegal parametrs",1); break; }
-		case 770: {RETURN_STRING("Uid not from this storage range",1); break; }
-		case 1025: {RETURN_STRING("Node is marked as read-only",1); break; }
-		case 1281: {RETURN_STRING("Node isn't locked",1); break; }
-		case 1537: {RETURN_STRING("Node is locked",1); break; }
-		case 1793: {RETURN_STRING("Some memory issues",1); break; }
-		case 0x00000802: {RETURN_STRING("Bad graph integrity",1); break; }
-		case 0x00000a02: {RETURN_STRING("Unsupported command",1); break; }
-		case 0x00001801: {RETURN_STRING("Can't register new user",1); break; }
-		case 0x00001a01: {RETURN_STRING("Can't generate alert id",1); break; }
-		case 0x00001b02: {RETURN_STRING("Can't del node",1); break; }
-		case 0x00001c02: {RETURN_STRING("User isn't registered",1); break; }
-		case 0x00001d02: {RETURN_STRING("Syntax error in query",1); break; }
-		case 0x00001e02: {RETURN_STRING("Unknown field",1); break; }
-		case 0x00001f02: {RETURN_STRING("Number value is out of range",1); break; }
-		case 0x00002002: {RETURN_STRING("Insert already existing object",1); break; }
-		case 0x00002202: {RETURN_STRING("Can not order result",1); break; }
-		case 0x00002302: {RETURN_STRING("Multiple to update/delete",1); break; }
-		case 0x00002400: {RETURN_STRING("nothing to do (not an error)",1); break; }
-		case 0x00002502: {RETURN_STRING("id's update",1); break; }
-		case 0x00002602: {RETURN_STRING("unsupported version of protocol",1); break; }
-
-		case 0x00002702: {RETURN_STRING("Unknow error",1); break; }
-		case 0x00003102: {RETURN_STRING("Node not found",1); break; }
-
-		case 0x00003702: {RETURN_STRING("Node found",1); break; }
-		case 0x00003802: {RETURN_STRING("INDEX violation",1); break; }
-		case 0x00003902: {RETURN_STRING("No such space",1); break; }
-
-		default : {
-				char * err_string;
-				int len = spprintf(&err_string, 0, "Unknow error code : %X\n", ctx->errorcode);
-				RETVAL_STRINGL(err_string, len,1);
-				efree(err_string);
-			}
-	}
-
+	size_t last = buf->size - buf->readed;
+	if (last < len)
+		return false;
+	*str = (char *)(buf->value + buf->readed);
+	buf->readed += len;
+	return true;
 }
-/* }}}*/
-
 
-/* {{{ proto string tarantool::getInfo();
-   return tarantool info string */
-PHP_METHOD(tarantool_class, getInfo)
+static bool
+read_field_io_buf(struct io_buf *buf, zval *tuple)
 {
-	zval *id;
-	tarantool_object *ctx;
-	size_t response_len=0;
-
-	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id,
-		tarantool_class_entry) == FAILURE) {
-		return;
-	}
-
-	ctx = (tarantool_object *)zend_object_store_get_object(id TSRMLS_CC);
-	if (!ctx) {
-		zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"the context is null" ,0 TSRMLS_CC);
-		return;
-	}
-
-	if (!ctx->admin_stream) {
-		if (php_tnt_admin_connect(ctx TSRMLS_CC)) {
-			zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-				"the can't open remote host " ,0 TSRMLS_DC);
-			return;
-		}
-	}
-
-	if (php_stream_write(ctx->admin_stream, TARANTOOL_SHOW_INFO, TARANTOOL_SHOW_INFO_SIZE) != TARANTOOL_SHOW_INFO_SIZE) {
-		zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"Failed sending command" ,0 TSRMLS_DC);
-		return;
-	}
-
-	char * buf=emalloc(TARANTOOL_SMALL_BUFSIZE);
-	bzero(buf,TARANTOOL_SMALL_BUFSIZE);
-
-	response_len = php_stream_read(ctx->admin_stream, buf, TARANTOOL_SMALL_BUFSIZE);
-
-	if (response_len) {
-		RETVAL_STRINGL(buf,response_len,1);
-		efree(buf);
-		return;
+	int32_t field_length;
+
+	if (!read_varint_io_buf(buf, &field_length))
+		return false;
+
+	int32_t i32_val;
+	char *str_val;
+	switch (field_length) {
+	case sizeof(int32_t):
+		if (!read_int_io_buf(buf, &i32_val))
+			return false;
+		add_next_index_long(tuple, i32_val);
+		break;
+	default:
+		if (!read_str_io_buf(buf, &str_val, field_length))
+			return false;
+		add_next_index_stringl(tuple, str_val, field_length, true);
 	}
 
-	efree(buf);
-	RETURN_FALSE;
-
+	return true;
 }
-/* }}}*/
 
-/* {{{ proto string tarantool::getConf();
-   returb tarantool info string */
-PHP_METHOD(tarantool_class, getConf)
+static bool
+read_tuple_io_buf(struct io_buf *buf, zval **tuple)
 {
-	zval *id;
-	tarantool_object *ctx;
-	size_t response_len=0;
-
-	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id,
-		tarantool_class_entry) == FAILURE) {
-		return;
+	MAKE_STD_ZVAL(*tuple);
+	if (array_init(*tuple) == FAILURE) {
+		return false;
 	}
 
-	ctx = (tarantool_object *)zend_object_store_get_object(id TSRMLS_CC);
-	if (!ctx) {
-		zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"the context is null" ,0 TSRMLS_CC);
-		return;
-	}
+	int32_t size;
+	if (!read_int_io_buf(buf, &size))
+		return false;
 
-	if (!ctx->admin_stream) {
-		if (php_tnt_admin_connect(ctx TSRMLS_CC)) {
-			zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-				"the can't open remote host " ,0 TSRMLS_DC);
-			return;
-		}
-	}
-
-	if (php_stream_write(ctx->admin_stream, TARANTOOL_SHOW_CONF, TARANTOOL_SHOW_CONF_SIZE) != TARANTOOL_SHOW_CONF_SIZE) {
-		zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"Failed sending command" ,0 TSRMLS_DC);
-		return;
-	}
-
-	char * buf = emalloc(TARANTOOL_BUFSIZE);
-	response_len = php_stream_read(ctx->admin_stream, buf, TARANTOOL_BUFSIZE);
+	int32_t cardinality;
+	if (!read_int_io_buf(buf, &cardinality))
+		return false;
 
-	if (response_len) {
-		RETVAL_STRINGL(buf,response_len,1);
-		efree(buf);
-		return;
+	while (cardinality > 0) {
+		if (!read_field_io_buf(buf, *tuple))
+			return false;
+		cardinality -= 1;
 	}
 
-	efree(buf);
-	RETURN_FALSE;
+	return true;
+}
 
+static void *
+io_buf_write_struct(struct io_buf *buf, size_t n)
+{
+	if (!io_buf_reserve(buf, buf->size + n))
+		return NULL;
+	void *ptr = buf->value + buf->size;
+	buf->size += n;
+	return ptr;
 }
-/* }}}*/
 
-/* {{{ proto string tarantool::getStat();
-   returb tarantool statistic string */
-PHP_METHOD(tarantool_class, getStat)
+static bool
+io_buf_write_byte(struct io_buf *buf, int8_t value)
 {
-	zval *id;
-	tarantool_object *ctx;
-	size_t response_len=0;
+	if (!io_buf_reserve(buf, buf->size + sizeof(int8_t)))
+		return false;
+	*(int8_t *)(buf->value + buf->size) = value;
+	buf->size += sizeof(uint8_t);
+	return true;
+}
 
-	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id,
-		tarantool_class_entry) == FAILURE) {
-		return;
-	}
+static bool
+io_buf_write_int32(struct io_buf *buf, int32_t value)
+{
+	if (!io_buf_reserve(buf, buf->size + sizeof(int32_t)))
+		return false;
+	*(int32_t *)(buf->value + buf->size) = value;
+	buf->size += sizeof(int32_t);
+	return true;
+}
 
-	ctx = (tarantool_object *)zend_object_store_get_object(id TSRMLS_CC);
-	if (!ctx) {
-		zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"the context is null" ,0 TSRMLS_CC);
-		return;
-	}
+static bool
+io_buf_write_varint(struct io_buf *buf, int32_t value)
+{
+	if (!io_buf_reserve(buf, buf->size + 5))
+		/* reseve maximal varint size (5 bytes) */
+		return false;
 
-	if (!ctx->admin_stream) {
-		if (php_tnt_admin_connect(ctx TSRMLS_CC)) {
-			zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-				"the can't open remote host " ,0 TSRMLS_DC);
-			return;
+	if (value >= (1 << 7)) {
+		if (value >= (1 << 14)) {
+			if (value >= (1 << 21)) {
+				if (value >= (1 << 28))
+					io_buf_write_byte(buf, (int8_t)(value >> 28) | 0x80);
+				io_buf_write_byte(buf, (int8_t)(value >> 21) | 0x80);
+			}
+			io_buf_write_byte(buf, (int8_t)((value >> 14) | 0x80));
 		}
+		io_buf_write_byte(buf, (int8_t)((value >> 7) | 0x80));
 	}
+	io_buf_write_byte(buf, (int8_t)((value) & 0x7F));
 
-	if (php_stream_write(ctx->admin_stream, TARANTOOL_SHOW_STAT, TARANTOOL_SHOW_STAT_SIZE) != TARANTOOL_SHOW_STAT_SIZE) {
-		zend_throw_exception(zend_exception_get_default(TSRMLS_C),
-			"Failed sending command" ,0 TSRMLS_DC);
-		return;
-	}
-
-	char * buf = emalloc(TARANTOOL_SMALL_BUFSIZE);
-	bzero(buf,TARANTOOL_SMALL_BUFSIZE);
-
-	response_len = php_stream_read(ctx->admin_stream, buf, TARANTOOL_SMALL_BUFSIZE);
-
-	if (response_len) {
-		RETVAL_STRINGL(buf,response_len,1);
-		efree(buf);
-		return;
-	}
+	return true;
+}
 
-	efree(buf);
-	RETURN_FALSE;
+static bool
+io_buf_write_str(struct io_buf *buf, uint8_t *str, size_t len)
+{
+	if (!io_buf_reserve(buf, buf->size + len))
+		return false;
 
+	memcpy(buf->value + buf->size, str, len);
+	buf->size += len;
+	return true;
 }
-/* }}}*/
 
-static void printLine( u_char *p ) {
-	u_char b[4];
-	memcpy(b, p, 4);
-	php_printf("%x %x %x %x\t\t", b[0], b[1], b[2], b[3]);
+static bool
+io_buf_write_field(struct io_buf *buf, uint8_t *field_value, size_t field_length)
+{
+	if (!io_buf_write_varint(buf, (int32_t)field_length))
+		return false;
+	if (!io_buf_write_str(buf, field_value, field_length))
+		return false;
+	return true;
 }
 
-static void printLine3( u_char *p ) {
-	u_char b[12];
-	memcpy(b, p, 12);
-	php_printf("%x %x %x %x\t\t", b[0], b[1], b[2], b[3]);
-	php_printf("%x %x %x %x\t\t", b[4], b[5], b[6], b[7]);
-	php_printf("%x %x %x %x\n", b[8], b[9], b[10], b[11]);
+static bool
+io_buf_write_tuple_int(struct io_buf *buf, zval *tuple)
+{
+	/* single field tuple: (int) */
+	long long_value = Z_LVAL_P(tuple);
+	/* write tuple cardinality */
+	if (!io_buf_write_int32(buf, 1))
+		return false;
+	/* write field */
+	if (!io_buf_write_field(buf, (uint8_t *)&long_value, sizeof(int32_t)))
+		return false;
+
+	return true;
 }
 
+static bool
+io_buf_write_tuple_str(struct io_buf *buf, zval *tuple)
+{
+	/* single field tuple: (string) */
+	char *str_value = Z_STRVAL_P(tuple);
+	size_t str_length = Z_STRLEN_P(tuple);
+	/* write tuple cardinality */
+	if (!io_buf_write_int32(buf, 1))
+		return false;
+	/* write field */
+	if (!io_buf_write_field(buf, str_value, str_length))
+		return false;
+
+	return true;
+}
 
-static void
-leb128_write(char * buf, unsigned long value)
+static bool
+io_buf_write_tuple_array(struct io_buf *buf, zval *tuple)
 {
-	if (value >= (1 << 7)) {
-		if (value >= (1 << 14)) {
-			if (value >= (1 << 21)) {
-				if (value >= (1 << 28))
-					*(buf++) = (value >> 28) | 0x80;
-				*(buf++) = (value >> 21) | 0x80;
-			}
-			*(buf++) = ((value >> 14) | 0x80);
+	/* multyply tuple array */
+	HashTable *hash = Z_ARRVAL_P(tuple);
+	HashPosition itr;
+	zval **field;
+	/* put tuple cardinality */
+	io_buf_write_int32(buf, zend_hash_num_elements(hash));
+	for (zend_hash_internal_pointer_reset_ex(hash, &itr);
+		 zend_hash_get_current_data_ex(hash, (void **) &field, &itr) == SUCCESS;
+		 zend_hash_move_forward_ex(hash, &itr)) {
+		char *str_value;
+		size_t str_length;
+		long long_value;
+
+		switch (Z_TYPE_PP(field)) {
+		case IS_STRING:
+			/* string field */
+			str_value = Z_STRVAL_PP(field);
+			str_length = Z_STRLEN_PP(field);
+			io_buf_write_field(buf, str_value, str_length);
+			break;
+		case IS_LONG:
+			/* integer field */
+			long_value = Z_LVAL_PP(field);
+			io_buf_write_field(buf, (uint8_t *)&long_value, sizeof(int32_t));
+			break;
+		default:
+			raise_exception("unsupported field type");
+			return false;
 		}
-		*(buf++) = ((value >> 7) | 0x80);
 	}
-	*(buf++) = ((value) & 0x7F);
 
+	return true;
 }
 
-static int
-leb128_read(char * buf, int size, unsigned long * value)
+static bool
+io_buf_write_tuple(struct io_buf *buf, zval *tuple)
 {
-	*value = 0;
-
-	if (size < 1)
-		return -1;
+	switch (Z_TYPE_P(tuple)) {
+	case IS_LONG:
+		return io_buf_write_tuple_int(buf, tuple);
+	case IS_STRING:
+		return io_buf_write_tuple_str(buf, tuple);
+	case IS_ARRAY:
+		return io_buf_write_tuple_array(buf, tuple);
+	default:
+		raise_exception("unsupported tuple type");
+		return false;		
+	}
+
+	return true;
+}
 
-	if (!(buf[0] & 0x80)) {
+static bool
+io_buf_write_tuples_list_array(struct io_buf *buf, zval *tuples_list)
+{
+	HashTable *hash = Z_ARRVAL_P(tuples_list);
+	HashPosition itr;
+	zval **tuple;
+
+	/* write number of tuples */
+	if (!io_buf_write_int32(buf, zend_hash_num_elements(hash)))
+		return false;
+
+	/* write tuples */
+	for (zend_hash_internal_pointer_reset_ex(hash, &itr);
+		 zend_hash_get_current_data_ex(hash, (void **) &tuple, &itr) == SUCCESS;
+		 zend_hash_move_forward_ex(hash, &itr)) {
+		if (Z_TYPE_PP(tuple) != IS_ARRAY) {
+			raise_exception("invalid tuples list: expected array of array");
+			return false;
+		}
 
-		*value = buf[0] & 0x7f;
-		return 1;
+		if (!io_buf_write_tuple_array(buf, *tuple))
+			return false;
 	}
 
-	if (size < 2)
-		return -1;
-
-	if (!(buf[1] & 0x80)) {
+	return true;
+}
 
-		*value = (buf[0] & 0x7f) << 7 |
-		         (buf[1] & 0x7f);
-		return 2;
-	}
 
-	if (size < 3)
-		return -1;
+static bool
+io_buf_write_tuples_list(struct io_buf *buf, zval *tuples_list)
+{
+	HashTable *hash;
+	HashPosition itr;
+	zval **tuple;
+
+	switch (Z_TYPE_P(tuples_list)) {
+	case IS_LONG:
+		/* single tuple: long */
+		/* write number of tuples */
+		if (!io_buf_write_int32(buf, 1))
+			return false;
+		/* write tuple */
+		if (!io_buf_write_tuple_int(buf, tuples_list))
+			return false;
+		break;
+	case IS_STRING:
+		/* single tuple: string */
+		/* write number of tuples */
+		if (!io_buf_write_int32(buf, 1))
+			return false;		
+		/* write tuple */
+		if (!io_buf_write_tuple_str(buf, tuples_list))
+			return false;
+		break;
+	case IS_ARRAY:
+		/* array: migth be single or multi tuples array */
+		hash = Z_ARRVAL_P(tuples_list);
+		zend_hash_internal_pointer_reset_ex(hash, &itr);		
+		if (zend_hash_get_current_data_ex(hash, (void **) &tuple, &itr) != SUCCESS) {
+			raise_exception("invalid tuples list: empty array");
+			return false;
+		}
 
-	if (!(buf[2] & 0x80)) {
+		/* check type of the first element */
+		switch (Z_TYPE_PP(tuple)) {
+		case IS_STRING:
+		case IS_LONG:
+			/* single tuple: array */
+			/* write tuples count */
+			if (!io_buf_write_int32(buf, 1))
+				return false;
+			/* write tuple */
+			if (!io_buf_write_tuple_array(buf, tuples_list))
+				return false;
+			break;
+		case IS_ARRAY:
+			/* multi tuples list */
+			if (!io_buf_write_tuples_list_array(buf, tuples_list))
+				return false;
+			break;
+		default:
+			/* invalid element type */
+			raise_exception("unsupported tuple type");
+			return false;
+		}
 
-		*value = (buf[0] & 0x7f) << 14 |
-				 (buf[1] & 0x7f) << 7  |
-				 (buf[2] & 0x7f);
-		return 3;
+		break;
+	default:
+		raise_exception("unsupported tuple type");
+		return false;		
 	}
 
-	if (size < 4)
-		return -1;
+	return true;
+}
 
-	if (!(buf[3] & 0x80)) {
 
-		*value = (buf[0] & 0x7f) << 21 |
-				 (buf[1] & 0x7f) << 14 |
-				 (buf[2] & 0x7f) << 7  |
-				 (buf[3] & 0x7f);
-		return 4;
-	}
+/*----------------------------------------------------------------------------*
+ * Tarantool class functions
+ *----------------------------------------------------------------------------*/
 
-	if (size < 5)
-		return -1;
 
-	if (!(buf[4] & 0x80)) {
+/*----------------------------------------------------------------------------*
+ * alloc/free classes functions
+ *----------------------------------------------------------------------------*/
 
-		*value = (buf[0] & 0x7f) << 28 |
-		         (buf[1] & 0x7f) << 21 |
-				 (buf[2] & 0x7f) << 14 |
-				 (buf[3] & 0x7f) << 7  |
-				 (buf[4] & 0x7f);
-		return 5;
-	}
+static zend_object_value
+alloc_tarantool_object(zend_class_entry *entry TSRMLS_DC)
+{
+	zend_object_value new_value;
 
-	return -1;
+	/* allocate and clean-up instance */
+	tarantool_object *tnt = (tarantool_object *) emalloc(sizeof(tarantool_object));
+	/* TODO: emalloc result must be checked */
+	memset(tnt, 0, sizeof(tarantool_object));
+
+	/* initialize class instance */
+	zend_object_std_init(&tnt->zo, entry TSRMLS_CC);
+	new_value.handle = zend_objects_store_put(
+		tnt,
+		(zend_objects_store_dtor_t) zend_objects_destroy_object, 
+		(zend_objects_free_object_storage_t) free_tarantool_object,
+		NULL TSRMLS_CC);
+ 	new_value.handlers = zend_get_std_object_handlers();
+	return new_value;
 }
 
-
-static int
-leb128_size(unsigned long value)
+static void
+free_tarantool_object(tarantool_object *tnt TSRMLS_DC)
 {
-	if (value < (1 << 7))
-		return 1;
-
-	if (value < (1 << 14))
-		return 2;
+	if (tnt == NULL)
+		return;
 
-	if (value < (1 << 21))
-		return 3;
+	if (tnt->stream)
+		php_stream_close(tnt->stream);
 
-	if (value < (1 << 28))
-		return 4;
+	if (tnt->admin_stream)
+		php_stream_close(tnt->admin_stream);
 
-	return 5;
+	io_buf_destroy(tnt->io_buf);
+	io_buf_destroy(tnt->splice_field);
+	efree(tnt);
 }
 
+
+/*----------------------------------------------------------------------------*
+ * raise exceation functions
+ *----------------------------------------------------------------------------*/
+
 static void
-tarantool_dtor(void *object TSRMLS_DC)
+raise_exception(const char *format, ...)
 {
-	tarantool_object *ctx = (tarantool_object*)object;
+	/* format exception message */
+	va_list ap;
+	va_start(ap, format);
+	char *message = NULL;
+	vspprintf(&message, 0, format, ap);
+	va_end(ap);
+	/* check formated message */
+	if (message == NULL)
+		message = "error: can't format error message";
+
+	/* throw exception */
+	zend_throw_exception(zend_exception_get_default(TSRMLS_C),
+						 message,
+						 0 TSRMLS_DC);
+}
 
-	if (ctx) {
-		if (ctx->stream) {
-			php_stream_close(ctx->stream);
-		}
 
-		if (ctx->admin_stream) {
-			php_stream_close(ctx->admin_stream);
-		}
+/*----------------------------------------------------------------------------*
+ * php stream functions
+ *----------------------------------------------------------------------------*/
 
-		if (ctx->host) {
-			efree(ctx->host);
-		}
+static php_stream *
+establish_connection(char *host, int port)
+{
+	char *msg = NULL;
+	/* initialize connection parameters */
+	char *dest_addr = NULL;
+	size_t dest_addr_len = spprintf(&dest_addr, 0, "tcp://%s:%d", host, port);
+	int options = ENFORCE_SAFE_MODE | REPORT_ERRORS;
+	int flags = STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT;
+	struct timeval timeout = {
+		.tv_sec = TARANTOOL_TIMEOUT_SEC,
+		.tv_usec = TARANTOOL_TIMEOUT_USEC,
+	};
+	char *error_msg = NULL;
+	int error_code = 0;
+
+	/* establish connection */
+	php_stream *stream = php_stream_xport_create(dest_addr, dest_addr_len,
+												 options, flags,
+												 NULL, &timeout, NULL,
+												 &error_msg, &error_code);
+	efree(dest_addr);
+
+	/* check result */
+	if (error_code && error_msg) {
+		raise_exception("establist connection fail: %s", error_msg);
+		efree(error_msg);
+		return NULL;
+	}
+
+	return stream;
+}
 
+static bool
+send_admin_request(php_stream *stream, struct io_buf *buf)
+{
+	if (php_stream_write(stream,
+						 buf->value,
+						 buf->size) != buf->size) {
+		raise_exception("send message fail");
+		return false;
 	}
 
-	zend_object_std_dtor(&ctx->zo TSRMLS_CC);
+	return true;
+}
+
+static bool
+recv_admin_response(php_stream *stream, struct io_buf *buf)
+{
+	char *line = php_stream_get_line(stream, NULL, 0, NULL);
+	while (strcmp(line, ADMIN_TOKEN_BEGIN) != 0) {
+		line = php_stream_get_line(stream, NULL, 0, NULL);
+	}
 
-	efree(object);
+	line = php_stream_get_line(stream, NULL, 0, NULL);
+	while (strcmp(line, ADMIN_TOKEN_END) != 0) {
+		io_buf_write_str(buf, line, strlen(line));
+		line = php_stream_get_line(stream, NULL, 0, NULL);
+	}
 
+	return true;
 }
 
-static zend_object_value tarantool_ctor(zend_class_entry *ce TSRMLS_DC)
+static bool
+send_iproto_request(php_stream *stream, int32_t type, int32_t request_id, struct io_buf *buf)
 {
-	zend_object_value new_value;
-	tarantool_object* obj = (tarantool_object*)emalloc(sizeof(tarantool_object));
-	memset(obj, 0, sizeof(tarantool_object));
+	/* send iproto header */
+	struct iproto_header header;
+	header.type = type;
+	header.length = buf->size;
+	header.request_id = request_id;
 
-	zend_object_std_init(&obj->zo, ce TSRMLS_CC);
+	size_t length = sizeof(struct iproto_header);
+	if (php_stream_write(stream, (char *) &header, length) != length) {
+		raise_exception("send requset failed");
+		return false;
+	}
 
-	new_value.handle = zend_objects_store_put(obj, (zend_objects_store_dtor_t)zend_objects_destroy_object,
-		(zend_objects_free_object_storage_t)tarantool_dtor, NULL TSRMLS_CC);
-	new_value.handlers = zend_get_std_object_handlers();
+	/* send requets */
+	if (php_stream_write(stream, buf->value, buf->size) != buf->size) {
+		raise_exception("send requset failed");
+		return false;
+	}
 
-	return new_value;
+	return true;
 }
 
-/* {{{ PHP_MINIT_FUNCTION
- */
-PHP_MINIT_FUNCTION(tarantool)
+static bool
+recv_iproto_response(php_stream *stream, struct io_buf *buf)
 {
-	zend_class_entry ce;
+	/* receiving header */
+	struct iproto_header header;
+	size_t length = sizeof(struct iproto_header);
+	if (php_stream_read(stream, (char *) &header, length) != length) {
+		raise_exception("receive response failed");
+		return false;
+	}
 
-	INIT_CLASS_ENTRY(ce, "Tarantool", tarantool_class_functions);
-	ce.create_object = tarantool_ctor;
-	tarantool_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
+	/* receiving body */
+	if (!io_buf_resize(buf, header.length))
+		return false;
+	if (php_stream_read(stream, buf->value, buf->size) != buf->size) {
+		raise_exception("receive response failed");
+		return false;
+	}
 
-	return SUCCESS;
+	return true;
 }
-/* }}} */
 
-/* {{{ PHP_MSHUTDOWN_FUNCTION
- */
-PHP_MSHUTDOWN_FUNCTION(tarantool)
+
+/*----------------------------------------------------------------------------*
+ * php hash functions
+ *----------------------------------------------------------------------------*/
+
+static bool
+hash_fing_long(HashTable *hash, char *key, long *value)
 {
-	/* uncomment this line if you have INI entries
-	UNREGISTER_INI_ENTRIES();
-	*/
-	return SUCCESS;
+	zval **zvalue = NULL;
+	if (zend_hash_find(hash, key, strlen(key) + 1, (void **)&zvalue) != SUCCESS)
+		return false;
+	if (Z_TYPE_PP(zvalue) != IS_LONG)
+		return false;
+	*value = Z_LVAL_PP(zvalue);
+	return true;
 }
-/* }}} */
-
 
-/* {{{ PHP_MINFO_FUNCTION
- */
-PHP_MINFO_FUNCTION(tarantool)
+static bool
+hash_fing_str(HashTable *hash, char *key, char **value, int *value_length)
 {
-	php_info_print_table_start();
-	php_info_print_table_header(2, "tarantool_box support", "enabled");
-	php_info_print_table_row(2,		"default host", TARANTOOL_DEF_HOST);
-	php_info_print_table_row(2,		"default port", TARANTOOL_DEF_PORT);
-	php_info_print_table_row(2,		"admin port",	TARANTOOL_ADMIN_PORT);
-	php_info_print_table_row(2,		"timeout in sec",TARANTOOL_TIMEOUT);
-	php_info_print_table_end();
+	zval **zvalue = NULL;
+	if (zend_hash_find(hash, key, strlen(key) + 1, (void **)&zvalue) != SUCCESS)
+		return false;
+	if (Z_TYPE_PP(zvalue) != IS_STRING)
+		return false;
+	*value = Z_STRVAL_PP(zvalue);
+	*value_length = Z_STRLEN_PP(zvalue);
+	return true;
+}
 
-	/* Remove comments if you have entries in php.ini
-	DISPLAY_INI_ENTRIES();
-	*/
+static bool
+hash_fing_scalar(HashTable *hash, char *key, zval ***value)
+{
+	if (zend_hash_find(hash, key, strlen(key) + 1, (void **)value) != SUCCESS)
+		return false;
+	if (Z_TYPE_PP(*value) != IS_STRING && Z_TYPE_PP(*value) != IS_LONG)
+		return false;
+	return true;
 }
-/* }}} */
+
 
 /*
  * Local variables:
diff --git a/connector/php/tarantool.h b/connector/php/tarantool.h
index a05dfeacfd..6c52876f5e 100644
--- a/connector/php/tarantool.h
+++ b/connector/php/tarantool.h
@@ -16,79 +16,163 @@
   | Copyright (c) 2011                                                   |
   +----------------------------------------------------------------------+
 */
-
-/* $Id: header 252479 2008-02-07 19:39:50Z iliaa $ */
-
 #ifndef PHP_TARANTOOL_H
 #define PHP_TARANTOOL_H
 
-extern zend_module_entry tarantool_module_entry;
-#define phpext_tarantool_ptr &tarantool_module_entry
-
-#ifdef PHP_WIN32
-#	define PHP_TARANTOOL_API __declspec(dllexport)
-#elif defined(__GNUC__) && __GNUC__ >= 4
-#	define PHP_TARANTOOL_API __attribute__ ((visibility("default")))
-#else
-#	define PHP_TARANTOOL_API
+#ifdef ZTS
+#include "TSRM.h"
 #endif
 
-#define TARANTOOL_TIMEOUT  5 // sec
-#define TARANTOOL_DEF_PORT 33013
-#define TARANTOOL_ADMIN_PORT 33015
 
-#define TARANTOOL_DEF_HOST "localhost"
-#define TARANTOOL_BUFSIZE  2048 
-#define TARANTOOL_SMALL_BUFSIZE  256 
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+
+/*----------------------------------------------------------------------------*
+ * tbuf constants
+ *----------------------------------------------------------------------------*/
+
+enum {
+	/* tbuf minimal capacity */
+	IO_BUF_CAPACITY_MIN = 128,
+	/* tbuf factor */
+	IO_BUF_CAPACITY_FACTOR = 2,
+};
+
+
+/*----------------------------------------------------------------------------*
+ * Connections constants
+ *----------------------------------------------------------------------------*/
+
+enum {
+	/* timeout: seconds */
+	TARANTOOL_TIMEOUT_SEC = 5,
+	/* timeout: microseconds */
+	TARANTOOL_TIMEOUT_USEC = 0,
+	/* tarantool default primary port */
+	TARANTOOL_DEFAULT_PORT = 33013,
+	/* tarantool default readonly port */
+	TARANTOOL_DEFAULT_RO_PORT = 33014,
+	/* tarantool default adnim port */
+	TARANTOOL_DEFAULT_ADMIN_PORT = 33015,
+};
+
+#define TARANTOOL_DEFAULT_HOST "localhost"
+
+
+/*----------------------------------------------------------------------------*
+ * Commands constants
+ *----------------------------------------------------------------------------*/
+
+/* tarantool/box flags */
+enum {
+	/* return resulting tuples */
+	TARANTOOL_FLAGS_RETURN_TUPLE = 0x01,
+	/* insert is add operation: errro will be raised if tuple exists */
+	TARANTOOL_FLAGS_ADD = 0x02,
+	/* insert is replace operation: errro will be raised if tuple doesn't exist */
+	TARANTOOL_FLAGS_REPLACE = 0x04,
+	/* doesn't write command to WAL */
+	TARANTOOL_FLAGS_NOT_STORE = 0x10,
+};
+
+/* tarantool command codes */
+enum {
+	/* insert/replace command code */
+	TARANTOOL_COMMAND_INSERT = 13,
+	/* select command code */
+	TARANTOOL_COMMAND_SELECT = 17,
+	/* update fields command code */
+	TARANTOOL_COMMAND_UPDATE = 19,
+	/* delete command code */
+	TARANTOOL_COMMAND_DELETE = 21,
+	/* call lua function command code */
+	TARANTOOL_COMMAND_CALL = 22,
+	/* pid command code */
+	TARANTOOL_COMMAND_PING = 65280,
+};
+
+/* update fields operation codes */
+enum {
+	/* update fields: assing field value operation code */
+	TARANTOOL_OP_ASSIGN = 0,
+	/* update fields: add operation code */
+	TARANTOOL_OP_ADD = 1,
+	/* update fields: and operation code */
+	TARANTOOL_OP_AND = 2,
+	/* update fields: xor operation code */
+	TARANTOOL_OP_XOR = 3,
+	/* update fields: or operation code */
+	TARANTOOL_OP_OR	= 4,
+	/* update fields: splice operation code */
+	TARANTOOL_OP_SPLICE = 5,
+};
+
+
+/*----------------------------------------------------------------------------*
+ * Amdin commands
+ *----------------------------------------------------------------------------*/
+
+/* admin protocol separator */
+#define ADMIN_SEPARATOR "\r\n"
+/* admin command begin token */
+#define ADMIN_TOKEN_BEGIN "---"ADMIN_SEPARATOR
+/* admin command end token */
+#define ADMIN_TOKEN_END "..."ADMIN_SEPARATOR
+
+/* show information admin command */
+#define ADMIN_COMMAND_SHOW_INFO "show info"
+/* show statistic admin command */
+#define ADMIN_COMMAND_SHOW_STAT "show stat"
+/* show configuration admin command */
+#define ADMIN_COMMAND_SHOW_CONF "show configuration"
+
+
+/*============================================================================*
+ * Interaface decalaration
+ *============================================================================*/
+
+
+/*----------------------------------------------------------------------------*
+ * Tarantool module interface
+ *----------------------------------------------------------------------------*/
+
+/* initialize module function */
+PHP_MINIT_FUNCTION(tarantool);
+
+/* shutdown module function */
+PHP_MSHUTDOWN_FUNCTION(tarantool);
 
-#define TARANTOOL_INSERT  13 
-#define TARANTOOL_SELECT  17 
-#define TARANTOOL_UPDATE  19 
-#define TARANTOOL_DELETE  20 
-#define TARANTOOL_CALL    22
-#define TARANTOOL_PING	  65280
+/* show information about this module */
+PHP_MINFO_FUNCTION(tarantool);
 
-#define TARANTOOL_REQUEST_ID  8 
 
-#define TARANTOOL_OP_ASSIGN 0 
-#define TARANTOOL_OP_ADD	1 
-#define TARANTOOL_OP_AND	2
-#define TARANTOOL_OP_XOR	3
-#define TARANTOOL_OP_OR		4
+/*----------------------------------------------------------------------------*
+ * Tarantool class interface
+ *----------------------------------------------------------------------------*/
 
-#define TARANTOOL_SHOW_INFO "show info\r\n"
-#define TARANTOOL_SHOW_INFO_SIZE sizeof(TARANTOOL_SHOW_INFO) 
+/* class constructor */
+PHP_METHOD(tarantool_class, __construct);
 
-#define TARANTOOL_SHOW_STAT "show stat\r\n"
-#define TARANTOOL_SHOW_STAT_SIZE sizeof(TARANTOOL_SHOW_STAT) 
+/* do select operation */
+PHP_METHOD(tarantool_class, select);
 
-#define TARANTOOL_SHOW_CONF "show configuration\n"
-#define TARANTOOL_SHOW_CONF_SIZE sizeof(TARANTOOL_SHOW_CONF) 
+/* do insert operation */
+PHP_METHOD(tarantool_class, insert);
 
+/* do update fields operation */
+PHP_METHOD(tarantool_class, update_fields);
 
-#ifdef ZTS
-#include "TSRM.h"
-#endif
+/* do delete operation */
+PHP_METHOD(tarantool_class, delete);
 
-PHP_MINIT_FUNCTION(tarantool);
-PHP_MSHUTDOWN_FUNCTION(tarantool);
+/* call lua funtion operation */
+PHP_METHOD(tarantool_class, call);
 
-PHP_MINFO_FUNCTION(tarantool);
+/* do admin command */
+PHP_METHOD(tarantool_class, admin);
 
-PHP_METHOD( tarantool_class, __construct);
-
-PHP_METHOD( tarantool_class, insert);
-PHP_METHOD( tarantool_class, select);
-PHP_METHOD( tarantool_class, mselect);
-PHP_METHOD( tarantool_class, call);
-PHP_METHOD( tarantool_class, getTuple);
-PHP_METHOD( tarantool_class, delete);
-PHP_METHOD( tarantool_class, update);
-PHP_METHOD( tarantool_class, inc);
-PHP_METHOD( tarantool_class, getError);
-PHP_METHOD( tarantool_class, getInfo);
-PHP_METHOD( tarantool_class, getStat);
-PHP_METHOD( tarantool_class, getConf);
 
 #ifdef ZTS
 #define TARANTOOL_G(v) TSRMG(tarantool_globals_id, zend_tarantool_globals *, v)
@@ -96,8 +180,7 @@ PHP_METHOD( tarantool_class, getConf);
 #define TARANTOOL_G(v) (tarantool_globals.v)
 #endif
 
-#endif	
-/* PHP_TARANTOOL_H */
+#endif /* PHP_TARANTOOL_H */
 
 /*
  * Local variables:
diff --git a/connector/php/test/admin.phpt b/connector/php/test/admin.phpt
new file mode 100644
index 0000000000..e13120ddce
--- /dev/null
+++ b/connector/php/test/admin.phpt
@@ -0,0 +1,112 @@
+--TEST--
+Tarantool/box administation commands test
+--FILE--
+<?php
+include "lib/php/tarantool_utest.php";
+
+$tarantool = new Tarantool("localhost", 33013, 33015);
+
+echo "---------- test begin ----------\n";
+echo "help\n";
+echo $tarantool->admin("help");
+echo "----------- test end -----------\n\n";
+
+echo "---------- test begin ----------\n";
+echo "insert\n";
+for ($i = 0; $i < 10; ++$i)
+    echo $tarantool->admin("lua box.insert(0, $i, 'test_id1', 'test field #$i')");
+echo "----------- test end -----------\n\n";
+
+echo "---------- test begin ----------\n";
+echo "select\n";
+echo $tarantool->admin("lua box.select(0, 1, 'test_id1')");
+echo "----------- test end -----------\n\n";
+
+echo "---------- test begin ----------\n";
+echo "myselect\n";
+echo $tarantool->admin("lua myselect(0, 1, 'test_id1')");
+echo "----------- test end -----------\n\n";
+
+echo "---------- test begin ----------\n";
+echo "delete\n";
+for ($i = 0; $i < 10; ++$i)
+    echo $tarantool->admin("lua box.delete(0, $i)");
+echo "----------- test end -----------\n\n";
+?>
+===DONE===
+--EXPECT--
+---------- test begin ----------
+help
+available commands:
+ - help
+ - exit
+ - show info
+ - show fiber
+ - show configuration
+ - show slab
+ - show palloc
+ - show stat
+ - save coredump
+ - save snapshot
+ - lua command
+ - reload configuration
+----------- test end -----------
+
+---------- test begin ----------
+insert
+ - 0: {'test_id1', 'test field #0'}
+ - 1: {'test_id1', 'test field #1'}
+ - 2: {'test_id1', 'test field #2'}
+ - 3: {'test_id1', 'test field #3'}
+ - 4: {'test_id1', 'test field #4'}
+ - 5: {'test_id1', 'test field #5'}
+ - 6: {'test_id1', 'test field #6'}
+ - 7: {'test_id1', 'test field #7'}
+ - 8: {'test_id1', 'test field #8'}
+ - 9: {'test_id1', 'test field #9'}
+----------- test end -----------
+
+---------- test begin ----------
+select
+ - 0: {'test_id1', 'test field #0'}
+ - 1: {'test_id1', 'test field #1'}
+ - 2: {'test_id1', 'test field #2'}
+ - 3: {'test_id1', 'test field #3'}
+ - 4: {'test_id1', 'test field #4'}
+ - 5: {'test_id1', 'test field #5'}
+ - 6: {'test_id1', 'test field #6'}
+ - 7: {'test_id1', 'test field #7'}
+ - 8: {'test_id1', 'test field #8'}
+ - 9: {'test_id1', 'test field #9'}
+----------- test end -----------
+
+---------- test begin ----------
+myselect
+select in space: 0 index: 1 by key test_id1
+ - 0: {'test_id1', 'test field #0'}
+ - 1: {'test_id1', 'test field #1'}
+ - 2: {'test_id1', 'test field #2'}
+ - 3: {'test_id1', 'test field #3'}
+ - 4: {'test_id1', 'test field #4'}
+ - 5: {'test_id1', 'test field #5'}
+ - 6: {'test_id1', 'test field #6'}
+ - 7: {'test_id1', 'test field #7'}
+ - 8: {'test_id1', 'test field #8'}
+ - 9: {'test_id1', 'test field #9'}
+----------- test end -----------
+
+---------- test begin ----------
+delete
+ - 0: {'test_id1', 'test field #0'}
+ - 1: {'test_id1', 'test field #1'}
+ - 2: {'test_id1', 'test field #2'}
+ - 3: {'test_id1', 'test field #3'}
+ - 4: {'test_id1', 'test field #4'}
+ - 5: {'test_id1', 'test field #5'}
+ - 6: {'test_id1', 'test field #6'}
+ - 7: {'test_id1', 'test field #7'}
+ - 8: {'test_id1', 'test field #8'}
+ - 9: {'test_id1', 'test field #9'}
+----------- test end -----------
+
+===DONE===
\ No newline at end of file
diff --git a/connector/php/test/bin/run-test.bash b/connector/php/test/bin/run-test.bash
new file mode 100755
index 0000000000..b7df9a01c1
--- /dev/null
+++ b/connector/php/test/bin/run-test.bash
@@ -0,0 +1,204 @@
+#!/bin/bash
+#==============================================================================#
+# PHP tarantool test suite runner
+#==============================================================================#
+
+#------------------------------------------------------------------------------#
+# Constants
+#------------------------------------------------------------------------------#
+
+# Success constant
+SUCCESS=0
+# Failure constant
+FAILURE=1
+
+# test runner etc directory
+TEST_RUNNER_ETC_DIR="etc"
+# test runner var directory
+TEST_RUNNER_VAR_DIR="var"
+# test runner var directory
+TEST_RUNNER_LIB_DIR="lib"
+
+# php.ini file
+PHP_INI="$TEST_RUNNER_ETC_DIR/php.ini"
+
+# Tarantool/box binary file name
+TARANTOOL_BOX_BIN="tarantool_box"
+# Tarantool/box configuration file
+TARANTOOL_BOX_CFG="$TEST_RUNNER_ETC_DIR/tarantool_box.cfg"
+# Tarantool/box pid file
+TARANTOOL_BOX_PID="$TEST_RUNNER_VAR_DIR/tarantool_box.pid"
+
+
+#------------------------------------------------------------------------------#
+# Suite runner functions
+#------------------------------------------------------------------------------#
+
+# initialize suite
+function init_suite()
+{
+	# check TARANTOOL_HOME variable
+	if [ ! -z $TARANTOOL_HOME ]; then
+		# Use user-defined path
+		tarantool_bin="$TARANTOOL_HOME/$TARANTOOL_BOX_BIN"
+    else
+		# try to find by standard paths
+		tarantool_bin="$TARANTOOL_BOX_BIN"
+	fi
+
+	# check binary
+	if ! which $tarantool_bin > /dev/null 2>&1; then
+		echo "can't found Tarantool/Box binary file"
+		exit $FAILURE
+	fi
+
+	# check pear
+	if ! which pear > /dev/null 2>&1; then
+		echo "can't found pear"
+		exit $FAILURE
+	fi
+
+	# check tarantool module library
+	if [ ! -f ../modules/tarantool.so ]; then
+		echo "can't found tarantool module library"
+		exit $FAILURE
+	fi
+	if [ -f $TEST_RUNNER_LIB_DIR/tarantool.so ]; then
+		rm $TEST_RUNNER_LIB_DIR/tarantool.so
+	fi
+	ln -s ../../modules/tarantool.so $TEST_RUNNER_LIB_DIR
+
+	if [ -f ../$TEST_RUNNER_VAR_DIR/init.lua ]; then
+		rm ../$TEST_RUNNER_VAR_DIR/init.lua
+	fi
+	ln -s ../$TEST_RUNNER_LIB_DIR/lua/test.lua $TEST_RUNNER_VAR_DIR/init.lua
+
+	return $SUCCESS
+}
+
+# initialize tarantool's storage
+function tarantool_init_storage()
+{
+	$tarantool_bin --init-storage -c $TARANTOOL_BOX_CFG 1> /dev/null 2>&1
+	return $SUCCESS
+}
+
+# start tarantool
+function tarantool_start()
+{
+	if [ -f $TARANTOOL_BOX_PID ]; then
+		tarantool_stop
+		tarantool_cleanup
+	fi
+
+	# run tarantool to background
+	$tarantool_bin -c $TARANTOOL_BOX_CFG &
+	# wait pid file
+	for i in {1..500}; do
+		if [ -f $TARANTOOL_BOX_PID ]; then
+			break
+		fi
+		sleep 0.01
+	done
+
+	if [ ! -f $TARANTOOL_BOX_PID ]; then
+		echo "error: can't start tarantool"
+		tarantool_cleanup
+		exit $FAILURE
+	fi
+
+	return $SUCCESS
+}
+
+# stop tarantool
+function tarantool_stop()
+{
+	if [ ! -f $TARANTOOL_BOX_PID ]; then
+		return $SUCCESS
+	fi
+
+	# get tarantool pid form pid file
+	pid=`cat $TARANTOOL_BOX_PID`
+	# kill process via SIGTERM
+	kill -TERM $pid 1> /dev/null 2>&1
+
+	for i in {1..500}; do
+		if [ ! -f $TARANTOOL_BOX_PID ]; then
+			# tarantool successfully stopped
+			return $SUCCESS
+		fi
+		sleep 0.01
+	done
+
+	if [ -f $TARANTOOL_BOX_PID ]; then
+		kill -KILL $pid 1> /dev/null 2>&1
+	fi
+
+	return $SUCCESS
+}
+
+# clean-up tarantool
+function tarantool_cleanup()
+{
+	# delete pid
+	rm -f $TEST_RUNNER_VAR_DIR/*.pid
+	# delete xlogs
+	rm -f $TEST_RUNNER_VAR_DIR/*.xlog
+	# delete snaps
+	rm -f $TEST_RUNNER_VAR_DIR/*.snap
+}
+
+
+#------------------------------------------------------------------------------#
+# run test scrip body
+#------------------------------------------------------------------------------#
+
+#
+# initialize
+#
+
+printf "initialize tarantool ... "
+# initializing suite
+init_suite
+# initializing storage
+tarantool_init_storage
+printf "done\n"
+
+printf "starting tarantool ... "
+# start tarantool
+tarantool_start
+printf "done\n"
+
+
+#
+# run
+#
+
+printf "\n"
+printf "================================= PHP test ===============================\n"
+
+# running pear's regression test scrips
+PHPRC=$PHP_INI pear run-tests $1
+
+printf "==========================================================================\n"
+printf "\n"
+
+#
+# stop & clean-up
+#
+
+printf "stopping tarantool ... "
+# stop tarantool
+tarantool_stop
+# clean-up tarantool
+tarantool_cleanup
+printf "done\n"
+
+#
+# Local variables:
+# tab-width: 4
+# c-basic-offset: 4
+# End:
+# vim600: noet sw=4 ts=4 fdm=marker
+# vim<600: noet sw=4 ts=4
+#
diff --git a/connector/php/test/call.phpt b/connector/php/test/call.phpt
new file mode 100644
index 0000000000..fe85b595f8
--- /dev/null
+++ b/connector/php/test/call.phpt
@@ -0,0 +1,93 @@
+--TEST--
+Tarantool/box call commands test
+--FILE--
+<?php
+include "lib/php/tarantool_utest.php";
+
+$tarantool = new Tarantool("localhost", 33013, 33015);
+test_init($tarantool, 0);
+
+echo "---------- test begin ----------\n";
+echo "test call: myselect by primary index\n";
+test_call($tarantool, "box.select", array(0, 0, 2), 0);
+echo "----------- test end -----------\n\n";
+
+echo "---------- test begin ----------\n";
+echo "test call: function w/o params\n";
+test_call($tarantool, "myfoo", array(), 0);
+echo "----------- test end -----------\n\n";
+
+echo "---------- test begin ----------\n";
+echo "test call: call undefined function (expected error exception)\n";
+test_call($tarantool, "fafagaga", array("fafa-gaga", "foo", "bar"), 0);
+echo "----------- test end -----------\n\n";
+
+test_clean($tarantool, 0);
+?>
+===DONE===
+--EXPECT--
+---------- test begin ----------
+test call: myselect by primary index
+result:
+count = 1
+tuple[0]:
+  id     = 2
+  series = Star Wars
+  year   = 1983
+  name   = Return of the Jedi...
+  crawl  = Luke Skywalker has returned
+to his home planet of
+Tatooine in an attempt
+to rescue his friend
+Han Solo from the
+clutches of the vile
+gangster Jabba the Hutt.
+
+Little does Luke know
+that the GALACTIC EMPIRE
+has secretly begun construction
+on a new armored space station
+even more powerful than the
+first dreaded Death Star.
+
+When completed, this ultimate
+weapon will spell certain
+doom for the small band of
+rebels struggling to restore
+freedom to the galaxy...
+----------- test end -----------
+
+---------- test begin ----------
+test call: function w/o params
+result:
+count = 1
+tuple[0]:
+  id     = 0
+  series = Star Wars
+  year   = 1977 year
+  name   = A New Hope...
+  crawl  = A long time ago, in a galaxy far, far away...
+It is a period of civil war. Rebel
+spaceships, striking from a hidden
+base, have won their first victory
+against the evil Galactic Empire.
+
+During the battle, Rebel spies managed
+to steal secret plans to the Empire's
+ultimate weapon, the Death Star, an
+armored space station with enough
+power to destroy an entire planet.
+
+Pursued by the Empire's sinister agents,
+Princess Leia races home aboard her
+starship, custodian of the stolen plans
+that can save her people and restore
+freedom to the galaxy....
+----------- test end -----------
+
+---------- test begin ----------
+test call: call undefined function (expected error exception)
+catched exception: call failed: 12802
+----------- test end -----------
+
+===DONE===
\ No newline at end of file
diff --git a/connector/php/test/delete.phpt b/connector/php/test/delete.phpt
new file mode 100644
index 0000000000..d19a0aaaef
--- /dev/null
+++ b/connector/php/test/delete.phpt
@@ -0,0 +1,125 @@
+--TEST--
+Tarantool/box delete commands test
+--FILE--
+<?php
+include "lib/php/tarantool_utest.php";
+
+$tarantool = new Tarantool("localhost", 33013, 33015);
+
+test_init($tarantool, 0);
+
+echo "---------- test begin ----------\n";
+echo "test delete: invalid key (expected error exception)\n";
+test_delete($tarantool, 0, $tarantool, 0);
+echo "----------- test end -----------\n\n";
+
+echo "---------- test begin ----------\n";
+echo "test delete: invalid key (expected error exception)\n";
+test_delete($tarantool, 0, array($tarantool), 0);
+echo "----------- test end -----------\n\n";
+
+echo "---------- test begin ----------\n";
+echo "test delete: invalid key (expected error exception)\n";
+test_delete($tarantool, 0, array(1, 2), 0);
+echo "----------- test end -----------\n\n";
+
+echo "---------- test begin ----------\n";
+echo "test delete: delete key as interger\n";
+test_delete($tarantool, 0, 0, TARANTOOL_FLAGS_RETURN_TUPLE);
+echo "----------- test end -----------\n\n";
+
+echo "---------- test begin ----------\n";
+echo "test delete: delete key as array\n";
+test_delete($tarantool, 0, array(1), TARANTOOL_FLAGS_RETURN_TUPLE);
+echo "----------- test end -----------\n\n";
+
+echo "---------- test begin ----------\n";
+echo "test delete: delete key (tuple doesn't return)\n";
+test_delete($tarantool, 0, 2, 0);
+echo "----------- test end -----------\n\n";
+
+test_clean($tarantool, 0);
+?>
+===DONE===
+--EXPECT--
+---------- test begin ----------
+test delete: invalid key (expected error exception)
+catched exception: unsupported tuple type
+----------- test end -----------
+
+---------- test begin ----------
+test delete: invalid key (expected error exception)
+catched exception: unsupported field type
+----------- test end -----------
+
+---------- test begin ----------
+test delete: invalid key (expected error exception)
+catched exception: delete failed: 514
+----------- test end -----------
+
+---------- test begin ----------
+test delete: delete key as interger
+result:
+count = 1
+tuple:
+  id     = 0
+  series = Star Wars
+  year   = 1977
+  name   = A New Hope...
+  crawl  = A long time ago, in a galaxy far, far away...
+It is a period of civil war. Rebel
+spaceships, striking from a hidden
+base, have won their first victory
+against the evil Galactic Empire.
+
+During the battle, Rebel spies managed
+to steal secret plans to the Empire's
+ultimate weapon, the Death Star, an
+armored space station with enough
+power to destroy an entire planet.
+
+Pursued by the Empire's sinister agents,
+Princess Leia races home aboard her
+starship, custodian of the stolen plans
+that can save her people and restore
+freedom to the galaxy....
+----------- test end -----------
+
+---------- test begin ----------
+test delete: delete key as array
+result:
+count = 1
+tuple:
+  id     = 1
+  series = Star Wars
+  year   = 1980
+  name   = The Empire Strikes Back...
+  crawl  = It is a dark time for the
+Rebellion. Although the Death
+Star has been destroyed.
+Imperial troops have driven the
+Rebel forces from their hidden
+base and pursued them across
+the galaxy.
+
+Evading the dreaded Imperial
+Starfleet, a group of freedom
+fighters led by Luke Skywalker
+have established a new secret base
+on the remote ice world
+of Hoth.
+
+The evil lord Darth Vader,
+obsessed with finding young
+Skywalker, has dispatched
+thousands of remote probes
+into the far reaches of space....
+----------- test end -----------
+
+---------- test begin ----------
+test delete: delete key (tuple doesn't return)
+result:
+count = 1
+----------- test end -----------
+
+===DONE===
\ No newline at end of file
diff --git a/connector/php/test/errors.phpt b/connector/php/test/errors.phpt
new file mode 100644
index 0000000000..2450b3efb6
--- /dev/null
+++ b/connector/php/test/errors.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Tarantool/box error commands test
+--FILE--
+<?php
+
+try
+{
+    $tarantool = new Tarantool("localhost", -33013, 0);
+    echo "error: the exception didn't raise\n";
+} catch (Exception $e) {
+    echo "catched exception: ", $e->getMessage(), "\n";
+}
+
+try {
+    $tarantool = new Tarantool("localhost", 33013, 65537);
+    echo "error: the exception didn't raise\n";
+} catch (Exception $e) {
+    echo "catched exception: ", $e->getMessage(), "\n";
+}
+
+?>
+===DONE===
+--EXPECT--
+catched exception: invalid primary port value: -33013
+catched exception: invalid admin port value: 65537
+===DONE===
diff --git a/connector/php/test/etc/php.ini b/connector/php/test/etc/php.ini
new file mode 100644
index 0000000000..ae7b2ee849
--- /dev/null
+++ b/connector/php/test/etc/php.ini
@@ -0,0 +1,1851 @@
+[PHP]
+
+;;;;;;;;;;;;;;;;;;;
+; About php.ini   ;
+;;;;;;;;;;;;;;;;;;;
+; PHP's initialization file, generally called php.ini, is responsible for
+; configuring many of the aspects of PHP's behavior.
+
+; PHP attempts to find and load this configuration from a number of locations.
+; The following is a summary of its search order:
+; 1. SAPI module specific location.
+; 2. The PHPRC environment variable. (As of PHP 5.2.0)
+; 3. A number of predefined registry keys on Windows (As of PHP 5.2.0)
+; 4. Current working directory (except CLI)
+; 5. The web server's directory (for SAPI modules), or directory of PHP
+; (otherwise in Windows)
+; 6. The directory from the --with-config-file-path compile time option, or the
+; Windows directory (C:\windows or C:\winnt)
+; See the PHP docs for more specific information.
+; http://php.net/configuration.file
+
+; The syntax of the file is extremely simple.  Whitespace and Lines
+; beginning with a semicolon are silently ignored (as you probably guessed).
+; Section headers (e.g. [Foo]) are also silently ignored, even though
+; they might mean something in the future.
+
+; Directives following the section heading [PATH=/www/mysite] only
+; apply to PHP files in the /www/mysite directory.  Directives
+; following the section heading [HOST=www.example.com] only apply to
+; PHP files served from www.example.com.  Directives set in these
+; special sections cannot be overridden by user-defined INI files or
+; at runtime. Currently, [PATH=] and [HOST=] sections only work under
+; CGI/FastCGI.
+; http://php.net/ini.sections
+
+; Directives are specified using the following syntax:
+; directive = value
+; Directive names are *case sensitive* - foo=bar is different from FOO=bar.
+; Directives are variables used to configure PHP or PHP extensions.
+; There is no name validation.  If PHP can't find an expected
+; directive because it is not set or is mistyped, a default value will be used.
+
+; The value can be a string, a number, a PHP constant (e.g. E_ALL or M_PI), one
+; of the INI constants (On, Off, True, False, Yes, No and None) or an expression
+; (e.g. E_ALL & ~E_NOTICE), a quoted string ("bar"), or a reference to a
+; previously set variable or directive (e.g. ${foo})
+
+; Expressions in the INI file are limited to bitwise operators and parentheses:
+; |  bitwise OR
+; ^  bitwise XOR
+; &  bitwise AND
+; ~  bitwise NOT
+; !  boolean NOT
+
+; Boolean flags can be turned on using the values 1, On, True or Yes.
+; They can be turned off using the values 0, Off, False or No.
+
+; An empty string can be denoted by simply not writing anything after the equal
+; sign, or by using the None keyword:
+
+;  foo =         ; sets foo to an empty string
+;  foo = None    ; sets foo to an empty string
+;  foo = "None"  ; sets foo to the string 'None'
+
+; If you use constants in your value, and these constants belong to a
+; dynamically loaded extension (either a PHP extension or a Zend extension),
+; you may only use these constants *after* the line that loads the extension.
+
+;;;;;;;;;;;;;;;;;;;
+; About this file ;
+;;;;;;;;;;;;;;;;;;;
+; PHP comes packaged with two INI files. One that is recommended to be used
+; in production environments and one that is recommended to be used in
+; development environments.
+
+; php.ini-production contains settings which hold security, performance and
+; best practices at its core. But please be aware, these settings may break
+; compatibility with older or less security conscience applications. We
+; recommending using the production ini in production and testing environments.
+
+; php.ini-development is very similar to its production variant, except it's
+; much more verbose when it comes to errors. We recommending using the
+; development version only in development environments as errors shown to
+; application users can inadvertently leak otherwise secure information.
+
+;;;;;;;;;;;;;;;;;;;
+; Quick Reference ;
+;;;;;;;;;;;;;;;;;;;
+; The following are all the settings which are different in either the production
+; or development versions of the INIs with respect to PHP's default behavior.
+; Please see the actual settings later in the document for more details as to why
+; we recommend these changes in PHP's behavior.
+
+; allow_call_time_pass_reference
+;   Default Value: On
+;   Development Value: Off
+;   Production Value: Off
+
+; display_errors
+;   Default Value: On
+;   Development Value: On
+;   Production Value: Off
+
+; display_startup_errors
+;   Default Value: Off
+;   Development Value: On
+;   Production Value: Off
+
+; error_reporting
+;   Default Value: E_ALL & ~E_NOTICE
+;   Development Value: E_ALL | E_STRICT
+;   Production Value: E_ALL & ~E_DEPRECATED
+
+; html_errors
+;   Default Value: On
+;   Development Value: On
+;   Production value: Off
+
+; log_errors
+;   Default Value: Off
+;   Development Value: On
+;   Production Value: On
+
+; magic_quotes_gpc
+;   Default Value: On
+;   Development Value: Off
+;   Production Value: Off
+
+; max_input_time
+;   Default Value: -1 (Unlimited)
+;   Development Value: 60 (60 seconds)
+;   Production Value: 60 (60 seconds)
+
+; output_buffering
+;   Default Value: Off
+;   Development Value: 4096
+;   Production Value: 4096
+
+; register_argc_argv
+;   Default Value: On
+;   Development Value: Off
+;   Production Value: Off
+
+; register_long_arrays
+;   Default Value: On
+;   Development Value: Off
+;   Production Value: Off
+
+; request_order
+;   Default Value: None
+;   Development Value: "GP"
+;   Production Value: "GP"
+
+; session.bug_compat_42
+;   Default Value: On
+;   Development Value: On
+;   Production Value: Off
+
+; session.bug_compat_warn
+;   Default Value: On
+;   Development Value: On
+;   Production Value: Off
+
+; session.gc_divisor
+;   Default Value: 100
+;   Development Value: 1000
+;   Production Value: 1000
+
+; session.hash_bits_per_character
+;   Default Value: 4
+;   Development Value: 5
+;   Production Value: 5
+
+; short_open_tag
+;   Default Value: On
+;   Development Value: Off
+;   Production Value: Off
+
+; track_errors
+;   Default Value: Off
+;   Development Value: On
+;   Production Value: Off
+
+; url_rewriter.tags
+;   Default Value: "a=href,area=href,frame=src,form=,fieldset="
+;   Development Value: "a=href,area=href,frame=src,input=src,form=fakeentry"
+;   Production Value: "a=href,area=href,frame=src,input=src,form=fakeentry"
+
+; variables_order
+;   Default Value: "EGPCS"
+;   Development Value: "GPCS"
+;   Production Value: "GPCS"
+
+;;;;;;;;;;;;;;;;;;;;
+; php.ini Options  ;
+;;;;;;;;;;;;;;;;;;;;
+; Name for user-defined php.ini (.htaccess) files. Default is ".user.ini"
+;user_ini.filename = ".user.ini"
+
+; To disable this feature set this option to empty value
+;user_ini.filename =
+
+; TTL for user-defined php.ini files (time-to-live) in seconds. Default is 300 seconds (5 minutes)
+;user_ini.cache_ttl = 300
+
+;;;;;;;;;;;;;;;;;;;;
+; Language Options ;
+;;;;;;;;;;;;;;;;;;;;
+
+; Enable the PHP scripting language engine under Apache.
+; http://php.net/engine
+engine = On
+
+; This directive determines whether or not PHP will recognize code between
+; <? and ?> tags as PHP source which should be processed as such. It's been
+; recommended for several years that you not use the short tag "short cut" and
+; instead to use the full <?php and ?> tag combination. With the wide spread use
+; of XML and use of these tags by other languages, the server can become easily
+; confused and end up parsing the wrong code in the wrong context. But because
+; this short cut has been a feature for such a long time, it's currently still
+; supported for backwards compatibility, but we recommend you don't use them.
+; Default Value: On
+; Development Value: Off
+; Production Value: Off
+; http://php.net/short-open-tag
+short_open_tag = On
+
+; Allow ASP-style <% %> tags.
+; http://php.net/asp-tags
+asp_tags = Off
+
+; The number of significant digits displayed in floating point numbers.
+; http://php.net/precision
+precision = 14
+
+; Enforce year 2000 compliance (will cause problems with non-compliant browsers)
+; http://php.net/y2k-compliance
+y2k_compliance = On
+
+; Output buffering is a mechanism for controlling how much output data
+; (excluding headers and cookies) PHP should keep internally before pushing that
+; data to the client. If your application's output exceeds this setting, PHP
+; will send that data in chunks of roughly the size you specify.
+; Turning on this setting and managing its maximum buffer size can yield some
+; interesting side-effects depending on your application and web server.
+; You may be able to send headers and cookies after you've already sent output
+; through print or echo. You also may see performance benefits if your server is
+; emitting less packets due to buffered output versus PHP streaming the output
+; as it gets it. On production servers, 4096 bytes is a good setting for performance
+; reasons.
+; Note: Output buffering can also be controlled via Output Buffering Control
+;   functions.
+; Possible Values:
+;   On = Enabled and buffer is unlimited. (Use with caution)
+;   Off = Disabled
+;   Integer = Enables the buffer and sets its maximum size in bytes.
+; Note: This directive is hardcoded to Off for the CLI SAPI
+; Default Value: Off
+; Development Value: 4096
+; Production Value: 4096
+; http://php.net/output-buffering
+output_buffering = 4096
+
+; You can redirect all of the output of your scripts to a function.  For
+; example, if you set output_handler to "mb_output_handler", character
+; encoding will be transparently converted to the specified encoding.
+; Setting any output handler automatically turns on output buffering.
+; Note: People who wrote portable scripts should not depend on this ini
+;   directive. Instead, explicitly set the output handler using ob_start().
+;   Using this ini directive may cause problems unless you know what script
+;   is doing.
+; Note: You cannot use both "mb_output_handler" with "ob_iconv_handler"
+;   and you cannot use both "ob_gzhandler" and "zlib.output_compression".
+; Note: output_handler must be empty if this is set 'On' !!!!
+;   Instead you must use zlib.output_handler.
+; http://php.net/output-handler
+;output_handler =
+
+; Transparent output compression using the zlib library
+; Valid values for this option are 'off', 'on', or a specific buffer size
+; to be used for compression (default is 4KB)
+; Note: Resulting chunk size may vary due to nature of compression. PHP
+;   outputs chunks that are few hundreds bytes each as a result of
+;   compression. If you prefer a larger chunk size for better
+;   performance, enable output_buffering in addition.
+; Note: You need to use zlib.output_handler instead of the standard
+;   output_handler, or otherwise the output will be corrupted.
+; http://php.net/zlib.output-compression
+zlib.output_compression = Off
+
+; http://php.net/zlib.output-compression-level
+;zlib.output_compression_level = -1
+
+; You cannot specify additional output handlers if zlib.output_compression
+; is activated here. This setting does the same as output_handler but in
+; a different order.
+; http://php.net/zlib.output-handler
+;zlib.output_handler =
+
+; Implicit flush tells PHP to tell the output layer to flush itself
+; automatically after every output block.  This is equivalent to calling the
+; PHP function flush() after each and every call to print() or echo() and each
+; and every HTML block.  Turning this option on has serious performance
+; implications and is generally recommended for debugging purposes only.
+; http://php.net/implicit-flush
+; Note: This directive is hardcoded to On for the CLI SAPI
+implicit_flush = Off
+
+; The unserialize callback function will be called (with the undefined class'
+; name as parameter), if the unserializer finds an undefined class
+; which should be instantiated. A warning appears if the specified function is
+; not defined, or if the function doesn't include/implement the missing class.
+; So only set this entry, if you really want to implement such a
+; callback-function.
+unserialize_callback_func =
+
+; When floats & doubles are serialized store serialize_precision significant
+; digits after the floating point. The default value ensures that when floats
+; are decoded with unserialize, the data will remain the same.
+serialize_precision = 17
+
+; This directive allows you to enable and disable warnings which PHP will issue
+; if you pass a value by reference at function call time. Passing values by
+; reference at function call time is a deprecated feature which will be removed
+; from PHP at some point in the near future. The acceptable method for passing a
+; value by reference to a function is by declaring the reference in the functions
+; definition, not at call time. This directive does not disable this feature, it
+; only determines whether PHP will warn you about it or not. These warnings
+; should enabled in development environments only.
+; Default Value: On (Suppress warnings)
+; Development Value: Off (Issue warnings)
+; Production Value: Off (Issue warnings)
+; http://php.net/allow-call-time-pass-reference
+allow_call_time_pass_reference = Off
+
+; Safe Mode
+; http://php.net/safe-mode
+safe_mode = Off
+
+; By default, Safe Mode does a UID compare check when
+; opening files. If you want to relax this to a GID compare,
+; then turn on safe_mode_gid.
+; http://php.net/safe-mode-gid
+safe_mode_gid = Off
+
+; When safe_mode is on, UID/GID checks are bypassed when
+; including files from this directory and its subdirectories.
+; (directory must also be in include_path or full path must
+; be used when including)
+; http://php.net/safe-mode-include-dir
+safe_mode_include_dir =
+
+; When safe_mode is on, only executables located in the safe_mode_exec_dir
+; will be allowed to be executed via the exec family of functions.
+; http://php.net/safe-mode-exec-dir
+safe_mode_exec_dir =
+
+; Setting certain environment variables may be a potential security breach.
+; This directive contains a comma-delimited list of prefixes.  In Safe Mode,
+; the user may only alter environment variables whose names begin with the
+; prefixes supplied here.  By default, users will only be able to set
+; environment variables that begin with PHP_ (e.g. PHP_FOO=BAR).
+; Note:  If this directive is empty, PHP will let the user modify ANY
+;   environment variable!
+; http://php.net/safe-mode-allowed-env-vars
+safe_mode_allowed_env_vars = PHP_
+
+; This directive contains a comma-delimited list of environment variables that
+; the end user won't be able to change using putenv().  These variables will be
+; protected even if safe_mode_allowed_env_vars is set to allow to change them.
+; http://php.net/safe-mode-protected-env-vars
+safe_mode_protected_env_vars = LD_LIBRARY_PATH
+
+; open_basedir, if set, limits all file operations to the defined directory
+; and below.  This directive makes most sense if used in a per-directory
+; or per-virtualhost web server configuration file. This directive is
+; *NOT* affected by whether Safe Mode is turned On or Off.
+; http://php.net/open-basedir
+;open_basedir =
+
+; This directive allows you to disable certain functions for security reasons.
+; It receives a comma-delimited list of function names. This directive is
+; *NOT* affected by whether Safe Mode is turned On or Off.
+; http://php.net/disable-functions
+disable_functions =
+
+; This directive allows you to disable certain classes for security reasons.
+; It receives a comma-delimited list of class names. This directive is
+; *NOT* affected by whether Safe Mode is turned On or Off.
+; http://php.net/disable-classes
+disable_classes =
+
+; Colors for Syntax Highlighting mode.  Anything that's acceptable in
+; <span style="color: ???????"> would work.
+; http://php.net/syntax-highlighting
+;highlight.string  = #DD0000
+;highlight.comment = #FF9900
+;highlight.keyword = #007700
+;highlight.bg      = #FFFFFF
+;highlight.default = #0000BB
+;highlight.html    = #000000
+
+; If enabled, the request will be allowed to complete even if the user aborts
+; the request. Consider enabling it if executing long requests, which may end up
+; being interrupted by the user or a browser timing out. PHP's default behavior
+; is to disable this feature.
+; http://php.net/ignore-user-abort
+;ignore_user_abort = On
+
+; Determines the size of the realpath cache to be used by PHP. This value should
+; be increased on systems where PHP opens many files to reflect the quantity of
+; the file operations performed.
+; http://php.net/realpath-cache-size
+;realpath_cache_size = 16k
+
+; Duration of time, in seconds for which to cache realpath information for a given
+; file or directory. For systems with rarely changing files, consider increasing this
+; value.
+; http://php.net/realpath-cache-ttl
+;realpath_cache_ttl = 120
+
+;;;;;;;;;;;;;;;;;
+; Miscellaneous ;
+;;;;;;;;;;;;;;;;;
+
+; Decides whether PHP may expose the fact that it is installed on the server
+; (e.g. by adding its signature to the Web server header).  It is no security
+; threat in any way, but it makes it possible to determine whether you use PHP
+; on your server or not.
+; http://php.net/expose-php
+expose_php = On
+
+;;;;;;;;;;;;;;;;;;;
+; Resource Limits ;
+;;;;;;;;;;;;;;;;;;;
+
+; Maximum execution time of each script, in seconds
+; http://php.net/max-execution-time
+; Note: This directive is hardcoded to 0 for the CLI SAPI
+max_execution_time = 30
+
+; Maximum amount of time each script may spend parsing request data. It's a good
+; idea to limit this time on productions servers in order to eliminate unexpectedly
+; long running scripts.
+; Note: This directive is hardcoded to -1 for the CLI SAPI
+; Default Value: -1 (Unlimited)
+; Development Value: 60 (60 seconds)
+; Production Value: 60 (60 seconds)
+; http://php.net/max-input-time
+max_input_time = 60
+
+; Maximum input variable nesting level
+; http://php.net/max-input-nesting-level
+;max_input_nesting_level = 64
+
+; Maximum amount of memory a script may consume (128MB)
+; http://php.net/memory-limit
+memory_limit = -1
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Error handling and logging ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; This directive informs PHP of which errors, warnings and notices you would like
+; it to take action for. The recommended way of setting values for this
+; directive is through the use of the error level constants and bitwise
+; operators. The error level constants are below here for convenience as well as
+; some common settings and their meanings.
+; By default, PHP is set to take action on all errors, notices and warnings EXCEPT
+; those related to E_NOTICE and E_STRICT, which together cover best practices and
+; recommended coding standards in PHP. For performance reasons, this is the
+; recommend error reporting setting. Your production server shouldn't be wasting
+; resources complaining about best practices and coding standards. That's what
+; development servers and development settings are for.
+; Note: The php.ini-development file has this setting as E_ALL | E_STRICT. This
+; means it pretty much reports everything which is exactly what you want during
+; development and early testing.
+;
+; Error Level Constants:
+; E_ALL             - All errors and warnings (includes E_STRICT as of PHP 6.0.0)
+; E_ERROR           - fatal run-time errors
+; E_RECOVERABLE_ERROR  - almost fatal run-time errors
+; E_WARNING         - run-time warnings (non-fatal errors)
+; E_PARSE           - compile-time parse errors
+; E_NOTICE          - run-time notices (these are warnings which often result
+;                     from a bug in your code, but it's possible that it was
+;                     intentional (e.g., using an uninitialized variable and
+;                     relying on the fact it's automatically initialized to an
+;                     empty string)
+; E_STRICT          - run-time notices, enable to have PHP suggest changes
+;                     to your code which will ensure the best interoperability
+;                     and forward compatibility of your code
+; E_CORE_ERROR      - fatal errors that occur during PHP's initial startup
+; E_CORE_WARNING    - warnings (non-fatal errors) that occur during PHP's
+;                     initial startup
+; E_COMPILE_ERROR   - fatal compile-time errors
+; E_COMPILE_WARNING - compile-time warnings (non-fatal errors)
+; E_USER_ERROR      - user-generated error message
+; E_USER_WARNING    - user-generated warning message
+; E_USER_NOTICE     - user-generated notice message
+; E_DEPRECATED      - warn about code that will not work in future versions
+;                     of PHP
+; E_USER_DEPRECATED - user-generated deprecation warnings
+;
+; Common Values:
+;   E_ALL & ~E_NOTICE  (Show all errors, except for notices and coding standards warnings.)
+;   E_ALL & ~E_NOTICE | E_STRICT  (Show all errors, except for notices)
+;   E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ERROR|E_CORE_ERROR  (Show only errors)
+;   E_ALL | E_STRICT  (Show all errors, warnings and notices including coding standards.)
+; Default Value: E_ALL & ~E_NOTICE
+; Development Value: E_ALL | E_STRICT
+; Production Value: E_ALL & ~E_DEPRECATED
+; http://php.net/error-reporting
+error_reporting = E_ALL & ~E_DEPRECATED
+
+; This directive controls whether or not and where PHP will output errors,
+; notices and warnings too. Error output is very useful during development, but
+; it could be very dangerous in production environments. Depending on the code
+; which is triggering the error, sensitive information could potentially leak
+; out of your application such as database usernames and passwords or worse.
+; It's recommended that errors be logged on production servers rather than
+; having the errors sent to STDOUT.
+; Possible Values:
+;   Off = Do not display any errors
+;   stderr = Display errors to STDERR (affects only CGI/CLI binaries!)
+;   On or stdout = Display errors to STDOUT
+; Default Value: On
+; Development Value: On
+; Production Value: Off
+; http://php.net/display-errors
+display_errors = Off
+
+; The display of errors which occur during PHP's startup sequence are handled
+; separately from display_errors. PHP's default behavior is to suppress those
+; errors from clients. Turning the display of startup errors on can be useful in
+; debugging configuration problems. But, it's strongly recommended that you
+; leave this setting off on production servers.
+; Default Value: Off
+; Development Value: On
+; Production Value: Off
+; http://php.net/display-startup-errors
+display_startup_errors = Off
+
+; Besides displaying errors, PHP can also log errors to locations such as a
+; server-specific log, STDERR, or a location specified by the error_log
+; directive found below. While errors should not be displayed on productions
+; servers they should still be monitored and logging is a great way to do that.
+; Default Value: Off
+; Development Value: On
+; Production Value: On
+; http://php.net/log-errors
+log_errors = On
+
+; Set maximum length of log_errors. In error_log information about the source is
+; added. The default is 1024 and 0 allows to not apply any maximum length at all.
+; http://php.net/log-errors-max-len
+log_errors_max_len = 1024
+
+; Do not log repeated messages. Repeated errors must occur in same file on same
+; line unless ignore_repeated_source is set true.
+; http://php.net/ignore-repeated-errors
+ignore_repeated_errors = Off
+
+; Ignore source of message when ignoring repeated messages. When this setting
+; is On you will not log errors with repeated messages from different files or
+; source lines.
+; http://php.net/ignore-repeated-source
+ignore_repeated_source = Off
+
+; If this parameter is set to Off, then memory leaks will not be shown (on
+; stdout or in the log). This has only effect in a debug compile, and if
+; error reporting includes E_WARNING in the allowed list
+; http://php.net/report-memleaks
+report_memleaks = On
+
+; This setting is on by default.
+;report_zend_debug = 0
+
+; Store the last error/warning message in $php_errormsg (boolean). Setting this value
+; to On can assist in debugging and is appropriate for development servers. It should
+; however be disabled on production servers.
+; Default Value: Off
+; Development Value: On
+; Production Value: Off
+; http://php.net/track-errors
+track_errors = Off
+
+; Turn off normal error reporting and emit XML-RPC error XML
+; http://php.net/xmlrpc-errors
+;xmlrpc_errors = 0
+
+; An XML-RPC faultCode
+;xmlrpc_error_number = 0
+
+; When PHP displays or logs an error, it has the capability of inserting html
+; links to documentation related to that error. This directive controls whether
+; those HTML links appear in error messages or not. For performance and security
+; reasons, it's recommended you disable this on production servers.
+; Note: This directive is hardcoded to Off for the CLI SAPI
+; Default Value: On
+; Development Value: On
+; Production value: Off
+; http://php.net/html-errors
+html_errors = Off
+
+; If html_errors is set On PHP produces clickable error messages that direct
+; to a page describing the error or function causing the error in detail.
+; You can download a copy of the PHP manual from http://php.net/docs
+; and change docref_root to the base URL of your local copy including the
+; leading '/'. You must also specify the file extension being used including
+; the dot. PHP's default behavior is to leave these settings empty.
+; Note: Never use this feature for production boxes.
+; http://php.net/docref-root
+; Examples
+;docref_root = "/phpmanual/"
+
+; http://php.net/docref-ext
+;docref_ext = .html
+
+; String to output before an error message. PHP's default behavior is to leave
+; this setting blank.
+; http://php.net/error-prepend-string
+; Example:
+;error_prepend_string = "<span style='color: #ff0000'>"
+
+; String to output after an error message. PHP's default behavior is to leave
+; this setting blank.
+; http://php.net/error-append-string
+; Example:
+;error_append_string = "</span>"
+
+; Log errors to specified file. PHP's default behavior is to leave this value
+; empty.
+; http://php.net/error-log
+; Example:
+;error_log = php_errors.log
+; Log errors to syslog (Event Log on NT, not valid in Windows 95).
+;error_log = syslog
+
+;;;;;;;;;;;;;;;;;
+; Data Handling ;
+;;;;;;;;;;;;;;;;;
+
+; The separator used in PHP generated URLs to separate arguments.
+; PHP's default setting is "&".
+; http://php.net/arg-separator.output
+; Example:
+;arg_separator.output = "&amp;"
+
+; List of separator(s) used by PHP to parse input URLs into variables.
+; PHP's default setting is "&".
+; NOTE: Every character in this directive is considered as separator!
+; http://php.net/arg-separator.input
+; Example:
+;arg_separator.input = ";&"
+
+; This directive determines which super global arrays are registered when PHP
+; starts up. If the register_globals directive is enabled, it also determines
+; what order variables are populated into the global space. G,P,C,E & S are
+; abbreviations for the following respective super globals: GET, POST, COOKIE,
+; ENV and SERVER. There is a performance penalty paid for the registration of
+; these arrays and because ENV is not as commonly used as the others, ENV is
+; is not recommended on productions servers. You can still get access to
+; the environment variables through getenv() should you need to.
+; Default Value: "EGPCS"
+; Development Value: "GPCS"
+; Production Value: "GPCS";
+; http://php.net/variables-order
+variables_order = "GPCS"
+
+; This directive determines which super global data (G,P,C,E & S) should
+; be registered into the super global array REQUEST. If so, it also determines
+; the order in which that data is registered. The values for this directive are
+; specified in the same manner as the variables_order directive, EXCEPT one.
+; Leaving this value empty will cause PHP to use the value set in the
+; variables_order directive. It does not mean it will leave the super globals
+; array REQUEST empty.
+; Default Value: None
+; Development Value: "GP"
+; Production Value: "GP"
+; http://php.net/request-order
+request_order = "GP"
+
+; Whether or not to register the EGPCS variables as global variables.  You may
+; want to turn this off if you don't want to clutter your scripts' global scope
+; with user data.
+; You should do your best to write your scripts so that they do not require
+; register_globals to be on;  Using form variables as globals can easily lead
+; to possible security problems, if the code is not very well thought of.
+; http://php.net/register-globals
+register_globals = Off
+
+; Determines whether the deprecated long $HTTP_*_VARS type predefined variables
+; are registered by PHP or not. As they are deprecated, we obviously don't
+; recommend you use them. They are on by default for compatibility reasons but
+; they are not recommended on production servers.
+; Default Value: On
+; Development Value: Off
+; Production Value: Off
+; http://php.net/register-long-arrays
+register_long_arrays = Off
+
+; This directive determines whether PHP registers $argv & $argc each time it
+; runs. $argv contains an array of all the arguments passed to PHP when a script
+; is invoked. $argc contains an integer representing the number of arguments
+; that were passed when the script was invoked. These arrays are extremely
+; useful when running scripts from the command line. When this directive is
+; enabled, registering these variables consumes CPU cycles and memory each time
+; a script is executed. For performance reasons, this feature should be disabled
+; on production servers.
+; Note: This directive is hardcoded to On for the CLI SAPI
+; Default Value: On
+; Development Value: Off
+; Production Value: Off
+; http://php.net/register-argc-argv
+register_argc_argv = Off
+
+; When enabled, the SERVER and ENV variables are created when they're first
+; used (Just In Time) instead of when the script starts. If these variables
+; are not used within a script, having this directive on will result in a
+; performance gain. The PHP directives register_globals, register_long_arrays,
+; and register_argc_argv must be disabled for this directive to have any affect.
+; http://php.net/auto-globals-jit
+auto_globals_jit = On
+
+; Maximum size of POST data that PHP will accept.
+; http://php.net/post-max-size
+post_max_size = 8M
+
+; Magic quotes are a preprocessing feature of PHP where PHP will attempt to
+; escape any character sequences in GET, POST, COOKIE and ENV data which might
+; otherwise corrupt data being placed in resources such as databases before
+; making that data available to you. Because of character encoding issues and
+; non-standard SQL implementations across many databases, it's not currently
+; possible for this feature to be 100% accurate. PHP's default behavior is to
+; enable the feature. We strongly recommend you use the escaping mechanisms
+; designed specifically for the database your using instead of relying on this
+; feature. Also note, this feature has been deprecated as of PHP 5.3.0 and is
+; scheduled for removal in PHP 6.
+; Default Value: On
+; Development Value: Off
+; Production Value: Off
+; http://php.net/magic-quotes-gpc
+magic_quotes_gpc = Off
+
+; Magic quotes for runtime-generated data, e.g. data from SQL, from exec(), etc.
+; http://php.net/magic-quotes-runtime
+magic_quotes_runtime = Off
+
+; Use Sybase-style magic quotes (escape ' with '' instead of \').
+; http://php.net/magic-quotes-sybase
+magic_quotes_sybase = Off
+
+; Automatically add files before PHP document.
+; http://php.net/auto-prepend-file
+auto_prepend_file =
+
+; Automatically add files after PHP document.
+; http://php.net/auto-append-file
+auto_append_file =
+
+; By default, PHP will output a character encoding using
+; the Content-type: header.  To disable sending of the charset, simply
+; set it to be empty.
+;
+; PHP's built-in default is text/html
+; http://php.net/default-mimetype
+default_mimetype = "text/html"
+
+; PHP's default character set is set to empty.
+; http://php.net/default-charset
+;default_charset = "iso-8859-1"
+
+; Always populate the $HTTP_RAW_POST_DATA variable. PHP's default behavior is
+; to disable this feature.
+; http://php.net/always-populate-raw-post-data
+;always_populate_raw_post_data = On
+
+;;;;;;;;;;;;;;;;;;;;;;;;;
+; Paths and Directories ;
+;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; UNIX: "/path1:/path2"
+;include_path = ".:/usr/share/php"
+;
+; Windows: "\path1;\path2"
+;include_path = ".;c:\php\includes"
+;
+; PHP's default setting for include_path is ".;/path/to/php/pear"
+; http://php.net/include-path
+
+; The root of the PHP pages, used only if nonempty.
+; if PHP was not compiled with FORCE_REDIRECT, you SHOULD set doc_root
+; if you are running php as a CGI under any web server (other than IIS)
+; see documentation for security issues.  The alternate is to use the
+; cgi.force_redirect configuration below
+; http://php.net/doc-root
+doc_root =
+
+; The directory under which PHP opens the script using /~username used only
+; if nonempty.
+; http://php.net/user-dir
+user_dir =
+
+; Directory in which the loadable extensions (modules) reside.
+; http://php.net/extension-dir
+; extension_dir = "lib/"
+
+; Whether or not to enable the dl() function.  The dl() function does NOT work
+; properly in multithreaded servers, such as IIS or Zeus, and is automatically
+; disabled on them.
+; http://php.net/enable-dl
+enable_dl = Off
+
+; cgi.force_redirect is necessary to provide security running PHP as a CGI under
+; most web servers.  Left undefined, PHP turns this on by default.  You can
+; turn it off here AT YOUR OWN RISK
+; **You CAN safely turn this off for IIS, in fact, you MUST.**
+; http://php.net/cgi.force-redirect
+;cgi.force_redirect = 1
+
+; if cgi.nph is enabled it will force cgi to always sent Status: 200 with
+; every request. PHP's default behavior is to disable this feature.
+;cgi.nph = 1
+
+; if cgi.force_redirect is turned on, and you are not running under Apache or Netscape
+; (iPlanet) web servers, you MAY need to set an environment variable name that PHP
+; will look for to know it is OK to continue execution.  Setting this variable MAY
+; cause security issues, KNOW WHAT YOU ARE DOING FIRST.
+; http://php.net/cgi.redirect-status-env
+;cgi.redirect_status_env = ;
+
+; cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI.  PHP's
+; previous behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok
+; what PATH_INFO is.  For more information on PATH_INFO, see the cgi specs.  Setting
+; this to 1 will cause PHP CGI to fix its paths to conform to the spec.  A setting
+; of zero causes PHP to behave as before.  Default is 1.  You should fix your scripts
+; to use SCRIPT_FILENAME rather than PATH_TRANSLATED.
+; http://php.net/cgi.fix-pathinfo
+;cgi.fix_pathinfo=1
+
+; FastCGI under IIS (on WINNT based OS) supports the ability to impersonate
+; security tokens of the calling client.  This allows IIS to define the
+; security context that the request runs under.  mod_fastcgi under Apache
+; does not currently support this feature (03/17/2002)
+; Set to 1 if running under IIS.  Default is zero.
+; http://php.net/fastcgi.impersonate
+;fastcgi.impersonate = 1;
+
+; Disable logging through FastCGI connection. PHP's default behavior is to enable
+; this feature.
+;fastcgi.logging = 0
+
+; cgi.rfc2616_headers configuration option tells PHP what type of headers to
+; use when sending HTTP response code. If it's set 0 PHP sends Status: header that
+; is supported by Apache. When this option is set to 1 PHP will send
+; RFC2616 compliant header.
+; Default is zero.
+; http://php.net/cgi.rfc2616-headers
+;cgi.rfc2616_headers = 0
+
+;;;;;;;;;;;;;;;;
+; File Uploads ;
+;;;;;;;;;;;;;;;;
+
+; Whether to allow HTTP file uploads.
+; http://php.net/file-uploads
+file_uploads = On
+
+; Temporary directory for HTTP uploaded files (will use system default if not
+; specified).
+; http://php.net/upload-tmp-dir
+;upload_tmp_dir =
+
+; Maximum allowed size for uploaded files.
+; http://php.net/upload-max-filesize
+upload_max_filesize = 2M
+
+; Maximum number of files that can be uploaded via a single request
+max_file_uploads = 20
+
+;;;;;;;;;;;;;;;;;;
+; Fopen wrappers ;
+;;;;;;;;;;;;;;;;;;
+
+; Whether to allow the treatment of URLs (like http:// or ftp://) as files.
+; http://php.net/allow-url-fopen
+allow_url_fopen = On
+
+; Whether to allow include/require to open URLs (like http:// or ftp://) as files.
+; http://php.net/allow-url-include
+allow_url_include = Off
+
+; Define the anonymous ftp password (your email address). PHP's default setting
+; for this is empty.
+; http://php.net/from
+;from="john@doe.com"
+
+; Define the User-Agent string. PHP's default setting for this is empty.
+; http://php.net/user-agent
+;user_agent="PHP"
+
+; Default timeout for socket based streams (seconds)
+; http://php.net/default-socket-timeout
+default_socket_timeout = 60
+
+; If your scripts have to deal with files from Macintosh systems,
+; or you are running on a Mac and need to deal with files from
+; unix or win32 systems, setting this flag will cause PHP to
+; automatically detect the EOL character in those files so that
+; fgets() and file() will work regardless of the source of the file.
+; http://php.net/auto-detect-line-endings
+;auto_detect_line_endings = Off
+
+;;;;;;;;;;;;;;;;;;;;;;
+; Dynamic Extensions ;
+;;;;;;;;;;;;;;;;;;;;;;
+
+extension=./lib/tarantool.so
+; If you wish to have an extension loaded automatically, use the following
+; syntax:
+;
+;   extension=modulename.extension
+;
+; For example, on Windows:
+;
+;   extension=msql.dll
+;
+; ... or under UNIX:
+;
+;   extension=msql.so
+;
+; ... or with a path:
+;
+;   extension=/path/to/extension/msql.so
+;
+; If you only provide the name of the extension, PHP will look for it in its
+; default extension directory.
+
+;;;;;;;;;;;;;;;;;;;
+; Module Settings ;
+;;;;;;;;;;;;;;;;;;;
+
+[Date]
+; Defines the default timezone used by the date functions
+; http://php.net/date.timezone
+;date.timezone =
+
+; http://php.net/date.default-latitude
+;date.default_latitude = 31.7667
+
+; http://php.net/date.default-longitude
+;date.default_longitude = 35.2333
+
+; http://php.net/date.sunrise-zenith
+;date.sunrise_zenith = 90.583333
+
+; http://php.net/date.sunset-zenith
+;date.sunset_zenith = 90.583333
+
+[filter]
+; http://php.net/filter.default
+;filter.default = unsafe_raw
+
+; http://php.net/filter.default-flags
+;filter.default_flags =
+
+[iconv]
+;iconv.input_encoding = ISO-8859-1
+;iconv.internal_encoding = ISO-8859-1
+;iconv.output_encoding = ISO-8859-1
+
+[intl]
+;intl.default_locale =
+; This directive allows you to produce PHP errors when some error
+; happens within intl functions. The value is the level of the error produced.
+; Default is 0, which does not produce any errors.
+;intl.error_level = E_WARNING
+
+[sqlite]
+; http://php.net/sqlite.assoc-case
+;sqlite.assoc_case = 0
+
+[sqlite3]
+;sqlite3.extension_dir =
+
+[Pcre]
+;PCRE library backtracking limit.
+; http://php.net/pcre.backtrack-limit
+;pcre.backtrack_limit=100000
+
+;PCRE library recursion limit.
+;Please note that if you set this value to a high number you may consume all
+;the available process stack and eventually crash PHP (due to reaching the
+;stack size limit imposed by the Operating System).
+; http://php.net/pcre.recursion-limit
+;pcre.recursion_limit=100000
+
+[Pdo]
+; Whether to pool ODBC connections. Can be one of "strict", "relaxed" or "off"
+; http://php.net/pdo-odbc.connection-pooling
+;pdo_odbc.connection_pooling=strict
+
+;pdo_odbc.db2_instance_name
+
+[Pdo_mysql]
+; If mysqlnd is used: Number of cache slots for the internal result set cache
+; http://php.net/pdo_mysql.cache_size
+pdo_mysql.cache_size = 2000
+
+; Default socket name for local MySQL connects.  If empty, uses the built-in
+; MySQL defaults.
+; http://php.net/pdo_mysql.default-socket
+pdo_mysql.default_socket=
+
+[Phar]
+; http://php.net/phar.readonly
+;phar.readonly = On
+
+; http://php.net/phar.require-hash
+;phar.require_hash = On
+
+;phar.cache_list =
+
+[Syslog]
+; Whether or not to define the various syslog variables (e.g. $LOG_PID,
+; $LOG_CRON, etc.).  Turning it off is a good idea performance-wise.  In
+; runtime, you can define these variables by calling define_syslog_variables().
+; http://php.net/define-syslog-variables
+define_syslog_variables  = Off
+
+[mail function]
+; For Win32 only.
+; http://php.net/smtp
+SMTP = localhost
+; http://php.net/smtp-port
+smtp_port = 25
+
+; For Win32 only.
+; http://php.net/sendmail-from
+;sendmail_from = me@example.com
+
+; For Unix only.  You may supply arguments as well (default: "sendmail -t -i").
+; http://php.net/sendmail-path
+;sendmail_path =
+
+; Force the addition of the specified parameters to be passed as extra parameters
+; to the sendmail binary. These parameters will always replace the value of
+; the 5th parameter to mail(), even in safe mode.
+;mail.force_extra_parameters =
+
+; Add X-PHP-Originating-Script: that will include uid of the script followed by the filename
+mail.add_x_header = On
+
+; The path to a log file that will log all mail() calls. Log entries include
+; the full path of the script, line number, To address and headers.
+;mail.log =
+
+[SQL]
+; http://php.net/sql.safe-mode
+sql.safe_mode = Off
+
+[ODBC]
+; http://php.net/odbc.default-db
+;odbc.default_db    =  Not yet implemented
+
+; http://php.net/odbc.default-user
+;odbc.default_user  =  Not yet implemented
+
+; http://php.net/odbc.default-pw
+;odbc.default_pw    =  Not yet implemented
+
+; Controls the ODBC cursor model.
+; Default: SQL_CURSOR_STATIC (default).
+;odbc.default_cursortype
+
+; Allow or prevent persistent links.
+; http://php.net/odbc.allow-persistent
+odbc.allow_persistent = On
+
+; Check that a connection is still valid before reuse.
+; http://php.net/odbc.check-persistent
+odbc.check_persistent = On
+
+; Maximum number of persistent links.  -1 means no limit.
+; http://php.net/odbc.max-persistent
+odbc.max_persistent = -1
+
+; Maximum number of links (persistent + non-persistent).  -1 means no limit.
+; http://php.net/odbc.max-links
+odbc.max_links = -1
+
+; Handling of LONG fields.  Returns number of bytes to variables.  0 means
+; passthru.
+; http://php.net/odbc.defaultlrl
+odbc.defaultlrl = 4096
+
+; Handling of binary data.  0 means passthru, 1 return as is, 2 convert to char.
+; See the documentation on odbc_binmode and odbc_longreadlen for an explanation
+; of odbc.defaultlrl and odbc.defaultbinmode
+; http://php.net/odbc.defaultbinmode
+odbc.defaultbinmode = 1
+
+;birdstep.max_links = -1
+
+[Interbase]
+; Allow or prevent persistent links.
+ibase.allow_persistent = 1
+
+; Maximum number of persistent links.  -1 means no limit.
+ibase.max_persistent = -1
+
+; Maximum number of links (persistent + non-persistent).  -1 means no limit.
+ibase.max_links = -1
+
+; Default database name for ibase_connect().
+;ibase.default_db =
+
+; Default username for ibase_connect().
+;ibase.default_user =
+
+; Default password for ibase_connect().
+;ibase.default_password =
+
+; Default charset for ibase_connect().
+;ibase.default_charset =
+
+; Default timestamp format.
+ibase.timestampformat = "%Y-%m-%d %H:%M:%S"
+
+; Default date format.
+ibase.dateformat = "%Y-%m-%d"
+
+; Default time format.
+ibase.timeformat = "%H:%M:%S"
+
+[MySQL]
+; Allow accessing, from PHP's perspective, local files with LOAD DATA statements
+; http://php.net/mysql.allow_local_infile
+mysql.allow_local_infile = On
+
+; Allow or prevent persistent links.
+; http://php.net/mysql.allow-persistent
+mysql.allow_persistent = On
+
+; If mysqlnd is used: Number of cache slots for the internal result set cache
+; http://php.net/mysql.cache_size
+mysql.cache_size = 2000
+
+; Maximum number of persistent links.  -1 means no limit.
+; http://php.net/mysql.max-persistent
+mysql.max_persistent = -1
+
+; Maximum number of links (persistent + non-persistent).  -1 means no limit.
+; http://php.net/mysql.max-links
+mysql.max_links = -1
+
+; Default port number for mysql_connect().  If unset, mysql_connect() will use
+; the $MYSQL_TCP_PORT or the mysql-tcp entry in /etc/services or the
+; compile-time value defined MYSQL_PORT (in that order).  Win32 will only look
+; at MYSQL_PORT.
+; http://php.net/mysql.default-port
+mysql.default_port =
+
+; Default socket name for local MySQL connects.  If empty, uses the built-in
+; MySQL defaults.
+; http://php.net/mysql.default-socket
+mysql.default_socket =
+
+; Default host for mysql_connect() (doesn't apply in safe mode).
+; http://php.net/mysql.default-host
+mysql.default_host =
+
+; Default user for mysql_connect() (doesn't apply in safe mode).
+; http://php.net/mysql.default-user
+mysql.default_user =
+
+; Default password for mysql_connect() (doesn't apply in safe mode).
+; Note that this is generally a *bad* idea to store passwords in this file.
+; *Any* user with PHP access can run 'echo get_cfg_var("mysql.default_password")
+; and reveal this password!  And of course, any users with read access to this
+; file will be able to reveal the password as well.
+; http://php.net/mysql.default-password
+mysql.default_password =
+
+; Maximum time (in seconds) for connect timeout. -1 means no limit
+; http://php.net/mysql.connect-timeout
+mysql.connect_timeout = 60
+
+; Trace mode. When trace_mode is active (=On), warnings for table/index scans and
+; SQL-Errors will be displayed.
+; http://php.net/mysql.trace-mode
+mysql.trace_mode = Off
+
+[MySQLi]
+
+; Maximum number of persistent links.  -1 means no limit.
+; http://php.net/mysqli.max-persistent
+mysqli.max_persistent = -1
+
+; Allow accessing, from PHP's perspective, local files with LOAD DATA statements
+; http://php.net/mysqli.allow_local_infile
+;mysqli.allow_local_infile = On
+
+; Allow or prevent persistent links.
+; http://php.net/mysqli.allow-persistent
+mysqli.allow_persistent = On
+
+; Maximum number of links.  -1 means no limit.
+; http://php.net/mysqli.max-links
+mysqli.max_links = -1
+
+; If mysqlnd is used: Number of cache slots for the internal result set cache
+; http://php.net/mysqli.cache_size
+mysqli.cache_size = 2000
+
+; Default port number for mysqli_connect().  If unset, mysqli_connect() will use
+; the $MYSQL_TCP_PORT or the mysql-tcp entry in /etc/services or the
+; compile-time value defined MYSQL_PORT (in that order).  Win32 will only look
+; at MYSQL_PORT.
+; http://php.net/mysqli.default-port
+mysqli.default_port = 3306
+
+; Default socket name for local MySQL connects.  If empty, uses the built-in
+; MySQL defaults.
+; http://php.net/mysqli.default-socket
+mysqli.default_socket =
+
+; Default host for mysql_connect() (doesn't apply in safe mode).
+; http://php.net/mysqli.default-host
+mysqli.default_host =
+
+; Default user for mysql_connect() (doesn't apply in safe mode).
+; http://php.net/mysqli.default-user
+mysqli.default_user =
+
+; Default password for mysqli_connect() (doesn't apply in safe mode).
+; Note that this is generally a *bad* idea to store passwords in this file.
+; *Any* user with PHP access can run 'echo get_cfg_var("mysqli.default_pw")
+; and reveal this password!  And of course, any users with read access to this
+; file will be able to reveal the password as well.
+; http://php.net/mysqli.default-pw
+mysqli.default_pw =
+
+; Allow or prevent reconnect
+mysqli.reconnect = Off
+
+[mysqlnd]
+; Enable / Disable collection of general statstics by mysqlnd which can be
+; used to tune and monitor MySQL operations.
+; http://php.net/mysqlnd.collect_statistics
+mysqlnd.collect_statistics = On
+
+; Enable / Disable collection of memory usage statstics by mysqlnd which can be
+; used to tune and monitor MySQL operations.
+; http://php.net/mysqlnd.collect_memory_statistics
+mysqlnd.collect_memory_statistics = Off
+
+; Size of a pre-allocated buffer used when sending commands to MySQL in bytes.
+; http://php.net/mysqlnd.net_cmd_buffer_size
+;mysqlnd.net_cmd_buffer_size = 2048
+
+; Size of a pre-allocated buffer used for reading data sent by the server in
+; bytes.
+; http://php.net/mysqlnd.net_read_buffer_size
+;mysqlnd.net_read_buffer_size = 32768
+
+[OCI8]
+
+; Connection: Enables privileged connections using external
+; credentials (OCI_SYSOPER, OCI_SYSDBA)
+; http://php.net/oci8.privileged-connect
+;oci8.privileged_connect = Off
+
+; Connection: The maximum number of persistent OCI8 connections per
+; process. Using -1 means no limit.
+; http://php.net/oci8.max-persistent
+;oci8.max_persistent = -1
+
+; Connection: The maximum number of seconds a process is allowed to
+; maintain an idle persistent connection. Using -1 means idle
+; persistent connections will be maintained forever.
+; http://php.net/oci8.persistent-timeout
+;oci8.persistent_timeout = -1
+
+; Connection: The number of seconds that must pass before issuing a
+; ping during oci_pconnect() to check the connection validity. When
+; set to 0, each oci_pconnect() will cause a ping. Using -1 disables
+; pings completely.
+; http://php.net/oci8.ping-interval
+;oci8.ping_interval = 60
+
+; Connection: Set this to a user chosen connection class to be used
+; for all pooled server requests with Oracle 11g Database Resident
+; Connection Pooling (DRCP).  To use DRCP, this value should be set to
+; the same string for all web servers running the same application,
+; the database pool must be configured, and the connection string must
+; specify to use a pooled server.
+;oci8.connection_class =
+
+; High Availability: Using On lets PHP receive Fast Application
+; Notification (FAN) events generated when a database node fails. The
+; database must also be configured to post FAN events.
+;oci8.events = Off
+
+; Tuning: This option enables statement caching, and specifies how
+; many statements to cache. Using 0 disables statement caching.
+; http://php.net/oci8.statement-cache-size
+;oci8.statement_cache_size = 20
+
+; Tuning: Enables statement prefetching and sets the default number of
+; rows that will be fetched automatically after statement execution.
+; http://php.net/oci8.default-prefetch
+;oci8.default_prefetch = 100
+
+; Compatibility. Using On means oci_close() will not close
+; oci_connect() and oci_new_connect() connections.
+; http://php.net/oci8.old-oci-close-semantics
+;oci8.old_oci_close_semantics = Off
+
+[PostgresSQL]
+; Allow or prevent persistent links.
+; http://php.net/pgsql.allow-persistent
+pgsql.allow_persistent = On
+
+; Detect broken persistent links always with pg_pconnect().
+; Auto reset feature requires a little overheads.
+; http://php.net/pgsql.auto-reset-persistent
+pgsql.auto_reset_persistent = Off
+
+; Maximum number of persistent links.  -1 means no limit.
+; http://php.net/pgsql.max-persistent
+pgsql.max_persistent = -1
+
+; Maximum number of links (persistent+non persistent).  -1 means no limit.
+; http://php.net/pgsql.max-links
+pgsql.max_links = -1
+
+; Ignore PostgreSQL backends Notice message or not.
+; Notice message logging require a little overheads.
+; http://php.net/pgsql.ignore-notice
+pgsql.ignore_notice = 0
+
+; Log PostgreSQL backends Notice message or not.
+; Unless pgsql.ignore_notice=0, module cannot log notice message.
+; http://php.net/pgsql.log-notice
+pgsql.log_notice = 0
+
+[Sybase-CT]
+; Allow or prevent persistent links.
+; http://php.net/sybct.allow-persistent
+sybct.allow_persistent = On
+
+; Maximum number of persistent links.  -1 means no limit.
+; http://php.net/sybct.max-persistent
+sybct.max_persistent = -1
+
+; Maximum number of links (persistent + non-persistent).  -1 means no limit.
+; http://php.net/sybct.max-links
+sybct.max_links = -1
+
+; Minimum server message severity to display.
+; http://php.net/sybct.min-server-severity
+sybct.min_server_severity = 10
+
+; Minimum client message severity to display.
+; http://php.net/sybct.min-client-severity
+sybct.min_client_severity = 10
+
+; Set per-context timeout
+; http://php.net/sybct.timeout
+;sybct.timeout=
+
+;sybct.packet_size
+
+; The maximum time in seconds to wait for a connection attempt to succeed before returning failure.
+; Default: one minute
+;sybct.login_timeout=
+
+; The name of the host you claim to be connecting from, for display by sp_who.
+; Default: none
+;sybct.hostname=
+
+; Allows you to define how often deadlocks are to be retried. -1 means "forever".
+; Default: 0
+;sybct.deadlock_retry_count=
+
+[bcmath]
+; Number of decimal digits for all bcmath functions.
+; http://php.net/bcmath.scale
+bcmath.scale = 0
+
+[browscap]
+; http://php.net/browscap
+;browscap = extra/browscap.ini
+
+[Session]
+; Handler used to store/retrieve data.
+; http://php.net/session.save-handler
+session.save_handler = files
+
+; Argument passed to save_handler.  In the case of files, this is the path
+; where data files are stored. Note: Windows users have to change this
+; variable in order to use PHP's session functions.
+;
+; The path can be defined as:
+;
+;     session.save_path = "N;/path"
+;
+; where N is an integer.  Instead of storing all the session files in
+; /path, what this will do is use subdirectories N-levels deep, and
+; store the session data in those directories.  This is useful if you
+; or your OS have problems with lots of files in one directory, and is
+; a more efficient layout for servers that handle lots of sessions.
+;
+; NOTE 1: PHP will not create this directory structure automatically.
+;         You can use the script in the ext/session dir for that purpose.
+; NOTE 2: See the section on garbage collection below if you choose to
+;         use subdirectories for session storage
+;
+; The file storage module creates files using mode 600 by default.
+; You can change that by using
+;
+;     session.save_path = "N;MODE;/path"
+;
+; where MODE is the octal representation of the mode. Note that this
+; does not overwrite the process's umask.
+; http://php.net/session.save-path
+;session.save_path = "/tmp"
+
+; Whether to use cookies.
+; http://php.net/session.use-cookies
+session.use_cookies = 1
+
+; http://php.net/session.cookie-secure
+;session.cookie_secure =
+
+; This option forces PHP to fetch and use a cookie for storing and maintaining
+; the session id. We encourage this operation as it's very helpful in combatting
+; session hijacking when not specifying and managing your own session id. It is
+; not the end all be all of session hijacking defense, but it's a good start.
+; http://php.net/session.use-only-cookies
+session.use_only_cookies = 1
+
+; Name of the session (used as cookie name).
+; http://php.net/session.name
+session.name = PHPSESSID
+
+; Initialize session on request startup.
+; http://php.net/session.auto-start
+session.auto_start = 0
+
+; Lifetime in seconds of cookie or, if 0, until browser is restarted.
+; http://php.net/session.cookie-lifetime
+session.cookie_lifetime = 0
+
+; The path for which the cookie is valid.
+; http://php.net/session.cookie-path
+session.cookie_path = /
+
+; The domain for which the cookie is valid.
+; http://php.net/session.cookie-domain
+session.cookie_domain =
+
+; Whether or not to add the httpOnly flag to the cookie, which makes it inaccessible to browser scripting languages such as JavaScript.
+; http://php.net/session.cookie-httponly
+session.cookie_httponly =
+
+; Handler used to serialize data.  php is the standard serializer of PHP.
+; http://php.net/session.serialize-handler
+session.serialize_handler = php
+
+; Defines the probability that the 'garbage collection' process is started
+; on every session initialization. The probability is calculated by using
+; gc_probability/gc_divisor. Where session.gc_probability is the numerator
+; and gc_divisor is the denominator in the equation. Setting this value to 1
+; when the session.gc_divisor value is 100 will give you approximately a 1% chance
+; the gc will run on any give request.
+; Default Value: 1
+; Development Value: 1
+; Production Value: 1
+; http://php.net/session.gc-probability
+session.gc_probability = 0
+
+; Defines the probability that the 'garbage collection' process is started on every
+; session initialization. The probability is calculated by using the following equation:
+; gc_probability/gc_divisor. Where session.gc_probability is the numerator and
+; session.gc_divisor is the denominator in the equation. Setting this value to 1
+; when the session.gc_divisor value is 100 will give you approximately a 1% chance
+; the gc will run on any give request. Increasing this value to 1000 will give you
+; a 0.1% chance the gc will run on any give request. For high volume production servers,
+; this is a more efficient approach.
+; Default Value: 100
+; Development Value: 1000
+; Production Value: 1000
+; http://php.net/session.gc-divisor
+session.gc_divisor = 1000
+
+; After this number of seconds, stored data will be seen as 'garbage' and
+; cleaned up by the garbage collection process.
+; http://php.net/session.gc-maxlifetime
+session.gc_maxlifetime = 1440
+
+; NOTE: If you are using the subdirectory option for storing session files
+;       (see session.save_path above), then garbage collection does *not*
+;       happen automatically.  You will need to do your own garbage
+;       collection through a shell script, cron entry, or some other method.
+;       For example, the following script would is the equivalent of
+;       setting session.gc_maxlifetime to 1440 (1440 seconds = 24 minutes):
+;          find /path/to/sessions -cmin +24 | xargs rm
+
+; PHP 4.2 and less have an undocumented feature/bug that allows you to
+; to initialize a session variable in the global scope, even when register_globals
+; is disabled.  PHP 4.3 and later will warn you, if this feature is used.
+; You can disable the feature and the warning separately. At this time,
+; the warning is only displayed, if bug_compat_42 is enabled. This feature
+; introduces some serious security problems if not handled correctly. It's
+; recommended that you do not use this feature on production servers. But you
+; should enable this on development servers and enable the warning as well. If you
+; do not enable the feature on development servers, you won't be warned when it's
+; used and debugging errors caused by this can be difficult to track down.
+; Default Value: On
+; Development Value: On
+; Production Value: Off
+; http://php.net/session.bug-compat-42
+session.bug_compat_42 = Off
+
+; This setting controls whether or not you are warned by PHP when initializing a
+; session value into the global space. session.bug_compat_42 must be enabled before
+; these warnings can be issued by PHP. See the directive above for more information.
+; Default Value: On
+; Development Value: On
+; Production Value: Off
+; http://php.net/session.bug-compat-warn
+session.bug_compat_warn = Off
+
+; Check HTTP Referer to invalidate externally stored URLs containing ids.
+; HTTP_REFERER has to contain this substring for the session to be
+; considered as valid.
+; http://php.net/session.referer-check
+session.referer_check =
+
+; How many bytes to read from the file.
+; http://php.net/session.entropy-length
+session.entropy_length = 0
+
+; Specified here to create the session id.
+; http://php.net/session.entropy-file
+; On systems that don't have /dev/urandom /dev/arandom can be used
+; On windows, setting the entropy_length setting will activate the 
+; Windows random source (using the CryptoAPI)
+;session.entropy_file = /dev/urandom
+
+; Set to {nocache,private,public,} to determine HTTP caching aspects
+; or leave this empty to avoid sending anti-caching headers.
+; http://php.net/session.cache-limiter
+session.cache_limiter = nocache
+
+; Document expires after n minutes.
+; http://php.net/session.cache-expire
+session.cache_expire = 180
+
+; trans sid support is disabled by default.
+; Use of trans sid may risk your users security.
+; Use this option with caution.
+; - User may send URL contains active session ID
+;   to other person via. email/irc/etc.
+; - URL that contains active session ID may be stored
+;   in publically accessible computer.
+; - User may access your site with the same session ID
+;   always using URL stored in browser's history or bookmarks.
+; http://php.net/session.use-trans-sid
+session.use_trans_sid = 0
+
+; Select a hash function for use in generating session ids.
+; Possible Values
+;   0  (MD5 128 bits)
+;   1  (SHA-1 160 bits)
+; This option may also be set to the name of any hash function supported by
+; the hash extension. A list of available hashes is returned by the hash_algos()
+; function.
+; http://php.net/session.hash-function
+session.hash_function = 0
+
+; Define how many bits are stored in each character when converting
+; the binary hash data to something readable.
+; Possible values:
+;   4  (4 bits: 0-9, a-f)
+;   5  (5 bits: 0-9, a-v)
+;   6  (6 bits: 0-9, a-z, A-Z, "-", ",")
+; Default Value: 4
+; Development Value: 5
+; Production Value: 5
+; http://php.net/session.hash-bits-per-character
+session.hash_bits_per_character = 5
+
+; The URL rewriter will look for URLs in a defined set of HTML tags.
+; form/fieldset are special; if you include them here, the rewriter will
+; add a hidden <input> field with the info which is otherwise appended
+; to URLs.  If you want XHTML conformity, remove the form entry.
+; Note that all valid entries require a "=", even if no value follows.
+; Default Value: "a=href,area=href,frame=src,form=,fieldset="
+; Development Value: "a=href,area=href,frame=src,input=src,form=fakeentry"
+; Production Value: "a=href,area=href,frame=src,input=src,form=fakeentry"
+; http://php.net/url-rewriter.tags
+url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry"
+
+[MSSQL]
+; Allow or prevent persistent links.
+mssql.allow_persistent = On
+
+; Maximum number of persistent links.  -1 means no limit.
+mssql.max_persistent = -1
+
+; Maximum number of links (persistent+non persistent).  -1 means no limit.
+mssql.max_links = -1
+
+; Minimum error severity to display.
+mssql.min_error_severity = 10
+
+; Minimum message severity to display.
+mssql.min_message_severity = 10
+
+; Compatibility mode with old versions of PHP 3.0.
+mssql.compatability_mode = Off
+
+; Connect timeout
+;mssql.connect_timeout = 5
+
+; Query timeout
+;mssql.timeout = 60
+
+; Valid range 0 - 2147483647.  Default = 4096.
+;mssql.textlimit = 4096
+
+; Valid range 0 - 2147483647.  Default = 4096.
+;mssql.textsize = 4096
+
+; Limits the number of records in each batch.  0 = all records in one batch.
+;mssql.batchsize = 0
+
+; Specify how datetime and datetim4 columns are returned
+; On => Returns data converted to SQL server settings
+; Off => Returns values as YYYY-MM-DD hh:mm:ss
+;mssql.datetimeconvert = On
+
+; Use NT authentication when connecting to the server
+mssql.secure_connection = Off
+
+; Specify max number of processes. -1 = library default
+; msdlib defaults to 25
+; FreeTDS defaults to 4096
+;mssql.max_procs = -1
+
+; Specify client character set.
+; If empty or not set the client charset from freetds.comf is used
+; This is only used when compiled with FreeTDS
+;mssql.charset = "ISO-8859-1"
+
+[Assertion]
+; Assert(expr); active by default.
+; http://php.net/assert.active
+;assert.active = On
+
+; Issue a PHP warning for each failed assertion.
+; http://php.net/assert.warning
+;assert.warning = On
+
+; Don't bail out by default.
+; http://php.net/assert.bail
+;assert.bail = Off
+
+; User-function to be called if an assertion fails.
+; http://php.net/assert.callback
+;assert.callback = 0
+
+; Eval the expression with current error_reporting().  Set to true if you want
+; error_reporting(0) around the eval().
+; http://php.net/assert.quiet-eval
+;assert.quiet_eval = 0
+
+[COM]
+; path to a file containing GUIDs, IIDs or filenames of files with TypeLibs
+; http://php.net/com.typelib-file
+;com.typelib_file =
+
+; allow Distributed-COM calls
+; http://php.net/com.allow-dcom
+;com.allow_dcom = true
+
+; autoregister constants of a components typlib on com_load()
+; http://php.net/com.autoregister-typelib
+;com.autoregister_typelib = true
+
+; register constants casesensitive
+; http://php.net/com.autoregister-casesensitive
+;com.autoregister_casesensitive = false
+
+; show warnings on duplicate constant registrations
+; http://php.net/com.autoregister-verbose
+;com.autoregister_verbose = true
+
+; The default character set code-page to use when passing strings to and from COM objects.
+; Default: system ANSI code page
+;com.code_page=
+
+[mbstring]
+; language for internal character representation.
+; http://php.net/mbstring.language
+;mbstring.language = Japanese
+
+; internal/script encoding.
+; Some encoding cannot work as internal encoding.
+; (e.g. SJIS, BIG5, ISO-2022-*)
+; http://php.net/mbstring.internal-encoding
+;mbstring.internal_encoding = EUC-JP
+
+; http input encoding.
+; http://php.net/mbstring.http-input
+;mbstring.http_input = auto
+
+; http output encoding. mb_output_handler must be
+; registered as output buffer to function
+; http://php.net/mbstring.http-output
+;mbstring.http_output = SJIS
+
+; enable automatic encoding translation according to
+; mbstring.internal_encoding setting. Input chars are
+; converted to internal encoding by setting this to On.
+; Note: Do _not_ use automatic encoding translation for
+;       portable libs/applications.
+; http://php.net/mbstring.encoding-translation
+;mbstring.encoding_translation = Off
+
+; automatic encoding detection order.
+; auto means
+; http://php.net/mbstring.detect-order
+;mbstring.detect_order = auto
+
+; substitute_character used when character cannot be converted
+; one from another
+; http://php.net/mbstring.substitute-character
+;mbstring.substitute_character = none;
+
+; overload(replace) single byte functions by mbstring functions.
+; mail(), ereg(), etc are overloaded by mb_send_mail(), mb_ereg(),
+; etc. Possible values are 0,1,2,4 or combination of them.
+; For example, 7 for overload everything.
+; 0: No overload
+; 1: Overload mail() function
+; 2: Overload str*() functions
+; 4: Overload ereg*() functions
+; http://php.net/mbstring.func-overload
+;mbstring.func_overload = 0
+
+; enable strict encoding detection.
+;mbstring.strict_detection = Off
+
+; This directive specifies the regex pattern of content types for which mb_output_handler()
+; is activated.
+; Default: mbstring.http_output_conv_mimetype=^(text/|application/xhtml\+xml)
+;mbstring.http_output_conv_mimetype=
+
+; Allows to set script encoding. Only affects if PHP is compiled with --enable-zend-multibyte
+; Default: ""
+;mbstring.script_encoding=
+
+[gd]
+; Tell the jpeg decode to ignore warnings and try to create
+; a gd image. The warning will then be displayed as notices
+; disabled by default
+; http://php.net/gd.jpeg-ignore-warning
+;gd.jpeg_ignore_warning = 0
+
+[exif]
+; Exif UNICODE user comments are handled as UCS-2BE/UCS-2LE and JIS as JIS.
+; With mbstring support this will automatically be converted into the encoding
+; given by corresponding encode setting. When empty mbstring.internal_encoding
+; is used. For the decode settings you can distinguish between motorola and
+; intel byte order. A decode setting cannot be empty.
+; http://php.net/exif.encode-unicode
+;exif.encode_unicode = ISO-8859-15
+
+; http://php.net/exif.decode-unicode-motorola
+;exif.decode_unicode_motorola = UCS-2BE
+
+; http://php.net/exif.decode-unicode-intel
+;exif.decode_unicode_intel    = UCS-2LE
+
+; http://php.net/exif.encode-jis
+;exif.encode_jis =
+
+; http://php.net/exif.decode-jis-motorola
+;exif.decode_jis_motorola = JIS
+
+; http://php.net/exif.decode-jis-intel
+;exif.decode_jis_intel    = JIS
+
+[Tidy]
+; The path to a default tidy configuration file to use when using tidy
+; http://php.net/tidy.default-config
+;tidy.default_config = /usr/local/lib/php/default.tcfg
+
+; Should tidy clean and repair output automatically?
+; WARNING: Do not use this option if you are generating non-html content
+; such as dynamic images
+; http://php.net/tidy.clean-output
+tidy.clean_output = Off
+
+[soap]
+; Enables or disables WSDL caching feature.
+; http://php.net/soap.wsdl-cache-enabled
+soap.wsdl_cache_enabled=1
+
+; Sets the directory name where SOAP extension will put cache files.
+; http://php.net/soap.wsdl-cache-dir
+soap.wsdl_cache_dir="/tmp"
+
+; (time to live) Sets the number of second while cached file will be used
+; instead of original one.
+; http://php.net/soap.wsdl-cache-ttl
+soap.wsdl_cache_ttl=86400
+
+; Sets the size of the cache limit. (Max. number of WSDL files to cache)
+soap.wsdl_cache_limit = 5
+
+[sysvshm]
+; A default size of the shared memory segment
+;sysvshm.init_mem = 10000
+
+[ldap]
+; Sets the maximum number of open links or -1 for unlimited.
+ldap.max_links = -1
+
+[mcrypt]
+; For more information about mcrypt settings see http://php.net/mcrypt-module-open
+
+; Directory where to load mcrypt algorithms
+; Default: Compiled in into libmcrypt (usually /usr/local/lib/libmcrypt)
+;mcrypt.algorithms_dir=
+
+; Directory where to load mcrypt modes
+; Default: Compiled in into libmcrypt (usually /usr/local/lib/libmcrypt)
+;mcrypt.modes_dir=
+
+[dba]
+;dba.default_handler=
+
+; Local Variables:
+; tab-width: 4
+; End:
diff --git a/connector/php/test/etc/tarantool_box.cfg b/connector/php/test/etc/tarantool_box.cfg
new file mode 100644
index 0000000000..9ccb6910a3
--- /dev/null
+++ b/connector/php/test/etc/tarantool_box.cfg
@@ -0,0 +1,55 @@
+# Limit of memory used to store tuples to 100MB
+# (0.1 GB)
+# This effectively limits the memory, used by
+# Tarantool. However, index and connection memory
+# is stored outside the slab allocator, hence
+# the effective memory usage can be higher (sometimes
+# twice as high).
+slab_alloc_arena = 0.1
+
+# Tarantool executable directory
+work_dir = "var"
+
+# Store the pid in this file. Relative to startup dir.
+pid_file = "tarantool_box.pid"
+
+# Snapshot directory (where snapshots get saved/read)
+snap_dir="."
+
+# WAL directory (where WALs get saved/read)
+wal_dir="."
+
+# Pipe the logs into the following process.
+logger="cat - >> tarantool_box.log"
+
+# Read only and read-write port.
+primary_port = 33013
+
+# Read-only port.
+secondary_port = 33014
+
+# The port for administrative commands.
+admin_port = 33015
+
+# Log level
+log_level = 4
+
+# Each write ahead log contains this many rows.
+# When the limit is reached, Tarantool closes
+# the WAL and starts a new one.
+rows_per_wal = 5000000
+
+wal_fsync_delay = 0.1
+wal_writer_inbox_size=1024
+
+# Define a simple space with 1 HASH-based
+# primary key.
+space[0].enabled = 1
+space[0].index[0].type = "HASH"
+space[0].index[0].unique = 1
+space[0].index[0].key_field[0].fieldno = 0
+space[0].index[0].key_field[0].type = "NUM"
+space[0].index[1].type = "TREE"
+space[0].index[1].unique = 0
+space[0].index[1].key_field[0].fieldno = 1
+space[0].index[1].key_field[0].type = "STR"
diff --git a/connector/php/test/insert.phpt b/connector/php/test/insert.phpt
new file mode 100644
index 0000000000..047db2a297
--- /dev/null
+++ b/connector/php/test/insert.phpt
@@ -0,0 +1,173 @@
+--TEST--
+Tarantool/box insert command test
+--FILE--
+<?php
+include "lib/php/tarantool_utest.php";
+
+$tarantool = new Tarantool("localhost", 33013, 33015);
+
+echo "---------- test begin ----------\n";
+echo "test insert: invalid tuple (expected error exception)\n";
+test_insert($tarantool, 0, array(0, array(1, 2, 3), "str"), 0);
+echo "----------- test end -----------\n\n";
+
+echo "---------- test begin ----------\n";
+echo "test insert: invalid tuple (expected error exception)\n";
+test_insert($tarantool, 0, array(0, $tarantool), 0);
+echo "----------- test end -----------\n\n";
+
+echo "---------- test begin ----------\n";
+echo "test insert: assign tuple";
+test_insert($tarantool, 0, $sw4,
+            TARANTOOL_FLAGS_RETURN_TUPLE);
+echo "----------- test end -----------\n\n";
+
+echo "---------- test begin ----------\n";
+echo "test insert: assign tuple (tuple doesn't return)\n";
+test_insert($tarantool, 0, $sw6, 0);
+echo "----------- test end -----------\n\n";
+
+echo "---------- test begin ----------\n";
+echo "test insert: add existed tuple (expected error exception)\n";
+test_insert($tarantool, 0, $sw4,
+            TARANTOOL_FLAGS_RETURN_TUPLE | TARANTOOL_FLAGS_ADD);
+echo "----------- test end -----------\n\n";
+
+echo "---------- test begin ----------\n";
+echo "test insert: replace not existed tuple (expected error exception)\n";
+test_insert($tarantool, 0, $sw5,
+            TARANTOOL_FLAGS_RETURN_TUPLE | TARANTOOL_FLAGS_REPLACE);
+echo "----------- test end -----------\n\n";
+
+echo "---------- test begin ----------\n";
+echo "test insert: add not existed tuple\n";
+test_insert($tarantool, 0, $sw5,
+            TARANTOOL_FLAGS_RETURN_TUPLE | TARANTOOL_FLAGS_ADD);
+echo "----------- test end -----------\n\n";
+
+echo "---------- test begin ----------\n";
+echo "test insert: replace existed tuple\n";
+test_insert($tarantool, 0, $sw5,
+            TARANTOOL_FLAGS_RETURN_TUPLE | TARANTOOL_FLAGS_REPLACE);
+echo "----------- test end -----------\n\n";
+
+test_clean($tarantool, 0);
+?>
+===DONE===
+--EXPECT--
+---------- test begin ----------
+test insert: invalid tuple (expected error exception)
+catched exception: unsupported field type
+----------- test end -----------
+
+---------- test begin ----------
+test insert: invalid tuple (expected error exception)
+catched exception: unsupported field type
+----------- test end -----------
+
+---------- test begin ----------
+test insert: assign tupleresult:
+count = 1
+tuple:
+  id     = 0
+  series = Star Wars
+  year   = 1977
+  name   = A New Hope
+  crawl  = A long time ago, in a galaxy far, far away...
+It is a period of civil war. Rebel
+spaceships, striking from a hidden
+base, have won their first victory
+against the evil Galactic Empire.
+
+During the battle, Rebel spies managed
+to steal secret plans to the Empire's
+ultimate weapon, the Death Star, an
+armored space station with enough
+power to destroy an entire planet.
+
+Pursued by the Empire's sinister agents,
+Princess Leia races home aboard her
+starship, custodian of the stolen plans
+that can save her people and restore
+freedom to the galaxy....
+----------- test end -----------
+
+---------- test begin ----------
+test insert: assign tuple (tuple doesn't return)
+result:
+count = 1
+----------- test end -----------
+
+---------- test begin ----------
+test insert: add existed tuple (expected error exception)
+catched exception: insert failed: 14082
+----------- test end -----------
+
+---------- test begin ----------
+test insert: replace not existed tuple (expected error exception)
+catched exception: insert failed: 12546
+----------- test end -----------
+
+---------- test begin ----------
+test insert: add not existed tuple
+result:
+count = 1
+tuple:
+  id     = 1
+  series = Star Wars
+  year   = 1980
+  name   = The Empire Strikes Back
+  crawl  = It is a dark time for the
+Rebellion. Although the Death
+Star has been destroyed.
+Imperial troops have driven the
+Rebel forces from their hidden
+base and pursued them across
+the galaxy.
+
+Evading the dreaded Imperial
+Starfleet, a group of freedom
+fighters led by Luke Skywalker
+have established a new secret base
+on the remote ice world
+of Hoth.
+
+The evil lord Darth Vader,
+obsessed with finding young
+Skywalker, has dispatched
+thousands of remote probes
+into the far reaches of space....
+----------- test end -----------
+
+---------- test begin ----------
+test insert: replace existed tuple
+result:
+count = 1
+tuple:
+  id     = 1
+  series = Star Wars
+  year   = 1980
+  name   = The Empire Strikes Back
+  crawl  = It is a dark time for the
+Rebellion. Although the Death
+Star has been destroyed.
+Imperial troops have driven the
+Rebel forces from their hidden
+base and pursued them across
+the galaxy.
+
+Evading the dreaded Imperial
+Starfleet, a group of freedom
+fighters led by Luke Skywalker
+have established a new secret base
+on the remote ice world
+of Hoth.
+
+The evil lord Darth Vader,
+obsessed with finding young
+Skywalker, has dispatched
+thousands of remote probes
+into the far reaches of space....
+----------- test end -----------
+
+===DONE===
\ No newline at end of file
diff --git a/connector/php/test/lib/lua/test.lua b/connector/php/test/lib/lua/test.lua
new file mode 100644
index 0000000000..2dcc8f1df6
--- /dev/null
+++ b/connector/php/test/lib/lua/test.lua
@@ -0,0 +1,25 @@
+function myselect(space, index, key)
+    print("select in space: ", space, " index: ", index, " by key ", key)
+    return box.select(space, index, key)
+end
+
+function myfoo()
+    return { 0, "Star Wars", "1977 year", "A New Hope",
+	     "A long time ago, in a galaxy far, far away...\n" ..
+             "It is a period of civil war. Rebel\n" ..
+             "spaceships, striking from a hidden\n" ..
+             "base, have won their first victory\n" ..
+             "against the evil Galactic Empire.\n" ..
+             "\n" ..
+             "During the battle, Rebel spies managed\n" ..
+             "to steal secret plans to the Empire's\n" ..
+             "ultimate weapon, the Death Star, an\n" ..
+             "armored space station with enough\n"..
+             "power to destroy an entire planet.\n" ..
+             "\n" ..
+             "Pursued by the Empire's sinister agents,\n" ..
+             "Princess Leia races home aboard her\n" ..
+             "starship, custodian of the stolen plans\n" ..
+             "that can save her people and restore\n" ..
+             "freedom to the galaxy...." }
+end
\ No newline at end of file
diff --git a/connector/php/test/lib/php/tarantool_utest.php b/connector/php/test/lib/php/tarantool_utest.php
new file mode 100644
index 0000000000..27ac276d7b
--- /dev/null
+++ b/connector/php/test/lib/php/tarantool_utest.php
@@ -0,0 +1,183 @@
+<?php
+
+$sw4 = array(0, "Star Wars", 1977, "A New Hope",
+             "A long time ago, in a galaxy far, far away...\n" .
+             "It is a period of civil war. Rebel\n" .
+             "spaceships, striking from a hidden\n" .
+             "base, have won their first victory\n" .
+             "against the evil Galactic Empire.\n" .
+             "\n" .
+             "During the battle, Rebel spies managed\n" .
+             "to steal secret plans to the Empire's\n" .
+             "ultimate weapon, the Death Star, an\n" . 
+             "armored space station with enough\n". 
+             "power to destroy an entire planet.\n" .
+             "\n" .
+             "Pursued by the Empire's sinister agents,\n" .
+             "Princess Leia races home aboard her\n" .
+             "starship, custodian of the stolen plans\n" .
+             "that can save her people and restore\n" .
+             "freedom to the galaxy....");
+
+$sw5 = array(1, "Star Wars", 1980, "The Empire Strikes Back",
+             "It is a dark time for the\n" . 
+             "Rebellion. Although the Death\n" . 
+             "Star has been destroyed.\n" .
+             "Imperial troops have driven the\n" . 
+             "Rebel forces from their hidden\n" .
+             "base and pursued them across\n" . 
+             "the galaxy.\n" .
+             "\n" .
+             "Evading the dreaded Imperial\n" .
+             "Starfleet, a group of freedom\n" .
+             "fighters led by Luke Skywalker\n" .
+             "have established a new secret base\n" .
+             "on the remote ice world\n" .
+             "of Hoth.\n" .
+             "\n" .
+             "The evil lord Darth Vader,\n" .
+             "obsessed with finding young\n" .
+             "Skywalker, has dispatched\n" .
+             "thousands of remote probes\n" .
+             "into the far reaches of space....");
+
+$sw6 = array(2, "Star Wars", 1983, "Return of the Jedi",
+             "Luke Skywalker has returned\n" .
+             "to his home planet of\n" .
+             "Tatooine in an attempt\n" .
+             "to rescue his friend\n" .
+             "Han Solo from the\n" .
+             "clutches of the vile\n" .
+             "gangster Jabba the Hutt.\n" .
+             "\n" .
+             "Little does Luke know\n" .
+             "that the GALACTIC EMPIRE\n" .
+             "has secretly begun construction\n" .
+             "on a new armored space station\n" .
+             "even more powerful than the\n" .
+             "first dreaded Death Star.\n" .
+             "\n" .
+             "When completed, this ultimate\n" .
+             "weapon will spell certain\n" .
+             "doom for the small band of\n" .
+             "rebels struggling to restore\n" .
+             "freedom to the galaxy...");
+
+function test_init($tarantool, $space_no) {
+    try {
+        global $sw4, $sw5, $sw6;
+        $tarantool->insert($space_no, $sw4);
+        $tarantool->insert($space_no, $sw5);
+        $tarantool->insert($space_no, $sw6);
+    } catch (Exception $e) {
+        echo "init failed: ", $e->getMessage(), "\n";
+        throw $e;
+    }
+}
+
+function test_clean($tarantool, $space_no) {
+    try {
+        $tarantool->delete($space_no, 0);
+        $tarantool->delete($space_no, 1);
+        $tarantool->delete($space_no, 2);
+    } catch (Exception $e) {
+        echo "clean-up failed: ", $e->getMessage(), "\n";
+        throw $e;
+    } 
+}
+
+function test_select($tarantool, $space_no, $index_no, $key) {
+    try {
+        $result = $tarantool->select($space_no, $index_no, $key);
+        echo "result:\n";
+        echo "count = ", $result["count"], "\n";
+        $tuples_list = $result["tuples_list"];
+        sort($tuples_list);
+        for ($i = 0; $i < $result["count"]; $i++) {
+            echo "tuple[", $i, "]:", "\n";
+            echo "  id     = ", $tuples_list[$i][0], "\n";
+            echo "  series = ", $tuples_list[$i][1], "\n";
+            echo "  year   = ", $tuples_list[$i][2], "\n";
+            echo "  name   = ", $tuples_list[$i][3], "\n";
+            echo "  crawl  = ", $tuples_list[$i][4], "\n";
+        }
+    } catch (Exception $e) {
+        echo "catched exception: ", $e->getMessage(), "\n";
+    }
+}
+
+function test_insert($tarantool, $space_no, $tuple, $flags) {
+    try {
+        $result = $tarantool->insert($space_no, $tuple, $flags);
+        echo "result:\n";
+        echo "count = ", $result["count"], "\n";
+        if ($flags & TARANTOOL_FLAGS_RETURN_TUPLE) {
+            echo "tuple:", "\n";
+            echo "  id     = ", $result["tuple"][0], "\n";
+            echo "  series = ", $result["tuple"][1], "\n";
+            echo "  year   = ", $result["tuple"][2], "\n";
+            echo "  name   = ", $result["tuple"][3], "\n";
+            echo "  crawl  = ", $result["tuple"][4], "\n";
+        }
+    } catch (Exception $e) {
+        echo "catched exception: ", $e->getMessage(), "\n";
+    }
+}
+
+function test_update_fields($tarantool, $space_no, $tuple, $ops, $flags) {
+    try {
+        $result = $tarantool->update_fields($space_no, $tuple, $ops, $flags);
+        echo "result:\n";
+        echo "count = ", $result["count"], "\n";
+        if ($flags & TARANTOOL_FLAGS_RETURN_TUPLE) {
+            echo "tuple:", "\n";
+            echo "  id     = ", $result["tuple"][0], "\n";
+            echo "  series = ", $result["tuple"][1], "\n";
+            echo "  year   = ", $result["tuple"][2], "\n";
+            echo "  name   = ", $result["tuple"][3], "\n";
+            echo "  crawl  = ", $result["tuple"][4], "\n";
+        }
+    } catch (Exception $e) {
+        echo "catched exception: ", $e->getMessage(), "\n";
+    }
+}
+
+function test_delete($tarantool, $space_no, $tuple, $flags) {
+    try {
+        $result = $tarantool->delete($space_no, $tuple, $flags);
+        echo "result:\n";
+        echo "count = ", $result["count"], "\n";
+        if ($flags & TARANTOOL_FLAGS_RETURN_TUPLE) {
+            echo "tuple:", "\n";
+            echo "  id     = ", $result["tuple"][0], "\n";
+            echo "  series = ", $result["tuple"][1], "\n";
+            echo "  year   = ", $result["tuple"][2], "\n";
+            echo "  name   = ", $result["tuple"][3], "...\n";
+            echo "  crawl  = ", $result["tuple"][4], "\n";
+        }
+    } catch (Exception $e) {
+        echo "catched exception: ", $e->getMessage(), "\n";
+    }
+}
+
+function test_call($tarantool, $proc, $tuple, $flags) {
+    try {
+        $result = $tarantool->call($proc, $tuple, $flags);
+        echo "result:\n";
+        echo "count = ", $result["count"], "\n";
+        $tuples_list = $result["tuples_list"];
+        sort($tuples_list);
+        for ($i = 0; $i < $result["count"]; $i++) {
+            echo "tuple[", $i, "]:", "\n";
+            echo "  id     = ", $tuples_list[$i][0], "\n";
+            echo "  series = ", $tuples_list[$i][1], "\n";
+            echo "  year   = ", $tuples_list[$i][2], "\n";
+            echo "  name   = ", $tuples_list[$i][3], "...\n";
+            echo "  crawl  = ", $tuples_list[$i][4], "\n";
+        }
+    } catch (Exception $e) {
+        echo "catched exception: ", $e->getMessage(), "\n";
+    }
+}
+
+?>
diff --git a/connector/php/test/run-test b/connector/php/test/run-test
new file mode 120000
index 0000000000..1993bbd700
--- /dev/null
+++ b/connector/php/test/run-test
@@ -0,0 +1 @@
+bin/run-test.bash
\ No newline at end of file
diff --git a/connector/php/test/select.phpt b/connector/php/test/select.phpt
new file mode 100644
index 0000000000..c9a7b1d96c
--- /dev/null
+++ b/connector/php/test/select.phpt
@@ -0,0 +1,346 @@
+--TEST--
+Tarantool/box select commands test
+--FILE--
+<?php
+include "lib/php/tarantool_utest.php";
+
+$tarantool = new Tarantool("localhost", 33013, 33015);
+test_init($tarantool, 0);
+
+echo "---------- test begin ----------\n";
+echo "test select: key is integer\n";
+test_select($tarantool, 0, 0, 0);
+echo "----------- test end -----------\n\n";
+
+echo "---------- test begin ----------\n";
+echo "test select: key is string \n";
+test_select($tarantool, 0, 1, "Star Wars");
+echo "----------- test end -----------\n\n";
+
+echo "---------- test begin ----------\n";
+echo "test select: key is object (expected error exception)\n";
+test_select($tarantool, 0, 0, $tarantool);
+echo "----------- test end -----------\n\n";
+
+echo "---------- test begin ----------\n";
+echo "test select: key is array\n";
+test_select($tarantool, 0, 1, array("Star Wars"));
+echo "----------- test end -----------\n\n";
+
+echo "---------- test begin ----------\n";
+echo "test select: key is empty array (expected error exception)\n";
+test_select($tarantool, 0, 0, array());
+echo "----------- test end -----------\n\n";
+
+echo "---------- test begin ----------\n";
+echo "test select: key is array of objects (expected error exception)\n";
+test_select($tarantool, 0, 0, array($tarantool, 1, 2));
+echo "----------- test end -----------\n\n";
+
+echo "---------- test begin ----------\n";
+echo "test select: multi keys select\n";
+test_select($tarantool, 0, 0, array(array(0), array(1), array(2)));
+echo "----------- test end -----------\n\n";
+
+echo "---------- test begin ----------\n";
+echo "test select: key is array of array of objects (expected error exception)\n";
+test_select($tarantool, 0, 0, array(array(1, $tarantool)));
+echo "----------- test end -----------\n\n";
+
+echo "---------- test begin ----------\n";
+echo "test select: key is array of diffirent elements (expected error exception)\n";
+test_select($tarantool, 0, 0, array(array(1, 2), 2));
+echo "----------- test end -----------\n\n";
+
+test_clean($tarantool, 0);
+?>
+===DONE===
+--EXPECT--
+---------- test begin ----------
+test select: key is integer
+result:
+count = 1
+tuple[0]:
+  id     = 0
+  series = Star Wars
+  year   = 1977
+  name   = A New Hope
+  crawl  = A long time ago, in a galaxy far, far away...
+It is a period of civil war. Rebel
+spaceships, striking from a hidden
+base, have won their first victory
+against the evil Galactic Empire.
+
+During the battle, Rebel spies managed
+to steal secret plans to the Empire's
+ultimate weapon, the Death Star, an
+armored space station with enough
+power to destroy an entire planet.
+
+Pursued by the Empire's sinister agents,
+Princess Leia races home aboard her
+starship, custodian of the stolen plans
+that can save her people and restore
+freedom to the galaxy....
+----------- test end -----------
+
+---------- test begin ----------
+test select: key is string 
+result:
+count = 3
+tuple[0]:
+  id     = 0
+  series = Star Wars
+  year   = 1977
+  name   = A New Hope
+  crawl  = A long time ago, in a galaxy far, far away...
+It is a period of civil war. Rebel
+spaceships, striking from a hidden
+base, have won their first victory
+against the evil Galactic Empire.
+
+During the battle, Rebel spies managed
+to steal secret plans to the Empire's
+ultimate weapon, the Death Star, an
+armored space station with enough
+power to destroy an entire planet.
+
+Pursued by the Empire's sinister agents,
+Princess Leia races home aboard her
+starship, custodian of the stolen plans
+that can save her people and restore
+freedom to the galaxy....
+tuple[1]:
+  id     = 1
+  series = Star Wars
+  year   = 1980
+  name   = The Empire Strikes Back
+  crawl  = It is a dark time for the
+Rebellion. Although the Death
+Star has been destroyed.
+Imperial troops have driven the
+Rebel forces from their hidden
+base and pursued them across
+the galaxy.
+
+Evading the dreaded Imperial
+Starfleet, a group of freedom
+fighters led by Luke Skywalker
+have established a new secret base
+on the remote ice world
+of Hoth.
+
+The evil lord Darth Vader,
+obsessed with finding young
+Skywalker, has dispatched
+thousands of remote probes
+into the far reaches of space....
+tuple[2]:
+  id     = 2
+  series = Star Wars
+  year   = 1983
+  name   = Return of the Jedi
+  crawl  = Luke Skywalker has returned
+to his home planet of
+Tatooine in an attempt
+to rescue his friend
+Han Solo from the
+clutches of the vile
+gangster Jabba the Hutt.
+
+Little does Luke know
+that the GALACTIC EMPIRE
+has secretly begun construction
+on a new armored space station
+even more powerful than the
+first dreaded Death Star.
+
+When completed, this ultimate
+weapon will spell certain
+doom for the small band of
+rebels struggling to restore
+freedom to the galaxy...
+----------- test end -----------
+
+---------- test begin ----------
+test select: key is object (expected error exception)
+catched exception: unsupported tuple type
+----------- test end -----------
+
+---------- test begin ----------
+test select: key is array
+result:
+count = 3
+tuple[0]:
+  id     = 0
+  series = Star Wars
+  year   = 1977
+  name   = A New Hope
+  crawl  = A long time ago, in a galaxy far, far away...
+It is a period of civil war. Rebel
+spaceships, striking from a hidden
+base, have won their first victory
+against the evil Galactic Empire.
+
+During the battle, Rebel spies managed
+to steal secret plans to the Empire's
+ultimate weapon, the Death Star, an
+armored space station with enough
+power to destroy an entire planet.
+
+Pursued by the Empire's sinister agents,
+Princess Leia races home aboard her
+starship, custodian of the stolen plans
+that can save her people and restore
+freedom to the galaxy....
+tuple[1]:
+  id     = 1
+  series = Star Wars
+  year   = 1980
+  name   = The Empire Strikes Back
+  crawl  = It is a dark time for the
+Rebellion. Although the Death
+Star has been destroyed.
+Imperial troops have driven the
+Rebel forces from their hidden
+base and pursued them across
+the galaxy.
+
+Evading the dreaded Imperial
+Starfleet, a group of freedom
+fighters led by Luke Skywalker
+have established a new secret base
+on the remote ice world
+of Hoth.
+
+The evil lord Darth Vader,
+obsessed with finding young
+Skywalker, has dispatched
+thousands of remote probes
+into the far reaches of space....
+tuple[2]:
+  id     = 2
+  series = Star Wars
+  year   = 1983
+  name   = Return of the Jedi
+  crawl  = Luke Skywalker has returned
+to his home planet of
+Tatooine in an attempt
+to rescue his friend
+Han Solo from the
+clutches of the vile
+gangster Jabba the Hutt.
+
+Little does Luke know
+that the GALACTIC EMPIRE
+has secretly begun construction
+on a new armored space station
+even more powerful than the
+first dreaded Death Star.
+
+When completed, this ultimate
+weapon will spell certain
+doom for the small band of
+rebels struggling to restore
+freedom to the galaxy...
+----------- test end -----------
+
+---------- test begin ----------
+test select: key is empty array (expected error exception)
+catched exception: invalid tuples list: empty array
+----------- test end -----------
+
+---------- test begin ----------
+test select: key is array of objects (expected error exception)
+catched exception: unsupported tuple type
+----------- test end -----------
+
+---------- test begin ----------
+test select: multi keys select
+result:
+count = 3
+tuple[0]:
+  id     = 0
+  series = Star Wars
+  year   = 1977
+  name   = A New Hope
+  crawl  = A long time ago, in a galaxy far, far away...
+It is a period of civil war. Rebel
+spaceships, striking from a hidden
+base, have won their first victory
+against the evil Galactic Empire.
+
+During the battle, Rebel spies managed
+to steal secret plans to the Empire's
+ultimate weapon, the Death Star, an
+armored space station with enough
+power to destroy an entire planet.
+
+Pursued by the Empire's sinister agents,
+Princess Leia races home aboard her
+starship, custodian of the stolen plans
+that can save her people and restore
+freedom to the galaxy....
+tuple[1]:
+  id     = 1
+  series = Star Wars
+  year   = 1980
+  name   = The Empire Strikes Back
+  crawl  = It is a dark time for the
+Rebellion. Although the Death
+Star has been destroyed.
+Imperial troops have driven the
+Rebel forces from their hidden
+base and pursued them across
+the galaxy.
+
+Evading the dreaded Imperial
+Starfleet, a group of freedom
+fighters led by Luke Skywalker
+have established a new secret base
+on the remote ice world
+of Hoth.
+
+The evil lord Darth Vader,
+obsessed with finding young
+Skywalker, has dispatched
+thousands of remote probes
+into the far reaches of space....
+tuple[2]:
+  id     = 2
+  series = Star Wars
+  year   = 1983
+  name   = Return of the Jedi
+  crawl  = Luke Skywalker has returned
+to his home planet of
+Tatooine in an attempt
+to rescue his friend
+Han Solo from the
+clutches of the vile
+gangster Jabba the Hutt.
+
+Little does Luke know
+that the GALACTIC EMPIRE
+has secretly begun construction
+on a new armored space station
+even more powerful than the
+first dreaded Death Star.
+
+When completed, this ultimate
+weapon will spell certain
+doom for the small band of
+rebels struggling to restore
+freedom to the galaxy...
+----------- test end -----------
+
+---------- test begin ----------
+test select: key is array of array of objects (expected error exception)
+catched exception: unsupported field type
+----------- test end -----------
+
+---------- test begin ----------
+test select: key is array of diffirent elements (expected error exception)
+catched exception: invalid tuples list: expected array of array
+----------- test end -----------
+
+===DONE===
\ No newline at end of file
diff --git a/connector/php/test/update_fields.phpt b/connector/php/test/update_fields.phpt
new file mode 100644
index 0000000000..a1a811efcd
--- /dev/null
+++ b/connector/php/test/update_fields.phpt
@@ -0,0 +1,96 @@
+--TEST--
+Tarantool/box update fields commands test
+--FILE--
+<?php
+include "lib/php/tarantool_utest.php";
+
+$tarantool = new Tarantool("localhost", 33013, 33015);
+test_init($tarantool, 0);
+
+echo "---------- test begin ----------\n";
+echo "test update fields: do update w/o operations (expected error exception)\n";
+test_update_fields($tarantool, 0, 0, array(), TARANTOOL_FLAGS_RETURN_TUPLE);
+echo "----------- test end -----------\n\n";
+
+echo "---------- test begin ----------\n";
+echo "test update fields: invalid operation list (expected error exception)\n";
+test_update_fields($tarantool, 0, 0, array($tarantool), TARANTOOL_FLAGS_RETURN_TUPLE);
+echo "----------- test end -----------\n\n";
+
+echo "---------- test begin ----------\n";
+echo "test update fields: do update arith operation\n";
+test_update_fields($tarantool, 0, 0,
+                   array(
+                       array(
+                           "field" => 2,
+                           "op" => TARANTOOL_OP_ADD,
+                           "arg" => 30,
+                           ),
+                       array(
+                           "field" => 0,
+                           "op" => TARANTOOL_OP_ASSIGN,
+                           "arg" => 5,
+                           ),
+                       array(
+                           "field" => 1,
+                           "op" => TARANTOOL_OP_ASSIGN,
+                           "arg" => "",
+                           ),
+                       array(
+                           "field" => 3,
+                           "op" => TARANTOOL_OP_ASSIGN,
+                           "arg" => "return",
+                           ),
+                       array(
+                           "field" => 4,
+                           "op" => TARANTOOL_OP_SPLICE,
+                           "offset" => 1,
+                           "length" => 64,
+                           "list" => " <<splice string>> ",
+                           ),
+                       ), TARANTOOL_FLAGS_RETURN_TUPLE);
+echo "----------- test end -----------\n\n";
+
+
+test_clean($tarantool, 0);
+?>
+--EXPECT--
+---------- test begin ----------
+test update fields: do update w/o operations (expected error exception)
+ops count = 0
+catched exception: update fields failed: 514
+----------- test end -----------
+
+---------- test begin ----------
+test update fields: invalid operation list (expected error exception)
+ops count = 1
+catched exception: invalid operations list
+----------- test end -----------
+
+---------- test begin ----------
+test update fields: do update arith operation
+ops count = 5
+result:
+count = 1
+tuple:
+  id     = 5
+  series = 
+  year   = 2007
+  name   = return
+  crawl  = A <<splice string>> ivil war. Rebel
+spaceships, striking from a hidden
+base, have won their first victory
+against the evil Galactic Empire.
+
+During the battle, Rebel spies managed
+to steal secret plans to the Empire's
+ultimate weapon, the Death Star, an
+armored space station with enough
+power to destroy an entire planet.
+
+Pursued by the Empire's sinister agents,
+Princess Leia races home aboard her
+starship, custodian of the stolen plans
+that can save her people and restore
+freedom to the galaxy....
+----------- test end -----------
\ No newline at end of file
-- 
GitLab