PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/mysqli - mysqli_api.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 675 718 94.0 %
Date: 2014-10-22 Functions: 81 83 97.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   +----------------------------------------------------------------------+
       3             :   | PHP Version 7                                                        |
       4             :   +----------------------------------------------------------------------+
       5             :   | Copyright (c) 1997-2014 The PHP Group                                |
       6             :   +----------------------------------------------------------------------+
       7             :   | This source file is subject to version 3.01 of the PHP license,      |
       8             :   | that is bundled with this package in the file LICENSE, and is        |
       9             :   | available through the world-wide-web at the following url:           |
      10             :   | http://www.php.net/license/3_01.txt                                  |
      11             :   | If you did not receive a copy of the PHP license and are unable to   |
      12             :   | obtain it through the world-wide-web, please send a note to          |
      13             :   | license@php.net so we can mail you a copy immediately.               |
      14             :   +----------------------------------------------------------------------+
      15             :   | Authors: Georg Richter <georg@php.net>                               |
      16             :   |          Andrey Hristov <andrey@php.net>                             |
      17             :   |          Ulf Wendel <uw@php.net>                                     |
      18             :   +----------------------------------------------------------------------+
      19             : 
      20             :   $Id$
      21             : */
      22             : 
      23             : #ifdef HAVE_CONFIG_H
      24             : #include "config.h"
      25             : #endif
      26             : 
      27             : #include <signal.h>
      28             : 
      29             : #include "php.h"
      30             : #include "php_ini.h"
      31             : #include "php_globals.h"
      32             : #include "ext/standard/info.h"
      33             : #include "zend_smart_str.h"
      34             : #include "php_mysqli_structs.h"
      35             : #include "mysqli_priv.h"
      36             : 
      37             : 
      38             : #if !defined(MYSQLI_USE_MYSQLND)
      39             : /* {{{ mysqli_tx_cor_options_to_string */
      40             : static void mysqli_tx_cor_options_to_string(const MYSQL * const conn, smart_str * str, const uint32_t mode)
      41             : {
      42             :         if (mode & TRANS_COR_AND_CHAIN && !(mode & TRANS_COR_AND_NO_CHAIN)) {
      43             :                 if (str->s && str->s->len) {
      44             :                         smart_str_appendl(str, " ", sizeof(" ") - 1);
      45             :                 }
      46             :                 smart_str_appendl(str, "AND CHAIN", sizeof("AND CHAIN") - 1);
      47             :         } else if (mode & TRANS_COR_AND_NO_CHAIN && !(mode & TRANS_COR_AND_CHAIN)) {
      48             :                 if (str->s && str->s->len) {
      49             :                         smart_str_appendl(str, " ", sizeof(" ") - 1);
      50             :                 }
      51             :                 smart_str_appendl(str, "AND NO CHAIN", sizeof("AND NO CHAIN") - 1);
      52             :         }
      53             : 
      54             :         if (mode & TRANS_COR_RELEASE && !(mode & TRANS_COR_NO_RELEASE)) {
      55             :                 if (str->s && str->s->len) {
      56             :                         smart_str_appendl(str, " ", sizeof(" ") - 1);
      57             :                 }
      58             :                 smart_str_appendl(str, "RELEASE", sizeof("RELEASE") - 1);
      59             :         } else if (mode & TRANS_COR_NO_RELEASE && !(mode & TRANS_COR_RELEASE)) {
      60             :                 if (str->s && str->s->len) {
      61             :                         smart_str_appendl(str, " ", sizeof(" ") - 1);
      62             :                 }
      63             :                 smart_str_appendl(str, "NO RELEASE", sizeof("NO RELEASE") - 1);
      64             :         }
      65             :         smart_str_0(str);
      66             : }
      67             : /* }}} */
      68             : 
      69             : /* {{{ mysqlnd_escape_string_for_tx_name_in_comment */
      70             : char *
      71             : mysqli_escape_string_for_tx_name_in_comment(const char * const name TSRMLS_DC)
      72             : {
      73             :         char * ret = NULL;
      74             :         if (name) {
      75             :                 zend_bool warned = FALSE;
      76             :                 const char * p_orig = name;
      77             :                 char * p_copy;
      78             :                 p_copy = ret = emalloc(strlen(name) + 1 + 2 + 2 + 1); /* space, open, close, NullS */
      79             :                 *p_copy++ = ' ';
      80             :                 *p_copy++ = '/';
      81             :                 *p_copy++ = '*';
      82             :                 while (1) {
      83             :                         register char v = *p_orig;
      84             :                         if (v == 0) {
      85             :                                 break;
      86             :                         }
      87             :                         if ((v >= '0' && v <= '9') ||
      88             :                                 (v >= 'a' && v <= 'z') ||
      89             :                                 (v >= 'A' && v <= 'Z') ||
      90             :                                 v == '-' ||
      91             :                                 v == '_' ||
      92             :                                 v == ' ' ||
      93             :                                 v == '=')
      94             :                         {
      95             :                                 *p_copy++ = v;
      96             :                         } else if (warned == FALSE) {
      97             :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Transaction name truncated. Must be only [0-9A-Za-z\\-_=]+");
      98             :                                 warned = TRUE;
      99             :                         }
     100             :                         ++p_orig;
     101             :                 }
     102             :                 *p_copy++ = '*';
     103             :                 *p_copy++ = '/';
     104             :                 *p_copy++ = 0;
     105             :         }
     106             :         return ret;
     107             : }
     108             : /* }}} */
     109             : 
     110             : /* {{{ mysqli_commit_or_rollback_libmysql */
     111             : static int mysqli_commit_or_rollback_libmysql(MYSQL * conn, zend_bool commit, const uint32_t mode, const char * const name TSRMLS_DC)
     112             : {
     113             :         int ret;
     114             :         smart_str tmp_str = {0};
     115             :         mysqli_tx_cor_options_to_string(conn, &tmp_str, mode);
     116             :         smart_str_0(&tmp_str);
     117             : 
     118             :         {
     119             :                 char *query;
     120             :                 char *name_esc = mysqli_escape_string_for_tx_name_in_comment(name TSRMLS_CC);
     121             :                 size_t query_len;
     122             : 
     123             :                 query_len = spprintf(&query, 0,
     124             :                                 (commit? "COMMIT%s %s":"ROLLBACK%s %s"), name_esc? name_esc:"", tmp_str.s? tmp_str.s->val:"");
     125             :                 smart_str_free(&tmp_str);
     126             :                 if (name_esc) {
     127             :                         efree(name_esc);
     128             :                         name_esc = NULL;
     129             :                 }
     130             : 
     131             :                 ret = mysql_real_query(conn, query, query_len);
     132             :                 efree(query);
     133             :         }
     134             :         return ret;
     135             : }
     136             : /* }}} */
     137             : #endif
     138             : 
     139             : /* {{{ proto mixed mysqli_affected_rows(object link)
     140             :    Get number of affected rows in previous MySQL operation */
     141          27 : PHP_FUNCTION(mysqli_affected_rows)
     142             : {
     143             :         MY_MYSQL                *mysql;
     144             :         zval                    *mysql_link;
     145             :         my_ulonglong    rc;
     146             : 
     147          27 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
     148           3 :                 return;
     149             :         }
     150             : 
     151          24 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     152             : 
     153          17 :         rc = mysql_affected_rows(mysql->mysql);
     154          17 :         if (rc == (my_ulonglong) -1) {
     155           1 :                 RETURN_LONG(-1);
     156             :         }
     157          16 :         MYSQLI_RETURN_LONG_INT(rc);
     158             : }
     159             : /* }}} */
     160             : 
     161             : /* {{{ proto bool mysqli_autocommit(object link, bool mode)
     162             :    Turn auto commit on or of */
     163          33 : PHP_FUNCTION(mysqli_autocommit)
     164             : {
     165             :         MY_MYSQL        *mysql;
     166             :         zval            *mysql_link;
     167             :         zend_bool       automode;
     168             : 
     169          33 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ob", &mysql_link, mysqli_link_class_entry, &automode) == FAILURE) {
     170           3 :                 return;
     171             :         }
     172          30 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     173             : 
     174          28 :         if (mysql_autocommit(mysql->mysql, (my_bool)automode)) {
     175           0 :                 RETURN_FALSE;
     176             :         }
     177          28 :         RETURN_TRUE;
     178             : }
     179             : /* }}} */
     180             : 
     181             : /* {{{ mysqli_stmt_bind_param_do_bind */
     182             : #ifndef MYSQLI_USE_MYSQLND
     183             : static
     184             : int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int argc, unsigned int num_vars,
     185             :                                                                    zval *args, unsigned int start, const char * const types TSRMLS_DC)
     186             : {
     187             :         int                             i, ofs;
     188             :         MYSQL_BIND              *bind;
     189             :         unsigned long   rc;
     190             : 
     191             :         /* prevent leak if variables are already bound */
     192             :         if (stmt->param.var_cnt) {
     193             :                 php_free_stmt_bind_buffer(stmt->param, FETCH_SIMPLE);
     194             :         }
     195             : 
     196             :         stmt->param.is_null = ecalloc(num_vars, sizeof(char));
     197             :         bind = (MYSQL_BIND *) ecalloc(num_vars, sizeof(MYSQL_BIND));
     198             : 
     199             :         ofs = 0;
     200             :         for (i = start; i < argc; i++) {
     201             :                 zval *param;
     202             :                 if (Z_ISREF(args[i])) {
     203             :                         param = Z_REFVAL(args[i]);
     204             :                 } else {
     205             :                         param = &args[i];
     206             :                 }
     207             :                 /* set specified type */
     208             :                 switch (types[ofs]) {
     209             :                         case 'd': /* Double */
     210             :                                 bind[ofs].buffer_type = MYSQL_TYPE_DOUBLE;
     211             :                                 bind[ofs].buffer = &Z_DVAL_P(param);
     212             :                                 bind[ofs].is_null = &stmt->param.is_null[ofs];
     213             :                                 break;
     214             : 
     215             :                         case 'i': /* Integer */
     216             : #if SIZEOF_ZEND_LONG==8
     217             :                                 bind[ofs].buffer_type = MYSQL_TYPE_LONGLONG;
     218             : #elif SIZEOF_ZEND_LONG==4
     219             :                                 bind[ofs].buffer_type = MYSQL_TYPE_LONG;
     220             : #endif
     221             :                                 bind[ofs].buffer = &Z_LVAL_P(param);
     222             :                                 bind[ofs].is_null = &stmt->param.is_null[ofs];
     223             :                                 break;
     224             : 
     225             :                         case 'b': /* Blob (send data) */
     226             :                                 bind[ofs].buffer_type = MYSQL_TYPE_LONG_BLOB;
     227             :                                 /* don't initialize is_null and length to 0 because we use ecalloc */
     228             :                                 break;
     229             : 
     230             :                         case 's': /* string */
     231             :                                 bind[ofs].buffer_type = MYSQL_TYPE_VAR_STRING;
     232             :                                 /* don't initialize buffer and buffer_length because we use ecalloc */
     233             :                                 bind[ofs].is_null = &stmt->param.is_null[ofs];
     234             :                                 break;
     235             : 
     236             :                         default:
     237             :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Undefined fieldtype %c (parameter %d)", types[ofs], i+1);
     238             :                                 rc = 1;
     239             :                                 goto end_1;
     240             :                 }
     241             :                 ofs++;
     242             :         }
     243             :         rc = mysql_stmt_bind_param(stmt->stmt, bind);
     244             : 
     245             : end_1:
     246             :         if (rc) {
     247             :                 efree(stmt->param.is_null);
     248             :         } else {
     249             :                 stmt->param.var_cnt = num_vars;
     250             :                 stmt->param.vars = safe_emalloc(num_vars, sizeof(zval), 0);
     251             :                 for (i = 0; i < num_vars; i++) {
     252             :                         if (bind[i].buffer_type != MYSQL_TYPE_LONG_BLOB) {
     253             :                                 ZVAL_COPY(&stmt->param.vars[i], &args[i+start]);
     254             :                         } else {
     255             :                                 ZVAL_UNDEF(&stmt->param.vars[i]);
     256             :                         }
     257             :                 }
     258             :         }
     259             :         efree(bind);
     260             : 
     261             :         return rc;
     262             : }
     263             : #else
     264             : static
     265       20879 : int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int argc, unsigned int num_vars,
     266             :                                                                    zval *args, unsigned int start, const char * const types TSRMLS_DC)
     267             : {
     268             :         unsigned int i;
     269             :         MYSQLND_PARAM_BIND      *params;
     270       20879 :         enum_func_status        ret = FAIL;
     271             : 
     272             :         /* If no params -> skip binding and return directly */
     273       20879 :         if (argc == start) {
     274           0 :                 return PASS;
     275             :         }
     276       20879 :         params = mysqlnd_stmt_alloc_param_bind(stmt->stmt);
     277       20879 :         if (!params) {
     278           0 :                 goto end;
     279             :         }
     280      195680 :         for (i = 0; i < (argc - start); i++) {
     281             :                 zend_uchar type;
     282      174803 :                 switch (types[i]) {
     283             :                         case 'd': /* Double */
     284         976 :                                 type = MYSQL_TYPE_DOUBLE;
     285         976 :                                 break;
     286             :                         case 'i': /* Integer */
     287             : #if SIZEOF_ZEND_LONG==8
     288      153547 :                                 type = MYSQL_TYPE_LONGLONG;
     289             : #elif SIZEOF_ZEND_LONG==4
     290             :                                 type = MYSQL_TYPE_LONG;
     291             : #endif
     292      153547 :                                 break;
     293             :                         case 'b': /* Blob (send data) */
     294          24 :                                 type = MYSQL_TYPE_LONG_BLOB;
     295          24 :                                 break;
     296             :                         case 's': /* string */
     297       20254 :                                 type = MYSQL_TYPE_VAR_STRING;
     298       20254 :                                 break;
     299             :                         default:
     300             :                                 /* We count parameters from 1 */
     301           2 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Undefined fieldtype %c (parameter %d)", types[i], i + start + 1);
     302           2 :                                 ret = FAIL;
     303           2 :                                 mysqlnd_stmt_free_param_bind(stmt->stmt, params);
     304           2 :                                 goto end;
     305             :                 }
     306      174801 :                 ZVAL_COPY_VALUE(&params[i].zv, &args[i + start]);
     307      174801 :                 params[i].type = type;
     308             :         }
     309       20877 :         ret = mysqlnd_stmt_bind_param(stmt->stmt, params);
     310             : 
     311             : end:
     312       20879 :         return ret;
     313             : }
     314             : #endif
     315             : /* }}} */
     316             : 
     317             : /* {{{ proto bool mysqli_stmt_bind_param(object stmt, string types, mixed variable [,mixed,....]) U
     318             :    Bind variables to a prepared statement as parameters */
     319       20890 : PHP_FUNCTION(mysqli_stmt_bind_param)
     320             : {
     321             :         zval                    *args;
     322       20890 :         int                             argc = ZEND_NUM_ARGS();
     323             :         int                             num_vars;
     324       20890 :         int                             start = 2;
     325             :         MY_STMT                 *stmt;
     326             :         zval                    *mysql_stmt;
     327             :         char                    *types;
     328             :         size_t                  types_len;
     329             :         zend_ulong      rc;
     330             : 
     331             :         /* calculate and check number of parameters */
     332       20890 :         if (argc < 2) {
     333             :                 /* there has to be at least one pair */
     334           3 :                 WRONG_PARAM_COUNT;
     335             :         }
     336             : 
     337       20887 :         if (zend_parse_method_parameters((getThis()) ? 1:2 TSRMLS_CC, getThis(), "Os", &mysql_stmt, mysqli_stmt_class_entry,
     338             :                                                                         &types, &types_len) == FAILURE) {
     339           1 :                 return;
     340             :         }
     341             : 
     342       20886 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
     343             : 
     344       20886 :         num_vars = argc - 1;
     345       20910 :         if (getThis()) {
     346          24 :                 start = 1;
     347             :         } else {
     348             :                 /* ignore handle parameter in procedural interface*/
     349       20862 :                 --num_vars;
     350             :         }
     351       20886 :         if (!types_len) {
     352           1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid type or no types specified");
     353           1 :                 RETURN_FALSE;
     354             :         }
     355             : 
     356       20885 :         if (types_len != argc - start) {
     357             :                 /* number of bind variables doesn't match number of elements in type definition string */
     358           3 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of elements in type definition string doesn't match number of bind variables");
     359           3 :                 RETURN_FALSE;
     360             :         }
     361             : 
     362       20882 :         if (types_len != mysql_stmt_param_count(stmt->stmt)) {
     363           3 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of variables doesn't match number of parameters in prepared statement");
     364           3 :                 RETURN_FALSE;
     365             :         }
     366             : 
     367       20879 :         args = safe_emalloc(argc, sizeof(zval), 0);
     368             : 
     369       20879 :         if (zend_get_parameters_array_ex(argc, args) == FAILURE) {
     370           0 :                 zend_wrong_param_count(TSRMLS_C);
     371           0 :                 rc = 1;
     372             :         } else {
     373       20879 :                 rc = mysqli_stmt_bind_param_do_bind(stmt, argc, num_vars, args, start, types TSRMLS_CC);
     374       20879 :                 MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
     375             :         }
     376             : 
     377       20879 :         efree(args);
     378             : 
     379       20879 :         RETURN_BOOL(!rc);
     380             : }
     381             : /* }}} */
     382             : 
     383             : /* {{{ mysqli_stmt_bind_result_do_bind */
     384             : #ifndef MYSQLI_USE_MYSQLND
     385             : /* TODO:
     386             :    do_alloca, free_alloca
     387             : */
     388             : static int
     389             : mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval *args, unsigned int argc, unsigned int start TSRMLS_DC)
     390             : {
     391             :         MYSQL_BIND      *bind;
     392             :         int                     i, ofs;
     393             :         int                     var_cnt = argc - start;
     394             :         zend_long               col_type;
     395             :         zend_ulong              rc;
     396             : 
     397             :         /* prevent leak if variables are already bound */
     398             :         if (stmt->result.var_cnt) {
     399             :                 php_free_stmt_bind_buffer(stmt->result, FETCH_RESULT);
     400             :         }
     401             : 
     402             :         bind = (MYSQL_BIND *)ecalloc(var_cnt, sizeof(MYSQL_BIND));
     403             :         {
     404             :                 int size;
     405             :                 char *p = emalloc(size= var_cnt * (sizeof(char) + sizeof(VAR_BUFFER)));
     406             :                 stmt->result.buf = (VAR_BUFFER *) p;
     407             :                 stmt->result.is_null = p + var_cnt * sizeof(VAR_BUFFER);
     408             :                 memset(p, 0, size);
     409             :         }
     410             : 
     411             :         for (i=start; i < var_cnt + start ; i++) {
     412             :                 ofs = i - start;
     413             :                 col_type = (stmt->stmt->fields) ? stmt->stmt->fields[ofs].type : MYSQL_TYPE_STRING;
     414             : 
     415             :                 switch (col_type) {
     416             :                         case MYSQL_TYPE_DOUBLE:
     417             :                         case MYSQL_TYPE_FLOAT:
     418             :                                 stmt->result.buf[ofs].type = IS_DOUBLE;
     419             :                                 stmt->result.buf[ofs].buflen = sizeof(double);
     420             : 
     421             :                                 /* allocate buffer for double */
     422             :                                 stmt->result.buf[ofs].val = (char *)emalloc(sizeof(double));
     423             :                                 bind[ofs].buffer_type = MYSQL_TYPE_DOUBLE;
     424             :                                 bind[ofs].buffer = stmt->result.buf[ofs].val;
     425             :                                 bind[ofs].is_null = &stmt->result.is_null[ofs];
     426             :                                 break;
     427             : 
     428             :                         case MYSQL_TYPE_NULL:
     429             :                                 stmt->result.buf[ofs].type = IS_NULL;
     430             :                                 /*
     431             :                                   don't initialize to 0 :
     432             :                                   1. stmt->result.buf[ofs].buflen
     433             :                                   2. bind[ofs].buffer
     434             :                                   3. bind[ofs].buffer_length
     435             :                                   because memory was allocated with ecalloc
     436             :                                 */
     437             :                                 bind[ofs].buffer_type = MYSQL_TYPE_NULL;
     438             :                                 bind[ofs].is_null = &stmt->result.is_null[ofs];
     439             :                                 break;
     440             : 
     441             :                         case MYSQL_TYPE_SHORT:
     442             :                         case MYSQL_TYPE_TINY:
     443             :                         case MYSQL_TYPE_LONG:
     444             :                         case MYSQL_TYPE_INT24:
     445             :                         case MYSQL_TYPE_YEAR:
     446             :                                 stmt->result.buf[ofs].type = IS_LONG;
     447             :                                 /* don't set stmt->result.buf[ofs].buflen to 0, we used ecalloc */
     448             :                                 stmt->result.buf[ofs].val = (char *)emalloc(sizeof(int));
     449             :                                 bind[ofs].buffer_type = MYSQL_TYPE_LONG;
     450             :                                 bind[ofs].buffer = stmt->result.buf[ofs].val;
     451             :                                 bind[ofs].is_null = &stmt->result.is_null[ofs];
     452             :                                 bind[ofs].is_unsigned = (stmt->stmt->fields[ofs].flags & UNSIGNED_FLAG) ? 1 : 0;
     453             :                                 break;
     454             : 
     455             :                         case MYSQL_TYPE_LONGLONG:
     456             : #if MYSQL_VERSION_ID > 50002 || defined(MYSQLI_USE_MYSQLND)
     457             :                         case MYSQL_TYPE_BIT:
     458             : #endif
     459             :                                 stmt->result.buf[ofs].type = IS_STRING;
     460             :                                 stmt->result.buf[ofs].buflen = sizeof(my_ulonglong);
     461             :                                 stmt->result.buf[ofs].val = (char *)emalloc(stmt->result.buf[ofs].buflen);
     462             :                                 bind[ofs].buffer_type = col_type;
     463             :                                 bind[ofs].buffer = stmt->result.buf[ofs].val;
     464             :                                 bind[ofs].is_null = &stmt->result.is_null[ofs];
     465             :                                 bind[ofs].buffer_length = stmt->result.buf[ofs].buflen;
     466             :                                 bind[ofs].is_unsigned = (stmt->stmt->fields[ofs].flags & UNSIGNED_FLAG) ? 1 : 0;
     467             :                                 bind[ofs].length = &stmt->result.buf[ofs].output_len;
     468             :                                 break;
     469             : 
     470             :                         case MYSQL_TYPE_DATE:
     471             :                         case MYSQL_TYPE_TIME:
     472             :                         case MYSQL_TYPE_DATETIME:
     473             :                         case MYSQL_TYPE_NEWDATE:
     474             :                         case MYSQL_TYPE_VAR_STRING:
     475             :                         case MYSQL_TYPE_STRING:
     476             :                         case MYSQL_TYPE_TINY_BLOB:
     477             :                         case MYSQL_TYPE_BLOB:
     478             :                         case MYSQL_TYPE_MEDIUM_BLOB:
     479             :                         case MYSQL_TYPE_LONG_BLOB:
     480             :                         case MYSQL_TYPE_TIMESTAMP:
     481             :                         case MYSQL_TYPE_DECIMAL:
     482             :                         case MYSQL_TYPE_GEOMETRY:
     483             : #ifdef FIELD_TYPE_NEWDECIMAL
     484             :                         case MYSQL_TYPE_NEWDECIMAL:
     485             : #endif
     486             :                         {
     487             : #if MYSQL_VERSION_ID >= 50107
     488             :                                 /* Changed to my_bool in MySQL 5.1. See MySQL Bug #16144 */
     489             :                                 my_bool tmp;
     490             : #else
     491             :                                 zend_ulong tmp = 0;
     492             : #endif
     493             :                                 stmt->result.buf[ofs].type = IS_STRING;
     494             :                                 /*
     495             :                                         If the user has called $stmt->store_result() then we have asked
     496             :                                         max_length to be updated. this is done only for BLOBS because we don't want to allocate
     497             :                                         big chunkgs of memory 2^16 or 2^24
     498             :                                 */
     499             :                                 if (stmt->stmt->fields[ofs].max_length == 0 &&
     500             :                                         !mysql_stmt_attr_get(stmt->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &tmp) && !tmp)
     501             :                                 {
     502             :                                         /*
     503             :                                           Allocate directly 256 because it's easier to allocate a bit more
     504             :                                           than update max length even for text columns. Try SELECT UNION SELECT UNION with
     505             :                                           different lengths and you will see that we get different lengths in stmt->stmt->fields[ofs].length
     506             :                                           The just take 256 and saves us from realloc-ing.
     507             :                                         */
     508             :                                         stmt->result.buf[ofs].buflen =
     509             :                                                 (stmt->stmt->fields) ? (stmt->stmt->fields[ofs].length) ? stmt->stmt->fields[ofs].length + 1: 256: 256;
     510             : 
     511             :                                 } else {
     512             :                                         /*
     513             :                                                 the user has called store_result(). if he does not there is no way to determine the
     514             :                                                 libmysql does not allow us to allocate 0 bytes for a buffer so we try 1
     515             :                                         */
     516             :                                         if (!(stmt->result.buf[ofs].buflen = stmt->stmt->fields[ofs].max_length))
     517             :                                                 ++stmt->result.buf[ofs].buflen;
     518             :                                 }
     519             :                                 stmt->result.buf[ofs].val = (char *)emalloc(stmt->result.buf[ofs].buflen);
     520             :                                 bind[ofs].buffer_type = MYSQL_TYPE_STRING;
     521             :                                 bind[ofs].buffer = stmt->result.buf[ofs].val;
     522             :                                 bind[ofs].is_null = &stmt->result.is_null[ofs];
     523             :                                 bind[ofs].buffer_length = stmt->result.buf[ofs].buflen;
     524             :                                 bind[ofs].length = &stmt->result.buf[ofs].output_len;
     525             :                                 break;
     526             :                         }
     527             :                         default:
     528             :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Server returned unknown type %ld. Probably your client library is incompatible with the server version you use!", col_type);
     529             :                                 break;
     530             :                 }
     531             :         }
     532             : 
     533             :         rc = mysql_stmt_bind_result(stmt->stmt, bind);
     534             :         MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
     535             : 
     536             :         if (rc) {
     537             :                 /* dont close the statement or subsequent usage (for example ->execute()) will lead to crash */
     538             :                 for (i=0; i < var_cnt ; i++) {
     539             :                         if (stmt->result.buf[i].val) {
     540             :                                 efree(stmt->result.buf[i].val);
     541             :                         }
     542             :                 }
     543             :                 /* Don't free stmt->result.is_null because is_null & buf are one block of memory  */
     544             :                 efree(stmt->result.buf);
     545             :         } else {
     546             :                 stmt->result.var_cnt = var_cnt;
     547             :                 stmt->result.vars = safe_emalloc((var_cnt), sizeof(zval), 0);
     548             :                 for (i = start; i < var_cnt+start; i++) {
     549             :                         ofs = i-start;
     550             :                         ZVAL_COPY(&stmt->result.vars[ofs], &args[i]);
     551             :                 }
     552             :         }
     553             :         efree(bind);
     554             : 
     555             :         return rc;
     556             : }
     557             : #else
     558             : static int
     559        1269 : mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval *args, unsigned int argc, unsigned int start TSRMLS_DC)
     560             : {
     561             :         unsigned int i;
     562        1269 :         MYSQLND_RESULT_BIND *params = mysqlnd_stmt_alloc_result_bind(stmt->stmt);
     563        1269 :         if (params) {
     564        6791 :                 for (i = 0; i < (argc - start); i++) {
     565        5522 :                         ZVAL_COPY_VALUE(&params[i].zv, &args[i + start]);
     566             :                 }
     567        1269 :                 return mysqlnd_stmt_bind_result(stmt->stmt, params);
     568             :         }
     569           0 :         return FAIL;
     570             : }
     571             : #endif
     572             : /* }}} */
     573             : 
     574             : /* {{{ proto bool mysqli_stmt_bind_result(object stmt, mixed var, [,mixed, ...]) U
     575             :    Bind variables to a prepared statement for result storage */
     576        1277 : PHP_FUNCTION(mysqli_stmt_bind_result)
     577             : {
     578             :         zval            *args;
     579        1277 :         int                     argc = ZEND_NUM_ARGS();
     580        1277 :         int                     start = 1;
     581             :         zend_ulong              rc;
     582             :         MY_STMT         *stmt;
     583             :         zval            *mysql_stmt;
     584             : 
     585        1277 :         if (getThis()) {
     586          43 :                 start = 0;
     587             :         }
     588             : 
     589        1277 :         if (zend_parse_method_parameters((getThis()) ? 0:1 TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
     590           3 :                 return;
     591             :         }
     592             : 
     593        1274 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
     594             : 
     595        1273 :         if (argc < (getThis() ? 1 : 2)) {
     596           1 :                 WRONG_PARAM_COUNT;
     597             :         }
     598             : 
     599        1272 :         if ((argc - start) != mysql_stmt_field_count(stmt->stmt)) {
     600           3 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of bind variables doesn't match number of fields in prepared statement");
     601           3 :                 RETURN_FALSE;
     602             :         }
     603             : 
     604        1269 :         args = safe_emalloc(argc, sizeof(zval), 0);
     605             : 
     606        1269 :         if (zend_get_parameters_array_ex(argc, args) == FAILURE) {
     607           0 :                 efree(args);
     608           0 :                 WRONG_PARAM_COUNT;
     609             :         }
     610             : 
     611        1269 :         rc = mysqli_stmt_bind_result_do_bind(stmt, args, argc, start TSRMLS_CC);
     612             : 
     613        1269 :         efree(args);
     614             : 
     615        1269 :         RETURN_BOOL(!rc);
     616             : }
     617             : /* }}} */
     618             : 
     619             : /* {{{ proto bool mysqli_change_user(object link, string user, string password, string database)
     620             :    Change logged-in user of the active connection */
     621          42 : PHP_FUNCTION(mysqli_change_user)
     622             : {
     623             :         MY_MYSQL        *mysql;
     624          42 :         zval            *mysql_link = NULL;
     625             :         char            *user, *password, *dbname;
     626             :         size_t                  user_len, password_len, dbname_len;
     627             :         zend_ulong              rc;
     628             : #if !defined(MYSQLI_USE_MYSQLND) && defined(HAVE_MYSQLI_SET_CHARSET)
     629             :         const           CHARSET_INFO * old_charset;
     630             : #endif
     631             : 
     632          42 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Osss", &mysql_link, mysqli_link_class_entry, &user, &user_len, &password, &password_len, &dbname, &dbname_len) == FAILURE) {
     633          14 :                 return;
     634             :         }
     635          28 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     636             : 
     637             : #if !defined(MYSQLI_USE_MYSQLND) && defined(HAVE_MYSQLI_SET_CHARSET)
     638             :         old_charset = mysql->mysql->charset;
     639             : #endif
     640             : 
     641             : #if defined(MYSQLI_USE_MYSQLND)
     642          25 :         rc = mysqlnd_change_user_ex(mysql->mysql, user, password, dbname, FALSE, (size_t) password_len);
     643             : #else
     644             :         rc = mysql_change_user(mysql->mysql, user, password, dbname);
     645             : #endif
     646          25 :         MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
     647             : 
     648          25 :         if (rc) {
     649          14 :                 RETURN_FALSE;
     650             :         }
     651             : #if !defined(MYSQLI_USE_MYSQLND) && defined(HAVE_MYSQLI_SET_CHARSET)
     652             :         if (mysql_get_server_version(mysql->mysql) < 501023L) {
     653             :                 /*
     654             :                   Request the current charset, or it will be reset to the system one.
     655             :                   5.0 doesn't support it. Support added in 5.1.23 by fixing the following bug :
     656             :                   Bug #30472 libmysql doesn't reset charset, insert_id after succ. mysql_change_user() call
     657             :                 */
     658             :                 rc = mysql_set_character_set(mysql->mysql, old_charset->csname);
     659             :         }
     660             : #endif
     661             : 
     662          11 :         RETURN_TRUE;
     663             : }
     664             : /* }}} */
     665             : 
     666             : /* {{{ proto string mysqli_character_set_name(object link)
     667             :    Returns the name of the character set used for this connection */
     668          18 : PHP_FUNCTION(mysqli_character_set_name)
     669             : {
     670             :         MY_MYSQL        *mysql;
     671             :         zval            *mysql_link;
     672             :         const char      *cs_name;
     673             : 
     674          18 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
     675           5 :                 return;
     676             :         }
     677             : 
     678          13 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     679          10 :         cs_name = mysql_character_set_name(mysql->mysql);
     680          10 :         if (cs_name) {
     681          20 :                 RETURN_STRING(cs_name);
     682             :         }
     683             : }
     684             : /* }}} */
     685             : 
     686             : /* {{{ php_mysqli_close */
     687        1249 : void php_mysqli_close(MY_MYSQL * mysql, int close_type, int resource_status TSRMLS_DC)
     688             : {
     689        1249 :         if (resource_status > MYSQLI_STATUS_INITIALIZED) {
     690        1209 :                 MyG(num_links)--;
     691             :         }
     692             : 
     693        1249 :         if (!mysql->persistent) {
     694        1164 :                 mysqli_close(mysql->mysql, close_type);
     695             :         } else {
     696             :                 zend_resource *le;
     697         170 :                 if ((le = zend_hash_find_ptr(&EG(persistent_list), mysql->hash_key)) != NULL) {
     698          85 :                         if (le->type == php_le_pmysqli()) {
     699          85 :                                 mysqli_plist_entry *plist = (mysqli_plist_entry *) le->ptr;
     700             : #if defined(MYSQLI_USE_MYSQLND)
     701          85 :                                 mysqlnd_end_psession(mysql->mysql);
     702             : #endif
     703             : 
     704          87 :                                 if (MyG(rollback_on_cached_plink) &&
     705             : #if !defined(MYSQLI_USE_MYSQLND)
     706             :                                         mysqli_commit_or_rollback_libmysql(mysql->mysql, FALSE, TRANS_COR_NO_OPT, NULL TSRMLS_CC))
     707             : #else
     708           2 :                                         FAIL == mysqlnd_rollback(mysql->mysql, TRANS_COR_NO_OPT, NULL))
     709             : #endif
     710             :                                 {
     711           0 :                                         mysqli_close(mysql->mysql, close_type);                      
     712             :                                 } else {
     713          85 :                                         zend_ptr_stack_push(&plist->free_links, mysql->mysql);
     714          85 :                                         MyG(num_inactive_persistent)++;
     715             :                                 }
     716          85 :                                 MyG(num_active_persistent)--;
     717             :                         }
     718             :                 }
     719          85 :                 mysql->persistent = FALSE;
     720             :         }
     721        1249 :         mysql->mysql = NULL;
     722             : 
     723        1249 :         php_clear_mysql(mysql);
     724        1249 : }
     725             : /* }}} */
     726             : 
     727             : /* {{{ proto bool mysqli_close(object link)
     728             :    Close connection */
     729        1059 : PHP_FUNCTION(mysqli_close)
     730             : {
     731             :         zval            *mysql_link;
     732             :         MY_MYSQL        *mysql;
     733             : 
     734        1059 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
     735           9 :                 return;
     736             :         }
     737             : 
     738        1050 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_INITIALIZED);
     739             : 
     740        1048 :         php_mysqli_close(mysql, MYSQLI_CLOSE_EXPLICIT, ((MYSQLI_RESOURCE *)(Z_MYSQLI_P(mysql_link))->ptr)->status TSRMLS_CC);
     741        1048 :         ((MYSQLI_RESOURCE *)(Z_MYSQLI_P(mysql_link))->ptr)->status = MYSQLI_STATUS_UNKNOWN;
     742             : 
     743        1048 :         MYSQLI_CLEAR_RESOURCE(mysql_link);
     744        1048 :         efree(mysql);
     745        1048 :         RETURN_TRUE;
     746             : }
     747             : /* }}} */
     748             : 
     749             : /* {{{ proto bool mysqli_commit(object link[, int flags [, string name ]])
     750             :    Commit outstanding actions and close transaction */
     751          18 : PHP_FUNCTION(mysqli_commit)
     752             : {
     753             :         MY_MYSQL        *mysql;
     754             :         zval            *mysql_link;
     755          18 :         zend_long               flags = TRANS_COR_NO_OPT;
     756          18 :         char *          name = NULL;
     757          18 :         size_t                  name_len = 0;
     758             : 
     759          18 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|ls", &mysql_link, mysqli_link_class_entry, &flags, &name, &name_len) == FAILURE) {
     760           3 :                 return;
     761             :         }
     762          15 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     763             : 
     764             : #if !defined(MYSQLI_USE_MYSQLND)
     765             :         if (mysqli_commit_or_rollback_libmysql(mysql->mysql, TRUE, flags, name TSRMLS_CC)) {
     766             : #else
     767          12 :         if (FAIL == mysqlnd_commit(mysql->mysql, flags, name)) {
     768             : #endif
     769           0 :                 RETURN_FALSE;
     770             :         }
     771          12 :         RETURN_TRUE;
     772             : }
     773             : /* }}} */
     774             : 
     775             : /* {{{ proto bool mysqli_data_seek(object result, int offset)
     776             :    Move internal result pointer */
     777        1135 : PHP_FUNCTION(mysqli_data_seek)
     778             : {
     779             :         MYSQL_RES       *result;
     780             :         zval            *mysql_result;
     781             :         zend_long               offset;
     782             : 
     783        1135 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_result, mysqli_result_class_entry, &offset) == FAILURE) {
     784           6 :                 return;
     785             :         }
     786             : 
     787        1129 :         MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
     788             : 
     789        1124 :         if (mysqli_result_is_unbuffered(result)) {
     790           3 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function cannot be used with MYSQL_USE_RESULT");
     791           3 :                 RETURN_FALSE;
     792             :         }
     793             : 
     794        1121 :         if (offset < 0 || (uint64_t)offset >= mysql_num_rows(result)) {
     795        1029 :                 RETURN_FALSE;
     796             :         }
     797             : 
     798          92 :         mysql_data_seek(result, offset);
     799          92 :         RETURN_TRUE;
     800             : }
     801             : /* }}} */
     802             : 
     803             : /* {{{ proto void mysqli_debug(string debug) U
     804             : */
     805           0 : PHP_FUNCTION(mysqli_debug)
     806             : {
     807             :         char    *debug;
     808             :         size_t          debug_len;
     809             : 
     810           0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &debug, &debug_len) == FAILURE) {
     811           0 :                 return;
     812             :         }
     813             : 
     814           0 :         mysql_debug(debug);
     815           0 :         RETURN_TRUE;
     816             : }
     817             : /* }}} */
     818             : 
     819             : /* {{{ proto bool mysqli_dump_debug_info(object link)
     820             : */
     821           7 : PHP_FUNCTION(mysqli_dump_debug_info)
     822             : {
     823             :         MY_MYSQL        *mysql;
     824             :         zval            *mysql_link;
     825             : 
     826           7 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
     827           3 :                 return;
     828             :         }
     829           4 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     830             : 
     831           2 :         RETURN_BOOL(!mysql_dump_debug_info(mysql->mysql))
     832             : }
     833             : /* }}} */
     834             : 
     835             : /* {{{ proto int mysqli_errno(object link)
     836             :    Returns the numerical value of the error message from previous MySQL operation */
     837          73 : PHP_FUNCTION(mysqli_errno)
     838             : {
     839             :         MY_MYSQL        *mysql;
     840             :         zval            *mysql_link;
     841             : 
     842          73 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
     843           5 :                 return;
     844             :         }
     845          68 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     846          61 :         RETURN_LONG(mysql_errno(mysql->mysql));
     847             : }
     848             : /* }}} */
     849             : 
     850             : /* {{{ proto string mysqli_error(object link)
     851             :    Returns the text of the error message from previous MySQL operation */
     852          56 : PHP_FUNCTION(mysqli_error)
     853             : {
     854             :         MY_MYSQL        *mysql;
     855             :         zval            *mysql_link;
     856             :         const char      *err;
     857             : 
     858          56 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
     859           7 :                 return;
     860             :         }
     861          49 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     862          41 :         err = mysql_error(mysql->mysql);
     863          41 :         if (err) {
     864          82 :                 RETURN_STRING(err);
     865             :         }
     866             : }
     867             : /* }}} */
     868             : 
     869             : /* {{{ proto bool mysqli_stmt_execute(object stmt)
     870             :    Execute a prepared statement */
     871        4171 : PHP_FUNCTION(mysqli_stmt_execute)
     872             : {
     873             :         MY_STMT         *stmt;
     874             :         zval            *mysql_stmt;
     875             : #ifndef MYSQLI_USE_MYSQLND
     876             :         unsigned int    i;
     877             : #endif
     878             : 
     879        4171 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
     880           2 :                 return;
     881             :         }
     882        4169 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
     883             : 
     884             : #ifndef MYSQLI_USE_MYSQLND
     885             :         if (stmt->param.var_cnt) {
     886             :                 int j;
     887             :                 for (i = 0; i < stmt->param.var_cnt; i++) {
     888             :                         if (!Z_ISREF(stmt->param.vars[i])) {
     889             :                                 continue;
     890             :                         }
     891             :                         for (j = i + 1; j < stmt->param.var_cnt; j++) {
     892             :                                 /* Oops, someone binding the same variable - clone */
     893             :                                 if (Z_TYPE(stmt->param.vars[j]) == Z_TYPE(stmt->param.vars[i]) &&
     894             :                                                 Z_REFVAL(stmt->param.vars[j]) == Z_REFVAL(stmt->param.vars[i])) {
     895             :                                         SEPARATE_ZVAL(&stmt->param.vars[j]);
     896             :                                         break;
     897             :                                 }
     898             :                         }
     899             :                 }
     900             :         }
     901             :         for (i = 0; i < stmt->param.var_cnt; i++) {
     902             :                 if (!Z_ISUNDEF(stmt->param.vars[i])) {
     903             :                         zval *param;
     904             :                         if (Z_ISREF(stmt->param.vars[i])) {
     905             :                                 param = Z_REFVAL(stmt->param.vars[i]);
     906             :                         } else {
     907             :                                 param = &stmt->param.vars[i];
     908             :                         }
     909             :                         if (!(stmt->param.is_null[i] = (Z_ISNULL_P(param)))) {
     910             :                                 switch (stmt->stmt->params[i].buffer_type) {
     911             :                                         case MYSQL_TYPE_VAR_STRING:
     912             :                                                 convert_to_string_ex(param);
     913             :                                                 stmt->stmt->params[i].buffer = Z_STRVAL_P(param);
     914             :                                                 stmt->stmt->params[i].buffer_length = Z_STRLEN_P(param);
     915             :                                                 break;
     916             :                                         case MYSQL_TYPE_DOUBLE:
     917             :                                                 convert_to_double_ex(param);
     918             :                                                 stmt->stmt->params[i].buffer = &Z_DVAL_P(param);
     919             :                                                 break;
     920             :                                         case MYSQL_TYPE_LONGLONG:
     921             :                                         case MYSQL_TYPE_LONG:
     922             :                                                 convert_to_long_ex(param);
     923             :                                                 stmt->stmt->params[i].buffer = &Z_LVAL_P(param);
     924             :                                                 break;
     925             :                                         default:
     926             :                                                 break;
     927             :                                 }
     928             :                         }
     929             :                 }
     930             :         }
     931             : #endif
     932             : 
     933        4166 :         if (mysql_stmt_execute(stmt->stmt)) {
     934          10 :                 MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
     935          10 :                 RETVAL_FALSE;
     936             :         } else {
     937        4156 :                 RETVAL_TRUE;
     938             :         }
     939             : 
     940        4166 :         if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
     941           0 :                 php_mysqli_report_index(stmt->query, mysqli_stmt_server_status(stmt->stmt) TSRMLS_CC);
     942             :         }
     943             : }
     944             : /* }}} */
     945             : 
     946             : #ifndef MYSQLI_USE_MYSQLND
     947             : /* {{{ void mysqli_stmt_fetch_libmysql
     948             :    Fetch results from a prepared statement into the bound variables */
     949             : void mysqli_stmt_fetch_libmysql(INTERNAL_FUNCTION_PARAMETERS)
     950             : {
     951             :         MY_STMT         *stmt;
     952             :         zval                    *mysql_stmt;
     953             :         unsigned int    i;
     954             :         zend_ulong                      ret;
     955             :         unsigned int    uval;
     956             :         my_ulonglong    llval;
     957             : 
     958             : 
     959             :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
     960             :                 return;
     961             :         }
     962             :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
     963             : 
     964             :         /* reset buffers */
     965             :         for (i = 0; i < stmt->result.var_cnt; i++) {
     966             :                 if (stmt->result.buf[i].type == IS_STRING) {
     967             :                         memset(stmt->result.buf[i].val, 0, stmt->result.buf[i].buflen);
     968             :                 }
     969             :         }
     970             :         ret = mysql_stmt_fetch(stmt->stmt);
     971             : #ifdef MYSQL_DATA_TRUNCATED
     972             :         if (!ret || ret == MYSQL_DATA_TRUNCATED) {
     973             : #else
     974             :         if (!ret) {
     975             : #endif
     976             :                 for (i = 0; i < stmt->result.var_cnt; i++) {
     977             :                         zval *result;
     978             :                         /* it must be a reference, isn't it? */
     979             :                         if (Z_ISREF(stmt->result.vars[i])) {
     980             :                                 result = Z_REFVAL(stmt->result.vars[i]);
     981             :                         } else {
     982             :                                 result = &stmt->result.vars[i];
     983             :                         }
     984             :                         /*
     985             :                           QQ: Isn't it quite better to call zval_dtor(). What if the user has
     986             :                           assigned a resource, or an array to the bound variable? We are going
     987             :                           to leak probably. zval_dtor() will handle also Unicode/Non-unicode mode.
     988             :                         */
     989             :                         /* Even if the string is of length zero there is one byte alloced so efree() in all cases */
     990             :                         zval_ptr_dtor(result);
     991             :                         if (!stmt->result.is_null[i]) {
     992             :                                 switch (stmt->result.buf[i].type) {
     993             :                                         case IS_LONG:
     994             :                                                 if ((stmt->stmt->fields[i].type == MYSQL_TYPE_LONG)
     995             :                                                     && (stmt->stmt->fields[i].flags & UNSIGNED_FLAG))
     996             :                                                 {
     997             :                                                         /* unsigned int (11) */
     998             :                                                         uval= *(unsigned int *) stmt->result.buf[i].val;
     999             : #if SIZEOF_ZEND_LONG==4
    1000             :                                                         if (uval > INT_MAX) {
    1001             :                                                                 char *tmp, *p;
    1002             :                                                                 int j = 10;
    1003             :                                                                 tmp = emalloc(11);
    1004             :                                                                 p= &tmp[9];
    1005             :                                                                 do {
    1006             :                                                                         *p-- = (uval % 10) + 48;
    1007             :                                                                         uval = uval / 10;
    1008             :                                                                 } while (--j > 0);
    1009             :                                                                 tmp[10]= '\0';
    1010             :                                                                 /* unsigned int > INT_MAX is 10 digits - ALWAYS */
    1011             :                                                                 ZVAL_STRINGL(result, tmp, 10);
    1012             :                                                                 efree(tmp);
    1013             :                                                                 break;
    1014             :                                                         }
    1015             : #endif
    1016             :                                                 }
    1017             :                                                 if (stmt->stmt->fields[i].flags & UNSIGNED_FLAG) {
    1018             :                                                         ZVAL_LONG(result, *(unsigned int *)stmt->result.buf[i].val);
    1019             :                                                 } else {
    1020             :                                                         ZVAL_LONG(result, *(int *)stmt->result.buf[i].val);
    1021             :                                                 }
    1022             :                                                 break;
    1023             :                                         case IS_DOUBLE:
    1024             :                                                 ZVAL_DOUBLE(result, *(double *)stmt->result.buf[i].val);
    1025             :                                                 break;
    1026             :                                         case IS_STRING:
    1027             :                                                 if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_LONGLONG
    1028             : #if MYSQL_VERSION_ID > 50002
    1029             :                                                  || stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_BIT
    1030             : #endif
    1031             :                                                  ) {
    1032             :                                                         my_bool uns = (stmt->stmt->fields[i].flags & UNSIGNED_FLAG)? 1:0;
    1033             : #if MYSQL_VERSION_ID > 50002
    1034             :                                                         if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_BIT) {
    1035             :                                                                 switch (stmt->result.buf[i].output_len) {
    1036             :                                                                         case 8:llval = (my_ulonglong)  bit_uint8korr(stmt->result.buf[i].val);break;
    1037             :                                                                         case 7:llval = (my_ulonglong)  bit_uint7korr(stmt->result.buf[i].val);break;
    1038             :                                                                         case 6:llval = (my_ulonglong)  bit_uint6korr(stmt->result.buf[i].val);break;
    1039             :                                                                         case 5:llval = (my_ulonglong)  bit_uint5korr(stmt->result.buf[i].val);break;
    1040             :                                                                         case 4:llval = (my_ulonglong)  bit_uint4korr(stmt->result.buf[i].val);break;
    1041             :                                                                         case 3:llval = (my_ulonglong)  bit_uint3korr(stmt->result.buf[i].val);break;
    1042             :                                                                         case 2:llval = (my_ulonglong)  bit_uint2korr(stmt->result.buf[i].val);break;
    1043             :                                                                         case 1:llval = (my_ulonglong)  uint1korr(stmt->result.buf[i].val);break;
    1044             :                                                                 }
    1045             :                                                         } else
    1046             : #endif
    1047             :                                                         {
    1048             :                                                                 llval= *(my_ulonglong *) stmt->result.buf[i].val;
    1049             :                                                         }
    1050             : #if SIZEOF_ZEND_LONG==8
    1051             :                                                         if (uns && llval > 9223372036854775807L) {
    1052             : #elif SIZEOF_ZEND_LONG==4
    1053             :                                                         if ((uns && llval > L64(2147483647)) ||
    1054             :                                                                 (!uns && (( L64(2147483647) < (my_longlong) llval) ||
    1055             :                                                                 (L64(-2147483648) > (my_longlong) llval))))
    1056             :                                                         {
    1057             : #endif
    1058             :                                                                 char tmp[22];
    1059             :                                                                 /* even though lval is declared as unsigned, the value
    1060             :                                                                  * may be negative. Therefor we cannot use MYSQLI_LLU_SPEC and must
    1061             :                                                                  * use MYSQLI_LL_SPEC.
    1062             :                                                                  */
    1063             :                                                                 snprintf(tmp, sizeof(tmp), (stmt->stmt->fields[i].flags & UNSIGNED_FLAG)? MYSQLI_LLU_SPEC : MYSQLI_LL_SPEC, llval);
    1064             :                                                                 ZVAL_STRING(result, tmp);
    1065             :                                                         } else {
    1066             :                                                                 ZVAL_LONG(result, llval);
    1067             :                                                         }
    1068             :                                                 } else {
    1069             : #if defined(MYSQL_DATA_TRUNCATED) && MYSQL_VERSION_ID > 50002
    1070             :                                                         if (ret == MYSQL_DATA_TRUNCATED && *(stmt->stmt->bind[i].error) != 0) {
    1071             :                                                                 /* result was truncated */
    1072             :                                                                 ZVAL_STRINGL(result, stmt->result.buf[i].val, stmt->stmt->bind[i].buffer_length);
    1073             :                                                         } else {
    1074             : #else
    1075             :                                                         {
    1076             : #endif
    1077             :                                                                 ZVAL_STRINGL(result, stmt->result.buf[i].val, stmt->result.buf[i].output_len);
    1078             :                                                         }
    1079             :                                                 }
    1080             :                                                 break;
    1081             :                                         default:
    1082             :                                                 break;
    1083             :                                 }
    1084             :                         } else {
    1085             :                                 ZVAL_NULL(result);
    1086             :                         }
    1087             :                 }
    1088             :         } else {
    1089             :                 MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
    1090             :         }
    1091             : 
    1092             :         switch (ret) {
    1093             :                 case 0:
    1094             : #ifdef MYSQL_DATA_TRUNCATED
    1095             :                 /* according to SQL standard truncation (e.g. loss of precision is
    1096             :                    not an error) - for detecting possible truncation you have to
    1097             :                    check mysqli_stmt_warning
    1098             :                 */
    1099             :                 case MYSQL_DATA_TRUNCATED:
    1100             : #endif
    1101             :                         RETURN_TRUE;
    1102             :                 break;
    1103             :                 case 1:
    1104             :                         RETURN_FALSE;
    1105             :                 break;
    1106             :                 default:
    1107             :                         RETURN_NULL();
    1108             :                 break;
    1109             :         }
    1110             : }
    1111             : /* }}} */
    1112             : #else
    1113             : /* {{{ mixed mysqli_stmt_fetch_mysqlnd */
    1114       19030 : void mysqli_stmt_fetch_mysqlnd(INTERNAL_FUNCTION_PARAMETERS)
    1115             : {
    1116             :         MY_STMT         *stmt;
    1117             :         zval            *mysql_stmt;
    1118             :         zend_bool       fetched_anything;
    1119             : 
    1120       19030 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
    1121           3 :                 return;
    1122             :         }
    1123       19027 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
    1124             : 
    1125       19022 :         if (FAIL  == mysqlnd_stmt_fetch(stmt->stmt, &fetched_anything)) {
    1126           8 :                 RETURN_BOOL(FALSE);
    1127       19014 :         } else if (fetched_anything == TRUE) {
    1128       18858 :                 RETURN_BOOL(TRUE);
    1129             :         } else {
    1130         156 :                 RETURN_NULL();
    1131             :         }
    1132             : }
    1133             : #endif
    1134             : /* }}} */
    1135             : 
    1136             : /* {{{ proto mixed mysqli_stmt_fetch(object stmt) U
    1137             :    Fetch results from a prepared statement into the bound variables */
    1138       19030 : PHP_FUNCTION(mysqli_stmt_fetch)
    1139             : {
    1140             : #if !defined(MYSQLI_USE_MYSQLND)
    1141             :         mysqli_stmt_fetch_libmysql(INTERNAL_FUNCTION_PARAM_PASSTHRU);
    1142             : #else
    1143       19030 :         mysqli_stmt_fetch_mysqlnd(INTERNAL_FUNCTION_PARAM_PASSTHRU);
    1144             : #endif
    1145       19030 : }
    1146             : /* }}} */
    1147             : 
    1148             : /* {{{  php_add_field_properties */
    1149        1275 : static void php_add_field_properties(zval *value, const MYSQL_FIELD *field TSRMLS_DC)
    1150             : {
    1151             : #ifdef MYSQLI_USE_MYSQLND
    1152        2550 :         add_property_str(value, "name", zend_string_copy(field->sname));
    1153             : #else
    1154             :         add_property_stringl(value, "name",(field->name ? field->name : ""), field->name_length);
    1155             : #endif
    1156             : 
    1157        1275 :         add_property_stringl(value, "orgname", (field->org_name ? field->org_name : ""), field->org_name_length);
    1158        1275 :         add_property_stringl(value, "table", (field->table ? field->table : ""), field->table_length);
    1159        1275 :         add_property_stringl(value, "orgtable", (field->org_table ? field->org_table : ""), field->org_table_length);
    1160        1275 :         add_property_stringl(value, "def", (field->def ? field->def : ""), field->def_length);
    1161        1275 :         add_property_stringl(value, "db", (field->db ? field->db : ""), field->db_length);
    1162             : 
    1163             :         /* FIXME: manually set the catalog to "def" due to bug in
    1164             :          * libmysqlclient which does not initialize field->catalog
    1165             :          * and in addition, the catalog is always be "def"
    1166             :          */
    1167        1275 :         add_property_string(value, "catalog", "def");
    1168             : 
    1169        1275 :         add_property_long(value, "max_length", field->max_length);
    1170        1275 :         add_property_long(value, "length", field->length);
    1171        1275 :         add_property_long(value, "charsetnr", field->charsetnr);
    1172        1275 :         add_property_long(value, "flags", field->flags);
    1173        1275 :         add_property_long(value, "type", field->type);
    1174        1275 :         add_property_long(value, "decimals", field->decimals);
    1175        1275 : }
    1176             : /* }}} */
    1177             : 
    1178             : /* {{{ proto mixed mysqli_fetch_field (object result)
    1179             :    Get column information from a result and return as an object */
    1180         213 : PHP_FUNCTION(mysqli_fetch_field)
    1181             : {
    1182             :         MYSQL_RES       *result;
    1183             :         zval            *mysql_result;
    1184             :         const MYSQL_FIELD       *field;
    1185             : 
    1186         213 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
    1187           3 :                 return;
    1188             :         }
    1189             : 
    1190         210 :         MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
    1191             : 
    1192         204 :         if (!(field = mysql_fetch_field(result))) {
    1193           9 :                 RETURN_FALSE;
    1194             :         }
    1195             : 
    1196         195 :         object_init(return_value);
    1197         195 :         php_add_field_properties(return_value, field TSRMLS_CC);
    1198             : }
    1199             : /* }}} */
    1200             : 
    1201             : /* {{{ proto mixed mysqli_fetch_fields (object result)
    1202             :    Return array of objects containing field meta-data */
    1203         516 : PHP_FUNCTION(mysqli_fetch_fields)
    1204             : {
    1205             :         MYSQL_RES       *result;
    1206             :         zval            *mysql_result;
    1207             :         zval            obj;
    1208             : 
    1209             :         unsigned int i;
    1210             : 
    1211         516 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
    1212           2 :                 return;
    1213             :         }
    1214             : 
    1215         514 :         MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
    1216             : 
    1217         513 :         array_init(return_value);
    1218             : 
    1219        1555 :         for (i = 0; i < mysql_num_fields(result); i++) {
    1220        1042 :                 const MYSQL_FIELD *field = mysql_fetch_field_direct(result, i);
    1221             : 
    1222        1042 :                 object_init(&obj);
    1223             : 
    1224        1042 :                 php_add_field_properties(&obj, field TSRMLS_CC);
    1225        1042 :                 add_index_zval(return_value, i, &obj);
    1226             :         }
    1227             : }
    1228             : /* }}} */
    1229             : 
    1230             : /* {{{ proto mixed mysqli_fetch_field_direct (object result, int offset)
    1231             :    Fetch meta-data for a single field */
    1232          51 : PHP_FUNCTION(mysqli_fetch_field_direct)
    1233             : {
    1234             :         MYSQL_RES       *result;
    1235             :         zval            *mysql_result;
    1236             :         const MYSQL_FIELD       *field;
    1237             :         zend_long               offset;
    1238             : 
    1239          51 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_result, mysqli_result_class_entry, &offset) == FAILURE) {
    1240           7 :                 return;
    1241             :         }
    1242             : 
    1243          44 :         MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
    1244             : 
    1245          42 :         if (offset < 0 || offset >= (zend_long) mysql_num_fields(result)) {
    1246           4 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Field offset is invalid for resultset");
    1247           4 :                 RETURN_FALSE;
    1248             :         }
    1249             : 
    1250          38 :         if (!(field = mysql_fetch_field_direct(result,offset))) {
    1251           0 :                 RETURN_FALSE;
    1252             :         }
    1253             : 
    1254          38 :         object_init(return_value);
    1255          38 :         php_add_field_properties(return_value, field TSRMLS_CC);
    1256             : }
    1257             : /* }}} */
    1258             : 
    1259             : /* {{{ proto mixed mysqli_fetch_lengths (object result)
    1260             :    Get the length of each output in a result */
    1261          19 : PHP_FUNCTION(mysqli_fetch_lengths)
    1262             : {
    1263             :         MYSQL_RES               *result;
    1264             :         zval                    *mysql_result;
    1265             :         unsigned int    i;
    1266             :         zend_ulong      *ret;
    1267             : 
    1268          19 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
    1269           2 :                 return;
    1270             :         }
    1271             : 
    1272          17 :         MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
    1273             : 
    1274          16 :         if (!(ret = mysql_fetch_lengths(result))) {
    1275           7 :                 RETURN_FALSE;
    1276             :         }
    1277             : 
    1278           9 :         array_init(return_value);
    1279             : 
    1280          27 :         for (i = 0; i < mysql_num_fields(result); i++) {
    1281          18 :                 add_index_long(return_value, i, ret[i]);
    1282             :         }
    1283             : }
    1284             : /* }}} */
    1285             : 
    1286             : /* {{{ proto array mysqli_fetch_row (object result)
    1287             :    Get a result row as an enumerated array */
    1288          58 : PHP_FUNCTION(mysqli_fetch_row)
    1289             : {
    1290          58 :         php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_NUM, 0);
    1291          58 : }
    1292             : /* }}} */
    1293             : 
    1294             : /* {{{ proto int mysqli_field_count(object link)
    1295             :    Fetch the number of fields returned by the last query for the given link
    1296             : */
    1297          24 : PHP_FUNCTION(mysqli_field_count)
    1298             : {
    1299             :         MY_MYSQL        *mysql;
    1300             :         zval            *mysql_link;
    1301             : 
    1302          24 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
    1303           2 :                 return;
    1304             :         }
    1305          22 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    1306             : 
    1307          15 :         RETURN_LONG(mysql_field_count(mysql->mysql));
    1308             : }
    1309             : /* }}} */
    1310             : 
    1311             : /* {{{ proto int mysqli_field_seek(object result, int fieldnr)
    1312             :    Set result pointer to a specified field offset
    1313             : */
    1314         215 : PHP_FUNCTION(mysqli_field_seek)
    1315             : {
    1316             :         MYSQL_RES               *result;
    1317             :         zval                    *mysql_result;
    1318             :         zend_long       fieldnr;
    1319             : 
    1320         215 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_result, mysqli_result_class_entry, &fieldnr) == FAILURE) {
    1321           4 :                 return;
    1322             :         }
    1323         211 :         MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
    1324             : 
    1325         210 :         if (fieldnr < 0 || fieldnr >= mysql_num_fields(result)) {
    1326          59 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid field offset");
    1327          59 :                 RETURN_FALSE;
    1328             :         }
    1329             : 
    1330         151 :         mysql_field_seek(result, fieldnr);
    1331         151 :         RETURN_TRUE;
    1332             : }
    1333             : /* }}} */
    1334             : 
    1335             : /* {{{ proto int mysqli_field_tell(object result)
    1336             :    Get current field offset of result pointer */
    1337         160 : PHP_FUNCTION(mysqli_field_tell)
    1338             : {
    1339             :         MYSQL_RES       *result;
    1340             :         zval            *mysql_result;
    1341             : 
    1342         160 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
    1343           3 :                 return;
    1344             :         }
    1345         157 :         MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
    1346             : 
    1347         156 :         RETURN_LONG(mysql_field_tell(result));
    1348             : }
    1349             : /* }}} */
    1350             : 
    1351             : /* {{{ proto void mysqli_free_result(object result)
    1352             :    Free query result memory for the given result handle */
    1353        1253 : PHP_FUNCTION(mysqli_free_result)
    1354             : {
    1355             :         MYSQL_RES       *result;
    1356             :         zval            *mysql_result;
    1357             : 
    1358        1253 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
    1359           6 :                 return;
    1360             :         }
    1361        1247 :         MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
    1362             : 
    1363        1246 :         mysqli_free_result(result, FALSE);
    1364        1246 :         MYSQLI_CLEAR_RESOURCE(mysql_result);
    1365             : }
    1366             : /* }}} */
    1367             : 
    1368             : /* {{{ proto string mysqli_get_client_info(void)
    1369             :    Get MySQL client info */
    1370        2745 : PHP_FUNCTION(mysqli_get_client_info)
    1371             : {
    1372        2745 :         const char * info = mysql_get_client_info();
    1373        2745 :         if (info) {
    1374        5490 :                 RETURN_STRING(info);
    1375             :         }
    1376             : }
    1377             : /* }}} */
    1378             : 
    1379             : /* {{{ proto int mysqli_get_client_version(void)
    1380             :    Get MySQL client info */
    1381          18 : PHP_FUNCTION(mysqli_get_client_version)
    1382             : {
    1383          18 :         RETURN_LONG((zend_long)mysql_get_client_version());
    1384             : }
    1385             : /* }}} */
    1386             : 
    1387             : /* {{{ proto string mysqli_get_host_info (object link)
    1388             :    Get MySQL host info */
    1389          13 : PHP_FUNCTION(mysqli_get_host_info)
    1390             : {
    1391             :         MY_MYSQL        *mysql;
    1392          13 :         zval            *mysql_link = NULL;
    1393             : 
    1394          13 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
    1395           2 :                 return;
    1396             :         }
    1397          11 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    1398             : #if !defined(MYSQLI_USE_MYSQLND)
    1399             :         RETURN_STRING((mysql->mysql->host_info) ? mysql->mysql->host_info : "");
    1400             : #else
    1401          10 :         RETURN_STRING((mysql->mysql->data->host_info) ? mysql->mysql->data->host_info : "");
    1402             : #endif
    1403             : }
    1404             : /* }}} */
    1405             : 
    1406             : /* {{{ proto int mysqli_get_proto_info(object link)
    1407             :    Get MySQL protocol information */
    1408          14 : PHP_FUNCTION(mysqli_get_proto_info)
    1409             : {
    1410             :         MY_MYSQL        *mysql;
    1411          14 :         zval            *mysql_link = NULL;
    1412             : 
    1413          14 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
    1414           3 :                 return;
    1415             :         }
    1416          11 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    1417           5 :         RETURN_LONG(mysql_get_proto_info(mysql->mysql));
    1418             : }
    1419             : /* }}} */
    1420             : 
    1421             : /* {{{ proto string mysqli_get_server_info(object link)
    1422             :    Get MySQL server info */
    1423          14 : PHP_FUNCTION(mysqli_get_server_info)
    1424             : {
    1425             :         MY_MYSQL        *mysql;
    1426          14 :         zval            *mysql_link = NULL;
    1427             :         const char      *info;
    1428             : 
    1429          14 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
    1430           3 :                 return;
    1431             :         }
    1432          11 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    1433             : 
    1434           5 :         info = mysql_get_server_info(mysql->mysql);
    1435           5 :         if (info) {
    1436          10 :                 RETURN_STRING(info);
    1437             :         }
    1438             : }
    1439             : /* }}} */
    1440             : 
    1441             : /* {{{ proto int mysqli_get_server_version(object link)
    1442             :    Return the MySQL version for the server referenced by the given link */
    1443          64 : PHP_FUNCTION(mysqli_get_server_version)
    1444             : {
    1445             :         MY_MYSQL        *mysql;
    1446          64 :         zval            *mysql_link = NULL;
    1447             : 
    1448          64 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
    1449           2 :                 return;
    1450             :         }
    1451          62 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    1452             : 
    1453          56 :         RETURN_LONG(mysql_get_server_version(mysql->mysql));
    1454             : }
    1455             : /* }}} */
    1456             : 
    1457             : /* {{{ proto string mysqli_info(object link)
    1458             :    Get information about the most recent query */
    1459          19 : PHP_FUNCTION(mysqli_info)
    1460             : {
    1461             :         MY_MYSQL        *mysql;
    1462          19 :         zval            *mysql_link = NULL;
    1463             :         const char      *info;
    1464             : 
    1465          19 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
    1466           2 :                 return;
    1467             :         }
    1468          17 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    1469             : 
    1470          11 :         info = mysql_info(mysql->mysql);
    1471          11 :         if (info) {
    1472          12 :                 RETURN_STRING(info);
    1473             :         }
    1474             : }
    1475             : /* }}} */
    1476             : 
    1477             : /* {{{ php_mysqli_init() */
    1478        1186 : void php_mysqli_init(INTERNAL_FUNCTION_PARAMETERS)
    1479             : {
    1480             :         MYSQLI_RESOURCE *mysqli_resource;
    1481             :         MY_MYSQL *mysql;
    1482             : 
    1483             : // TODO: We can't properly check if this was to mysql_init() in a class method 
    1484             : //       or a call to mysqli->init().
    1485             : //       To solve the problem, we added instanceof check for the class of $this
    1486             : //       ???
    1487        1307 :         if (getThis() &&
    1488          61 :             instanceof_function(Z_OBJCE_P(getThis()), mysqli_link_class_entry TSRMLS_CC) &&
    1489          60 :             (Z_MYSQLI_P(getThis()))->ptr) {
    1490             : //???   if (getThis() && (Z_MYSQLI_P(getThis()))->ptr) {
    1491           2 :                 return;
    1492             :         }
    1493             : 
    1494        1184 :         mysql = (MY_MYSQL *)ecalloc(1, sizeof(MY_MYSQL));
    1495             : 
    1496             : #if !defined(MYSQLI_USE_MYSQLND)
    1497             :         if (!(mysql->mysql = mysql_init(NULL)))
    1498             : #else
    1499             :         /*
    1500             :           We create always persistent, as if the user want to connecto
    1501             :           to p:somehost, we can't convert the handle then
    1502             :         */
    1503        1184 :         if (!(mysql->mysql = mysqlnd_init(MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA, TRUE)))
    1504             : #endif
    1505             :         {
    1506           0 :                 efree(mysql);
    1507           0 :                 RETURN_FALSE;
    1508             :         }
    1509             : 
    1510        1184 :         mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
    1511        1184 :         mysqli_resource->ptr = (void *)mysql;
    1512        1184 :         mysqli_resource->status = MYSQLI_STATUS_INITIALIZED;
    1513             : 
    1514        2310 :         if (!getThis() || !instanceof_function(Z_OBJCE_P(getThis()), mysqli_link_class_entry TSRMLS_CC)) {
    1515        1126 :                 MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_link_class_entry);
    1516             :         } else {
    1517          58 :                 (Z_MYSQLI_P(getThis()))->ptr = mysqli_resource;
    1518             :         }
    1519             : }
    1520             : /* }}} */
    1521             : 
    1522             : /* {{{ proto resource mysqli_init(void)
    1523             :    Initialize mysqli and return a resource for use with mysql_real_connect */
    1524        1170 : PHP_FUNCTION(mysqli_init)
    1525             : {
    1526        1170 :         php_mysqli_init(INTERNAL_FUNCTION_PARAM_PASSTHRU);
    1527        1170 : }
    1528             : /* }}} */
    1529             : 
    1530             : /* {{{ proto mixed mysqli_insert_id(object link)
    1531             :    Get the ID generated from the previous INSERT operation */
    1532          28 : PHP_FUNCTION(mysqli_insert_id)
    1533             : {
    1534             :         MY_MYSQL                *mysql;
    1535             :         my_ulonglong    rc;
    1536             :         zval                    *mysql_link;
    1537             : 
    1538          28 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
    1539           3 :                 return;
    1540             :         }
    1541          25 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    1542          18 :         rc = mysql_insert_id(mysql->mysql);
    1543          18 :         MYSQLI_RETURN_LONG_INT(rc)
    1544             : }
    1545             : /* }}} */
    1546             : 
    1547             : /* {{{ proto bool mysqli_kill(object link, int processid)
    1548             :    Kill a mysql process on the server */
    1549          26 : PHP_FUNCTION(mysqli_kill)
    1550             : {
    1551             :         MY_MYSQL        *mysql;
    1552             :         zval            *mysql_link;
    1553             :         zend_long               processid;
    1554             : 
    1555          26 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_link, mysqli_link_class_entry, &processid) == FAILURE) {
    1556           2 :                 return;
    1557             :         }
    1558          24 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    1559             : 
    1560          24 :         if (processid <= 0) {
    1561           7 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "processid should have positive value");
    1562           7 :                 RETURN_FALSE;
    1563             :         }
    1564             : 
    1565          17 :         if (mysql_kill(mysql->mysql, processid)) {
    1566           3 :                 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
    1567           3 :                 RETURN_FALSE;
    1568             :         }
    1569          14 :         RETURN_TRUE;
    1570             : }
    1571             : /* }}} */
    1572             : 
    1573             : /* {{{ proto bool mysqli_more_results(object link)
    1574             :    check if there any more query results from a multi query */
    1575          37 : PHP_FUNCTION(mysqli_more_results)
    1576             : {
    1577             :         MY_MYSQL        *mysql;
    1578             :         zval            *mysql_link;
    1579             : 
    1580          37 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
    1581           2 :                 return;
    1582             :         }
    1583          35 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    1584             : 
    1585          34 :         RETURN_BOOL(mysql_more_results(mysql->mysql));
    1586             : }
    1587             : /* }}} */
    1588             : 
    1589             : /* {{{ proto bool mysqli_next_result(object link)
    1590             :    read next result from multi_query */
    1591          44 : PHP_FUNCTION(mysqli_next_result) {
    1592             :         MY_MYSQL        *mysql;
    1593             :         zval            *mysql_link;
    1594             : 
    1595          44 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
    1596           2 :                 return;
    1597             :         }
    1598          42 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    1599             : 
    1600          41 :         if (!mysql_more_results(mysql->mysql)) {
    1601          12 :                 php_error_docref(NULL TSRMLS_CC, E_STRICT, "There is no next result set. "
    1602             :                                                 "Please, call mysqli_more_results()/mysqli::more_results() to check "
    1603             :                                                 "whether to call this function/method");
    1604             :         }
    1605             : 
    1606          41 :         RETURN_BOOL(!mysql_next_result(mysql->mysql));
    1607             : }
    1608             : /* }}} */
    1609             : 
    1610             : #if defined(HAVE_STMT_NEXT_RESULT) && defined(MYSQLI_USE_MYSQLND)
    1611             : /* {{{ proto bool mysqli_stmt_next_result(object link)
    1612             :    check if there any more query results from a multi query */
    1613           3 : PHP_FUNCTION(mysqli_stmt_more_results)
    1614             : {
    1615             :         MY_STMT         *stmt;
    1616             :         zval            *mysql_stmt;
    1617             : 
    1618           3 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
    1619           0 :                 return;
    1620             :         }
    1621           3 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
    1622             : 
    1623           3 :         RETURN_BOOL(mysqlnd_stmt_more_results(stmt->stmt));
    1624             : }
    1625             : /* }}} */
    1626             : 
    1627             : /* {{{ proto bool mysqli_stmt_next_result(object link)
    1628             :    read next result from multi_query */
    1629           2 : PHP_FUNCTION(mysqli_stmt_next_result) {
    1630             :         MY_STMT         *stmt;
    1631             :         zval            *mysql_stmt;
    1632             : 
    1633           2 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
    1634           0 :                 return;
    1635             :         }
    1636           2 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
    1637             : 
    1638           2 :         if (!mysqlnd_stmt_more_results(stmt->stmt)) {
    1639           0 :                 php_error_docref(NULL TSRMLS_CC, E_STRICT, "There is no next result set. "
    1640             :                                                 "Please, call mysqli_stmt_more_results()/mysqli_stmt::more_results() to check "
    1641             :                                                 "whether to call this function/method");
    1642             :         }
    1643             : 
    1644           2 :         RETURN_BOOL(!mysql_stmt_next_result(stmt->stmt));
    1645             : }
    1646             : /* }}} */
    1647             : #endif
    1648             : 
    1649             : /* {{{ proto int mysqli_num_fields(object result)
    1650             :    Get number of fields in result */
    1651          12 : PHP_FUNCTION(mysqli_num_fields)
    1652             : {
    1653             :         MYSQL_RES       *result;
    1654             :         zval            *mysql_result;
    1655             : 
    1656          12 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
    1657           2 :                 return;
    1658             :         }
    1659          10 :         MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
    1660             : 
    1661           9 :         RETURN_LONG(mysql_num_fields(result));
    1662             : }
    1663             : /* }}} */
    1664             : 
    1665             : /* {{{ proto mixed mysqli_num_rows(object result)
    1666             :    Get number of rows in result */
    1667          29 : PHP_FUNCTION(mysqli_num_rows)
    1668             : {
    1669             :         MYSQL_RES       *result;
    1670             :         zval            *mysql_result;
    1671             : 
    1672          29 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
    1673           3 :                 return;
    1674             :         }
    1675          26 :         MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
    1676             : 
    1677          25 :         if (mysqli_result_is_unbuffered_and_not_everything_is_fetched(result)) {
    1678           3 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function cannot be used with MYSQL_USE_RESULT");
    1679           3 :                 RETURN_LONG(0);
    1680             :         }
    1681             : 
    1682          22 :         MYSQLI_RETURN_LONG_INT(mysql_num_rows(result));
    1683             : }
    1684             : /* }}} */
    1685             : 
    1686             : /* {{{ mysqli_options_get_option_zval_type */
    1687          88 : static int mysqli_options_get_option_zval_type(int option)
    1688             : {
    1689          88 :         switch (option) {
    1690             : #ifdef MYSQLI_USE_MYSQLND
    1691             : #if PHP_MAJOR_VERSION == 6
    1692             :                 /* PHP-7 doesn't supprt unicode yet ??? */
    1693             :                 case MYSQLND_OPT_NUMERIC_AND_DATETIME_AS_UNICODE:
    1694             : #endif
    1695             :                 case MYSQLND_OPT_NET_CMD_BUFFER_SIZE:
    1696             :                 case MYSQLND_OPT_NET_READ_BUFFER_SIZE:
    1697             : #ifdef MYSQLND_STRING_TO_INT_CONVERSION
    1698             :                 case MYSQLND_OPT_INT_AND_FLOAT_NATIVE:
    1699             : #endif
    1700             : #endif /* MYSQLI_USE_MYSQLND */
    1701             :                 case MYSQL_OPT_CONNECT_TIMEOUT:
    1702             : #ifdef MYSQL_REPORT_DATA_TRUNCATION
    1703             :                 case MYSQL_REPORT_DATA_TRUNCATION:
    1704             : #endif
    1705             :                 case MYSQL_OPT_LOCAL_INFILE:
    1706             :                 case MYSQL_OPT_NAMED_PIPE:
    1707             : #ifdef MYSQL_OPT_PROTOCOL
    1708             :                 case MYSQL_OPT_PROTOCOL:
    1709             : #endif /* MySQL 4.1.0 */
    1710             : #ifdef MYSQL_OPT_READ_TIMEOUT
    1711             :                 case MYSQL_OPT_READ_TIMEOUT:
    1712             :                 case MYSQL_OPT_WRITE_TIMEOUT:
    1713             :                 case MYSQL_OPT_GUESS_CONNECTION:
    1714             :                 case MYSQL_OPT_USE_EMBEDDED_CONNECTION:
    1715             :                 case MYSQL_OPT_USE_REMOTE_CONNECTION:
    1716             :                 case MYSQL_SECURE_AUTH:
    1717             : #endif /* MySQL 4.1.1 */
    1718             : #ifdef MYSQL_OPT_RECONNECT
    1719             :                 case MYSQL_OPT_RECONNECT:
    1720             : #endif /* MySQL 5.0.13 */
    1721             : #ifdef MYSQL_OPT_SSL_VERIFY_SERVER_CERT
    1722             :                 case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
    1723             : #endif /* MySQL 5.0.23 */
    1724             : #ifdef MYSQL_OPT_COMPRESS
    1725             :                 case MYSQL_OPT_COMPRESS:
    1726             : #endif /* mysqlnd @ PHP 5.3.2 */
    1727             : #ifdef MYSQL_OPT_SSL_VERIFY_SERVER_CERT
    1728             :         REGISTER_LONG_CONSTANT("MYSQLI_OPT_SSL_VERIFY_SERVER_CERT", MYSQL_OPT_SSL_VERIFY_SERVER_CERT, CONST_CS | CONST_PERSISTENT);
    1729             : #endif /* MySQL 5.1.1., mysqlnd @ PHP 5.3.3 */
    1730             : #if (MYSQL_VERSION_ID >= 50611 && defined(CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS)) || defined(MYSQLI_USE_MYSQLND)
    1731             :                 case MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS:
    1732             : #endif
    1733          31 :                         return IS_LONG;
    1734             : 
    1735             : #ifdef MYSQL_SHARED_MEMORY_BASE_NAME
    1736             :                 case MYSQL_SHARED_MEMORY_BASE_NAME:
    1737             : #endif /* MySQL 4.1.0 */
    1738             : #ifdef MYSQL_SET_CLIENT_IP
    1739             :                 case MYSQL_SET_CLIENT_IP:
    1740             : #endif /* MySQL 4.1.1 */
    1741             :                 case MYSQL_READ_DEFAULT_FILE:
    1742             :                 case MYSQL_READ_DEFAULT_GROUP:
    1743             :                 case MYSQL_INIT_COMMAND:
    1744             :                 case MYSQL_SET_CHARSET_NAME:
    1745             :                 case MYSQL_SET_CHARSET_DIR:
    1746             : #if MYSQL_VERSION_ID > 50605 || defined(MYSQLI_USE_MYSQLND)
    1747             :                 case MYSQL_SERVER_PUBLIC_KEY:
    1748             : #endif
    1749          55 :                         return IS_STRING;
    1750             : 
    1751             :                 default:
    1752           2 :                         return IS_NULL;
    1753             :         }
    1754             : }
    1755             : /* }}} */
    1756             : 
    1757             : /* {{{ proto bool mysqli_options(object link, int flags, mixed values)
    1758             :    Set options */
    1759         101 : PHP_FUNCTION(mysqli_options)
    1760             : {
    1761             :         MY_MYSQL                *mysql;
    1762         101 :         zval                    *mysql_link = NULL;
    1763             :         zval                    *mysql_value;
    1764             :         zend_long                       mysql_option;
    1765             :         unsigned int    l_value;
    1766             :         zend_long                       ret;
    1767             :         int                             expected_type;
    1768             : 
    1769         101 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Olz", &mysql_link, mysqli_link_class_entry, &mysql_option, &mysql_value) == FAILURE) {
    1770          10 :                 return;
    1771             :         }
    1772          91 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_INITIALIZED);
    1773             : 
    1774             : #if PHP_API_VERSION < 20100412
    1775             :         if ((PG(open_basedir) && PG(open_basedir)[0] != '\0') || PG(safe_mode)) {
    1776             : #else
    1777          89 :         if (PG(open_basedir) && PG(open_basedir)[0] != '\0') {
    1778             : #endif
    1779           1 :                 if(mysql_option == MYSQL_OPT_LOCAL_INFILE) {
    1780           1 :                         RETURN_FALSE;
    1781             :                 }
    1782             :         }
    1783          88 :         expected_type = mysqli_options_get_option_zval_type(mysql_option);
    1784         176 :         if (expected_type != Z_TYPE_P(mysql_value)) {
    1785           4 :                 switch (expected_type) {
    1786             :                         case IS_STRING:
    1787           4 :                                 convert_to_string_ex(mysql_value);
    1788           1 :                                 break;
    1789             :                         case IS_LONG:
    1790           2 :                                 convert_to_long_ex(mysql_value);
    1791             :                                 break;
    1792             :                         default:
    1793             :                                 break;
    1794             :                 }
    1795             :         }
    1796          88 :         switch (expected_type) {
    1797             :                 case IS_STRING:
    1798          55 :                         ret = mysql_options(mysql->mysql, mysql_option, Z_STRVAL_P(mysql_value));
    1799          55 :                         break;
    1800             :                 case IS_LONG:
    1801          31 :                         l_value = Z_LVAL_P(mysql_value);
    1802          31 :                         ret = mysql_options(mysql->mysql, mysql_option, (char *)&l_value);
    1803          31 :                         break;
    1804             :                 default:
    1805           2 :                         ret = 1;
    1806             :                         break;
    1807             :         }
    1808             : 
    1809          88 :         RETURN_BOOL(!ret);
    1810             : }
    1811             : /* }}} */
    1812             : 
    1813             : /* {{{ proto bool mysqli_ping(object link)
    1814             :    Ping a server connection or reconnect if there is no connection */
    1815          14 : PHP_FUNCTION(mysqli_ping)
    1816             : {
    1817             :         MY_MYSQL        *mysql;
    1818             :         zval            *mysql_link;
    1819             :         zend_long               rc;
    1820             : 
    1821          14 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
    1822           2 :                 return;
    1823             :         }
    1824          12 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    1825          11 :         rc = mysql_ping(mysql->mysql);
    1826          11 :         MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
    1827             : 
    1828          11 :         RETURN_BOOL(!rc);
    1829             : }
    1830             : /* }}} */
    1831             : 
    1832             : /* {{{ proto mixed mysqli_prepare(object link, string query)
    1833             :    Prepare a SQL statement for execution */
    1834         128 : PHP_FUNCTION(mysqli_prepare)
    1835             : {
    1836             :         MY_MYSQL                *mysql;
    1837             :         MY_STMT                 *stmt;
    1838         128 :         char                    *query = NULL;
    1839             :         size_t                          query_len;
    1840             :         zval                    *mysql_link;
    1841             :         MYSQLI_RESOURCE *mysqli_resource;
    1842             : 
    1843         128 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os",&mysql_link, mysqli_link_class_entry, &query, &query_len) == FAILURE) {
    1844           2 :                 return;
    1845             :         }
    1846         126 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    1847             : 
    1848             : #if !defined(MYSQLI_USE_MYSQLND)
    1849             :         if (mysql->mysql->status == MYSQL_STATUS_GET_RESULT) {
    1850             :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "All data must be fetched before a new statement prepare takes place");
    1851             :                 RETURN_FALSE;
    1852             :         }
    1853             : #endif
    1854             : 
    1855         126 :         stmt = (MY_STMT *)ecalloc(1,sizeof(MY_STMT));
    1856             : 
    1857         126 :         if ((stmt->stmt = mysql_stmt_init(mysql->mysql))) {
    1858         126 :                 if (mysql_stmt_prepare(stmt->stmt, query, query_len)) {
    1859             :                         /* mysql_stmt_close() clears errors, so we have to store them temporarily */
    1860             : #if !defined(MYSQLI_USE_MYSQLND)
    1861             :                         char  last_error[MYSQL_ERRMSG_SIZE];
    1862             :                         char  sqlstate[SQLSTATE_LENGTH+1];
    1863             :                         unsigned int last_errno;
    1864             : 
    1865             :                         last_errno = stmt->stmt->last_errno;
    1866             :                         memcpy(last_error, stmt->stmt->last_error, MYSQL_ERRMSG_SIZE);
    1867             :                         memcpy(sqlstate, mysql->mysql->net.sqlstate, SQLSTATE_LENGTH+1);
    1868             : #else
    1869          10 :                         MYSQLND_ERROR_INFO error_info = *mysql->mysql->data->error_info;
    1870             : #endif
    1871          10 :                         mysqli_stmt_close(stmt->stmt, FALSE);
    1872          10 :                         stmt->stmt = NULL;
    1873             : 
    1874             :                         /* restore error messages */
    1875             : #if !defined(MYSQLI_USE_MYSQLND)
    1876             :                         mysql->mysql->net.last_errno = last_errno;
    1877             :                         memcpy(mysql->mysql->net.last_error, last_error, MYSQL_ERRMSG_SIZE);
    1878             :                         memcpy(mysql->mysql->net.sqlstate, sqlstate, SQLSTATE_LENGTH+1);
    1879             : #else
    1880          10 :                         *mysql->mysql->data->error_info = error_info;
    1881             : #endif
    1882             :                 }
    1883             :         }
    1884             : 
    1885             :         /* don't initialize stmt->query with NULL, we ecalloc()-ed the memory */
    1886             :         /* Get performance boost if reporting is switched off */
    1887         126 :         if (stmt->stmt && query_len && (MyG(report_mode) & MYSQLI_REPORT_INDEX)) {
    1888           0 :                 stmt->query = (char *)emalloc(query_len + 1);
    1889           0 :                 memcpy(stmt->query, query, query_len);
    1890           0 :                 stmt->query[query_len] = '\0';
    1891             :         }
    1892             : 
    1893             :         /* don't join to the previous if because it won't work if mysql_stmt_prepare_fails */
    1894         126 :         if (!stmt->stmt) {
    1895          10 :                 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
    1896          10 :                 efree(stmt);
    1897          10 :                 RETURN_FALSE;
    1898             :         }
    1899             : #ifndef MYSQLI_USE_MYSQLND
    1900             :         ZVAL_COPY(&stmt->link_handle, mysql_link);
    1901             : #endif
    1902             : 
    1903         116 :         mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
    1904         116 :         mysqli_resource->ptr = (void *)stmt;
    1905             : 
    1906             :         /* change status */
    1907         116 :         mysqli_resource->status = MYSQLI_STATUS_VALID;
    1908         116 :         MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_stmt_class_entry);
    1909             : }
    1910             : /* }}} */
    1911             : 
    1912             : /* {{{ proto bool mysqli_real_connect(object link [,string hostname [,string username [,string passwd [,string dbname [,int port [,string socket [,int flags]]]]]]])
    1913             :    Open a connection to a mysql server */
    1914        1181 : PHP_FUNCTION(mysqli_real_connect)
    1915             : {
    1916        1181 :         mysqli_common_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, TRUE, FALSE);
    1917        1181 : }
    1918             : /* }}} */
    1919             : 
    1920             : /* {{{ proto bool mysqli_real_query(object link, string query)
    1921             :    Binary-safe version of mysql_query() */
    1922          62 : PHP_FUNCTION(mysqli_real_query)
    1923             : {
    1924             :         MY_MYSQL        *mysql;
    1925             :         zval            *mysql_link;
    1926          62 :         char            *query = NULL;
    1927             :         size_t          query_len;
    1928             : 
    1929          62 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &query, &query_len) == FAILURE) {
    1930           3 :                 return;
    1931             :         }
    1932          59 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    1933             : 
    1934          58 :         MYSQLI_DISABLE_MQ; /* disable multi statements/queries */
    1935             : 
    1936          58 :         if (mysql_real_query(mysql->mysql, query, query_len)) {
    1937           8 :                 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
    1938           8 :                 RETURN_FALSE;
    1939             :         }
    1940             : 
    1941          50 :         if (!mysql_field_count(mysql->mysql)) {
    1942          16 :                 if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
    1943           0 :                         php_mysqli_report_index(query, mysqli_server_status(mysql->mysql) TSRMLS_CC);
    1944             :                 }
    1945             :         }
    1946             : 
    1947          50 :         RETURN_TRUE;
    1948             : }
    1949             : /* }}} */
    1950             : 
    1951             : /* {{{ proto string mysqli_real_escape_string(object link, string escapestr)
    1952             :    Escapes special characters in a string for use in a SQL statement, taking into account the current charset of the connection */
    1953       12510 : PHP_FUNCTION(mysqli_real_escape_string) {
    1954             :         MY_MYSQL        *mysql;
    1955       12510 :         zval            *mysql_link = NULL;
    1956             :         char            *escapestr;
    1957             :         size_t                  escapestr_len;
    1958             :         zend_string *newstr;
    1959             : 
    1960       12510 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &escapestr, &escapestr_len) == FAILURE) {
    1961           7 :                 return;
    1962             :         }
    1963       12503 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    1964             : 
    1965       25002 :         newstr = zend_string_alloc(2 * escapestr_len, 0);
    1966       12501 :         newstr->len = mysql_real_escape_string(mysql->mysql, newstr->val, escapestr, escapestr_len);
    1967       25002 :         newstr = zend_string_realloc(newstr, newstr->len, 0);
    1968             : 
    1969       12501 :         RETURN_STR(newstr);
    1970             : }
    1971             : /* }}} */
    1972             : 
    1973             : /* {{{ proto bool mysqli_rollback(object link)
    1974             :    Undo actions from current transaction */
    1975          10 : PHP_FUNCTION(mysqli_rollback)
    1976             : {
    1977             :         MY_MYSQL        *mysql;
    1978             :         zval            *mysql_link;
    1979          10 :         zend_long               flags = TRANS_COR_NO_OPT;
    1980          10 :         char *          name = NULL;
    1981          10 :         size_t                  name_len = 0;
    1982             : 
    1983          10 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|ls", &mysql_link, mysqli_link_class_entry, &flags, &name, &name_len) == FAILURE) {
    1984           3 :                 return;
    1985             :         }
    1986           7 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    1987             : 
    1988             : #if !defined(MYSQLI_USE_MYSQLND)
    1989             :         if (mysqli_commit_or_rollback_libmysql(mysql->mysql, FALSE, flags, name TSRMLS_CC)) {
    1990             : #else
    1991           6 :         if (FAIL == mysqlnd_rollback(mysql->mysql, flags, name)) {
    1992             : #endif
    1993           0 :                 RETURN_FALSE;
    1994             :         }
    1995           6 :         RETURN_TRUE;
    1996             : }
    1997             : /* }}} */
    1998             : 
    1999             : /* {{{ proto bool mysqli_stmt_send_long_data(object stmt, int param_nr, string data)
    2000             : */
    2001          23 : PHP_FUNCTION(mysqli_stmt_send_long_data)
    2002             : {
    2003             :         MY_STMT *stmt;
    2004             :         zval    *mysql_stmt;
    2005             :         char    *data;
    2006             :         zend_long       param_nr;
    2007             :         size_t          data_len;
    2008             : 
    2009          23 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ols", &mysql_stmt, mysqli_stmt_class_entry, &param_nr, &data, &data_len) == FAILURE) {
    2010           5 :                 return;
    2011             :         }
    2012          18 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
    2013             : 
    2014          18 :         if (param_nr < 0) {
    2015           2 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid parameter number");
    2016           2 :                 RETURN_FALSE;
    2017             :         }
    2018          16 :         if (mysql_stmt_send_long_data(stmt->stmt, param_nr, data, data_len)) {
    2019           1 :                 RETURN_FALSE;
    2020             :         }
    2021          15 :         RETURN_TRUE;
    2022             : }
    2023             : /* }}} */
    2024             : 
    2025             : /* {{{ proto mixed mysqli_stmt_affected_rows(object stmt)
    2026             :    Return the number of rows affected in the last query for the given link */
    2027          25 : PHP_FUNCTION(mysqli_stmt_affected_rows)
    2028             : {
    2029             :         MY_STMT                 *stmt;
    2030             :         zval                    *mysql_stmt;
    2031             :         my_ulonglong    rc;
    2032             : 
    2033          25 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
    2034           2 :                 return;
    2035             :         }
    2036          23 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
    2037             : 
    2038          21 :         rc = mysql_stmt_affected_rows(stmt->stmt);
    2039          21 :         if (rc == (my_ulonglong) -1) {
    2040           5 :                 RETURN_LONG(-1);
    2041             :         }
    2042          16 :         MYSQLI_RETURN_LONG_INT(rc)
    2043             : }
    2044             : /* }}} */
    2045             : 
    2046             : /* {{{ proto bool mysqli_stmt_close(object stmt)
    2047             :    Close statement */
    2048         918 : PHP_FUNCTION(mysqli_stmt_close)
    2049             : {
    2050             :         MY_STMT         *stmt;
    2051             :         zval            *mysql_stmt;
    2052             : 
    2053         918 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
    2054           2 :                 return;
    2055             :         }
    2056         916 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
    2057             : 
    2058         913 :         mysqli_stmt_close(stmt->stmt, FALSE);
    2059         913 :         stmt->stmt = NULL;
    2060         913 :         php_clear_stmt_bind(stmt TSRMLS_CC);
    2061         913 :         MYSQLI_CLEAR_RESOURCE(mysql_stmt);
    2062         913 :         RETURN_TRUE;
    2063             : }
    2064             : /* }}} */
    2065             : 
    2066             : /* {{{ proto void mysqli_stmt_data_seek(object stmt, int offset)
    2067             :    Move internal result pointer */
    2068           8 : PHP_FUNCTION(mysqli_stmt_data_seek)
    2069             : {
    2070             :         MY_STMT         *stmt;
    2071             :         zval            *mysql_stmt;
    2072             :         zend_long               offset;
    2073             : 
    2074           8 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_stmt, mysqli_stmt_class_entry, &offset) == FAILURE) {
    2075           2 :                 return;
    2076             :         }
    2077           6 :         if (offset < 0) {
    2078           1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset must be positive");
    2079           1 :                 RETURN_FALSE;
    2080             :         }
    2081             : 
    2082           5 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
    2083             : 
    2084           3 :         mysql_stmt_data_seek(stmt->stmt, offset);
    2085             : }
    2086             : /* }}} */
    2087             : 
    2088             : /* {{{ proto int mysqli_stmt_field_count(object stmt) {
    2089             :    Return the number of result columns for the given statement */
    2090          20 : PHP_FUNCTION(mysqli_stmt_field_count)
    2091             : {
    2092             :         MY_STMT         *stmt;
    2093             :         zval            *mysql_stmt;
    2094             : 
    2095          20 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
    2096           2 :                 return;
    2097             :         }
    2098          18 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
    2099             : 
    2100          15 :         RETURN_LONG(mysql_stmt_field_count(stmt->stmt));
    2101             : }
    2102             : /* }}} */
    2103             : 
    2104             : /* {{{ proto void mysqli_stmt_free_result(object stmt)
    2105             :    Free stored result memory for the given statement handle */
    2106          53 : PHP_FUNCTION(mysqli_stmt_free_result)
    2107             : {
    2108             :         MY_STMT         *stmt;
    2109             :         zval            *mysql_stmt;
    2110             : 
    2111          53 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
    2112           2 :                 return;
    2113             :         }
    2114             : 
    2115          51 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
    2116             : 
    2117          49 :         mysql_stmt_free_result(stmt->stmt);
    2118             : }
    2119             : /* }}} */
    2120             : 
    2121             : /* {{{ proto mixed mysqli_stmt_insert_id(object stmt)
    2122             :    Get the ID generated from the previous INSERT operation */
    2123           8 : PHP_FUNCTION(mysqli_stmt_insert_id)
    2124             : {
    2125             :         MY_STMT                 *stmt;
    2126             :         my_ulonglong    rc;
    2127             :         zval                    *mysql_stmt;
    2128             : 
    2129           8 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
    2130           1 :                 return;
    2131             :         }
    2132           7 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
    2133           5 :         rc = mysql_stmt_insert_id(stmt->stmt);
    2134           5 :         MYSQLI_RETURN_LONG_INT(rc)
    2135             : }
    2136             : /* }}} */
    2137             : 
    2138             : /* {{{ proto int mysqli_stmt_param_count(object stmt)
    2139             :    Return the number of parameter for the given statement */
    2140          10 : PHP_FUNCTION(mysqli_stmt_param_count)
    2141             : {
    2142             :         MY_STMT         *stmt;
    2143             :         zval            *mysql_stmt;
    2144             : 
    2145          10 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
    2146           3 :                 return;
    2147             :         }
    2148           7 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
    2149             : 
    2150           5 :         RETURN_LONG(mysql_stmt_param_count(stmt->stmt));
    2151             : }
    2152             : /* }}} */
    2153             : 
    2154             : /* {{{ proto bool mysqli_stmt_reset(object stmt)
    2155             :    reset a prepared statement */
    2156          11 : PHP_FUNCTION(mysqli_stmt_reset)
    2157             : {
    2158             :         MY_STMT         *stmt;
    2159             :         zval            *mysql_stmt;
    2160             : 
    2161          11 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
    2162           3 :                 return;
    2163             :         }
    2164             : 
    2165           8 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
    2166             : 
    2167           6 :         if (mysql_stmt_reset(stmt->stmt)) {
    2168           0 :                 RETURN_FALSE;
    2169             :         }
    2170           6 :         RETURN_TRUE;
    2171             : }
    2172             : /* }}} */
    2173             : 
    2174             : /* {{{ proto mixed mysqli_stmt_num_rows(object stmt)
    2175             :    Return the number of rows in statements result set */
    2176          24 : PHP_FUNCTION(mysqli_stmt_num_rows)
    2177             : {
    2178             :         MY_STMT                 *stmt;
    2179             :         zval                    *mysql_stmt;
    2180             :         my_ulonglong    rc;
    2181             : 
    2182          24 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
    2183           2 :                 return;
    2184             :         }
    2185             : 
    2186          22 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
    2187             : 
    2188          21 :         rc = mysql_stmt_num_rows(stmt->stmt);
    2189          21 :         MYSQLI_RETURN_LONG_INT(rc)
    2190             : }
    2191             : /* }}} */
    2192             : 
    2193             : /* {{{ proto bool mysqli_select_db(object link, string dbname)
    2194             :    Select a MySQL database */
    2195          49 : PHP_FUNCTION(mysqli_select_db)
    2196             : {
    2197             :         MY_MYSQL        *mysql;
    2198             :         zval            *mysql_link;
    2199             :         char            *dbname;
    2200             :         size_t                  dbname_len;
    2201             : 
    2202          49 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &dbname, &dbname_len) == FAILURE) {
    2203           3 :                 return;
    2204             :         }
    2205          46 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    2206             : 
    2207          45 :         if (mysql_select_db(mysql->mysql, dbname)) {
    2208           8 :                 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
    2209           8 :                 RETURN_FALSE;
    2210             :         }
    2211          37 :         RETURN_TRUE;
    2212             : }
    2213             : /* }}} */
    2214             : 
    2215             : /* {{{ proto string mysqli_sqlstate(object link)
    2216             :    Returns the SQLSTATE error from previous MySQL operation */
    2217          16 : PHP_FUNCTION(mysqli_sqlstate)
    2218             : {
    2219             :         MY_MYSQL        *mysql;
    2220             :         zval            *mysql_link;
    2221             :         const char      *state;
    2222             : 
    2223          16 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
    2224           3 :                 return;
    2225             :         }
    2226          13 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    2227           6 :         state = mysql_sqlstate(mysql->mysql);
    2228           6 :         if (state) {
    2229          12 :                 RETURN_STRING(state);
    2230             :         }
    2231             : }
    2232             : /* }}} */
    2233             : 
    2234             : /* {{{ proto bool mysqli_ssl_set(object link ,string key ,string cert ,string ca ,string capath ,string cipher]) U
    2235             : */
    2236           9 : PHP_FUNCTION(mysqli_ssl_set)
    2237             : {
    2238             :         MY_MYSQL        *mysql;
    2239             :         zval            *mysql_link;
    2240             :         char            *ssl_parm[5];
    2241             :         size_t                  ssl_parm_len[5], i;
    2242             : 
    2243           9 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Osssss", &mysql_link, mysqli_link_class_entry, &ssl_parm[0], &ssl_parm_len[0], &ssl_parm[1], &ssl_parm_len[1], &ssl_parm[2], &ssl_parm_len[2], &ssl_parm[3], &ssl_parm_len[3], &ssl_parm[4], &ssl_parm_len[4])   == FAILURE) {
    2244           6 :                 return;
    2245             :         }
    2246           3 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_INITIALIZED);
    2247             : 
    2248          18 :         for (i = 0; i < 5; i++) {
    2249          15 :                 if (!ssl_parm_len[i]) {
    2250          10 :                         ssl_parm[i] = NULL;
    2251             :                 }
    2252             :         }
    2253             : 
    2254           3 :         mysql_ssl_set(mysql->mysql, ssl_parm[0], ssl_parm[1], ssl_parm[2], ssl_parm[3], ssl_parm[4]);
    2255             : 
    2256           3 :         RETURN_TRUE;
    2257             : }
    2258             : /* }}} */
    2259             : 
    2260             : /* {{{ proto mixed mysqli_stat(object link)
    2261             :    Get current system status */
    2262          11 : PHP_FUNCTION(mysqli_stat)
    2263             : {
    2264             :         MY_MYSQL        *mysql;
    2265             :         zval            *mysql_link;
    2266             : #if defined(MYSQLI_USE_MYSQLND)
    2267             :         zend_string *stat;
    2268             : #else
    2269             :         char            *stat;
    2270             : #endif
    2271             : 
    2272          11 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
    2273           3 :                 return;
    2274             :         }
    2275           8 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    2276             : 
    2277             : #if !defined(MYSQLI_USE_MYSQLND)
    2278             :         if ((stat = (char *)mysql_stat(mysql->mysql)))
    2279             :         {
    2280             :                 RETURN_STRING(stat);
    2281             : #else
    2282           7 :         if (mysqlnd_stat(mysql->mysql, &stat) == PASS)
    2283             :         {
    2284           7 :                 RETURN_STR(stat);
    2285             : #endif
    2286             :         } else {
    2287           0 :                 RETURN_FALSE;
    2288             :         }
    2289             : }
    2290             : 
    2291             : /* }}} */
    2292             : 
    2293             : /* {{{ proto bool mysqli_refresh(object link, long options)
    2294             :    Flush tables or caches, or reset replication server information */
    2295           0 : PHP_FUNCTION(mysqli_refresh)
    2296             : {
    2297             :         MY_MYSQL *mysql;
    2298           0 :         zval *mysql_link = NULL;
    2299             :         zend_long options;
    2300             : 
    2301           0 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_link, mysqli_link_class_entry, &options) == FAILURE) {
    2302           0 :                 return;
    2303             :         }
    2304           0 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_INITIALIZED);
    2305             : #ifdef MYSQLI_USE_MYSQLND
    2306           0 :         RETURN_BOOL(!mysql_refresh(mysql->mysql, (uint8_t) options));
    2307             : #else
    2308             :         RETURN_BOOL(!mysql_refresh(mysql->mysql, options));
    2309             : #endif
    2310             : }
    2311             : /* }}} */
    2312             : 
    2313             : /* {{{ proto int mysqli_stmt_attr_set(object stmt, long attr, long mode)
    2314             : */
    2315        1116 : PHP_FUNCTION(mysqli_stmt_attr_set)
    2316             : {
    2317             :         MY_STMT *stmt;
    2318             :         zval    *mysql_stmt;
    2319             :         zend_long       mode_in;
    2320             : #if MYSQL_VERSION_ID >= 50107
    2321             :         my_bool mode_b;
    2322             : #endif
    2323             :         zend_ulong      mode;
    2324             :         zend_long       attr;
    2325             :         void    *mode_p;
    2326             : 
    2327        1116 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll", &mysql_stmt, mysqli_stmt_class_entry, &attr, &mode_in) == FAILURE) {
    2328           4 :                 return;
    2329             :         }
    2330        1112 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
    2331             : 
    2332        1111 :         if (mode_in < 0) {
    2333           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "mode should be non-negative, %pd passed", mode_in);
    2334           0 :                 RETURN_FALSE;
    2335             :         }
    2336             : 
    2337        1111 :         switch (attr) {
    2338             : #if MYSQL_VERSION_ID >= 50107
    2339             :         case STMT_ATTR_UPDATE_MAX_LENGTH:
    2340             :                 mode_b = (my_bool) mode_in;
    2341             :                 mode_p = &mode_b;
    2342             :                 break;
    2343             : #endif
    2344             :         default:
    2345        1111 :                 mode = mode_in;
    2346        1111 :                 mode_p = &mode;
    2347             :                 break;
    2348             :         }
    2349             : #if !defined(MYSQLI_USE_MYSQLND)
    2350             :         if (mysql_stmt_attr_set(stmt->stmt, attr, mode_p)) {
    2351             : #else
    2352        1111 :         if (FAIL == mysql_stmt_attr_set(stmt->stmt, attr, mode_p)) {
    2353             : #endif
    2354        1101 :                 RETURN_FALSE;
    2355             :         }
    2356          10 :         RETURN_TRUE;
    2357             : }
    2358             : /* }}} */
    2359             : 
    2360             : /* {{{ proto int mysqli_stmt_attr_get(object stmt, long attr)
    2361             : */
    2362          13 : PHP_FUNCTION(mysqli_stmt_attr_get)
    2363             : {
    2364             :         MY_STMT *stmt;
    2365             :         zval    *mysql_stmt;
    2366          13 :         zend_ulong      value = 0;
    2367             :         zend_long       attr;
    2368             :         int             rc;
    2369             : 
    2370          13 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_stmt, mysqli_stmt_class_entry, &attr) == FAILURE) {
    2371           4 :                 return;
    2372             :         }
    2373           9 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
    2374             : 
    2375           6 :         if ((rc = mysql_stmt_attr_get(stmt->stmt, attr, &value))) {
    2376           1 :                 RETURN_FALSE;
    2377             :         }
    2378             : 
    2379             : #if MYSQL_VERSION_ID >= 50107
    2380             :         if (attr == STMT_ATTR_UPDATE_MAX_LENGTH)
    2381             :                 value = *((my_bool *)&value);
    2382             : #endif
    2383           5 :         RETURN_LONG((zend_ulong)value);
    2384             : }
    2385             : /* }}} */
    2386             : 
    2387             : /* {{{ proto int mysqli_stmt_errno(object stmt)
    2388             : */
    2389          11 : PHP_FUNCTION(mysqli_stmt_errno)
    2390             : {
    2391             :         MY_STMT *stmt;
    2392             :         zval    *mysql_stmt;
    2393             : 
    2394          11 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
    2395           2 :                 return;
    2396             :         }
    2397           9 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_INITIALIZED);
    2398             : 
    2399           8 :         RETURN_LONG(mysql_stmt_errno(stmt->stmt));
    2400             : }
    2401             : /* }}} */
    2402             : 
    2403             : /* {{{ proto string mysqli_stmt_error(object stmt)
    2404             : */
    2405          10 : PHP_FUNCTION(mysqli_stmt_error)
    2406             : {
    2407             :         MY_STMT *stmt;
    2408             :         zval    *mysql_stmt;
    2409             :         const char * err;
    2410             : 
    2411          10 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
    2412           2 :                 return;
    2413             :         }
    2414           8 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_INITIALIZED);
    2415             : 
    2416           7 :         err = mysql_stmt_error(stmt->stmt);
    2417           7 :         if (err) {
    2418          14 :                 RETURN_STRING(err);
    2419             :         }
    2420             : }
    2421             : /* }}} */
    2422             : 
    2423             : /* {{{ proto mixed mysqli_stmt_init(object link)
    2424             :    Initialize statement object
    2425             : */
    2426         830 : PHP_FUNCTION(mysqli_stmt_init)
    2427             : {
    2428             :         MY_MYSQL                *mysql;
    2429             :         MY_STMT                 *stmt;
    2430             :         zval                    *mysql_link;
    2431             :         MYSQLI_RESOURCE *mysqli_resource;
    2432             : 
    2433         830 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",&mysql_link, mysqli_link_class_entry) == FAILURE) {
    2434           3 :                 return;
    2435             :         }
    2436         827 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    2437             : 
    2438         826 :         stmt = (MY_STMT *)ecalloc(1,sizeof(MY_STMT));
    2439             : 
    2440         826 :         if (!(stmt->stmt = mysql_stmt_init(mysql->mysql))) {
    2441           0 :                 efree(stmt);
    2442           0 :                 RETURN_FALSE;
    2443             :         }
    2444             : #ifndef MYSQLI_USE_MYSQLND
    2445             :         ZVAL_COPY(&stmt->link_handle, mysql_link);
    2446             : #endif
    2447             : 
    2448         826 :         mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
    2449         826 :         mysqli_resource->status = MYSQLI_STATUS_INITIALIZED;
    2450         826 :         mysqli_resource->ptr = (void *)stmt;
    2451         826 :         MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_stmt_class_entry);
    2452             : }
    2453             : /* }}} */
    2454             : 
    2455             : /* {{{ proto bool mysqli_stmt_prepare(object stmt, string query)
    2456             :    prepare server side statement with query
    2457             : */
    2458        3259 : PHP_FUNCTION(mysqli_stmt_prepare)
    2459             : {
    2460             :         MY_STMT *stmt;
    2461             :         zval    *mysql_stmt;
    2462             :         char    *query;
    2463             :         size_t          query_len;
    2464             : 
    2465        3259 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_stmt, mysqli_stmt_class_entry, &query, &query_len) == FAILURE) {
    2466           5 :                 return;
    2467             :         }
    2468        3254 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_INITIALIZED);
    2469             : 
    2470        3252 :         if (mysql_stmt_prepare(stmt->stmt, query, query_len)) {
    2471          10 :                 MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
    2472          10 :                 RETURN_FALSE;
    2473             :         }
    2474             :         /* change status */
    2475        3242 :         MYSQLI_SET_STATUS(mysql_stmt, MYSQLI_STATUS_VALID);
    2476        3242 :         RETURN_TRUE;
    2477             : }
    2478             : /* }}} */
    2479             : 
    2480             : /* {{{ proto mixed mysqli_stmt_result_metadata(object stmt)
    2481             :    return result set from statement */
    2482         221 : PHP_FUNCTION(mysqli_stmt_result_metadata)
    2483             : {
    2484             :         MY_STMT                 *stmt;
    2485             :         MYSQL_RES               *result;
    2486             :         zval                    *mysql_stmt;
    2487             :         MYSQLI_RESOURCE *mysqli_resource;
    2488             : 
    2489         221 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
    2490           3 :                 return;
    2491             :         }
    2492         218 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
    2493             : 
    2494         216 :         if (!(result = mysql_stmt_result_metadata(stmt->stmt))){
    2495           0 :                 MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
    2496           0 :                 RETURN_FALSE;
    2497             :         }
    2498             : 
    2499         216 :         mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
    2500         216 :         mysqli_resource->ptr = (void *)result;
    2501         216 :         mysqli_resource->status = MYSQLI_STATUS_VALID;
    2502         216 :         MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
    2503             : }
    2504             : /* }}} */
    2505             : 
    2506             : /* {{{ proto bool mysqli_stmt_store_result(stmt)
    2507             : */
    2508          60 : PHP_FUNCTION(mysqli_stmt_store_result)
    2509             : {
    2510             :         MY_STMT *stmt;
    2511             :         zval    *mysql_stmt;
    2512             : 
    2513          60 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
    2514           2 :                 return;
    2515             :         }
    2516          58 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
    2517             : 
    2518             : #if !defined(MYSQLI_USE_MYSQLND)
    2519             :         {
    2520             :                 /*
    2521             :                   If the user wants to store the data and we have BLOBs/TEXTs we try to allocate
    2522             :                   not the maximal length of the type (which is 16MB even for LONGBLOB) but
    2523             :                   the maximal length of the field in the result set. If he/she has quite big
    2524             :                   BLOB/TEXT columns after calling store_result() the memory usage of PHP will
    2525             :                   double - but this is a known problem of the simple MySQL API ;)
    2526             :                 */
    2527             :                 int     i = 0;
    2528             : 
    2529             :                 for (i = mysql_stmt_field_count(stmt->stmt) - 1; i >=0; --i) {
    2530             :                         if (stmt->stmt->fields && (stmt->stmt->fields[i].type == MYSQL_TYPE_BLOB ||
    2531             :                                 stmt->stmt->fields[i].type == MYSQL_TYPE_MEDIUM_BLOB ||
    2532             :                                 stmt->stmt->fields[i].type == MYSQL_TYPE_LONG_BLOB ||
    2533             :                                 stmt->stmt->fields[i].type == MYSQL_TYPE_GEOMETRY))
    2534             :                         {
    2535             : #if MYSQL_VERSION_ID >= 50107
    2536             :                                 my_bool tmp=1;
    2537             : #else
    2538             :                                 uint tmp=1;
    2539             : #endif
    2540             :                                 mysql_stmt_attr_set(stmt->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &tmp);
    2541             :                                 break;
    2542             :                         }
    2543             :                 }
    2544             :         }
    2545             : #endif
    2546             : 
    2547          55 :         if (mysql_stmt_store_result(stmt->stmt)){
    2548           3 :                 MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
    2549           3 :                 RETURN_FALSE;
    2550             :         }
    2551          52 :         RETURN_TRUE;
    2552             : }
    2553             : /* }}} */
    2554             : 
    2555             : /* {{{ proto string mysqli_stmt_sqlstate(object stmt)
    2556             : */
    2557           8 : PHP_FUNCTION(mysqli_stmt_sqlstate)
    2558             : {
    2559             :         MY_STMT *stmt;
    2560             :         zval    *mysql_stmt;
    2561             :         const char * state;
    2562             : 
    2563           8 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
    2564           3 :                 return;
    2565             :         }
    2566           5 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
    2567             : 
    2568           3 :         state = mysql_stmt_sqlstate(stmt->stmt);
    2569           3 :         if (state) {
    2570           6 :                 RETURN_STRING(state);
    2571             :         }
    2572             : }
    2573             : /* }}} */
    2574             : 
    2575             : /* {{{ proto object mysqli_store_result(object link [, flags])
    2576             :    Buffer result set on client */
    2577          66 : PHP_FUNCTION(mysqli_store_result)
    2578             : {
    2579             :         MY_MYSQL                *mysql;
    2580             :         MYSQL_RES               *result;
    2581             :         zval                    *mysql_link;
    2582             :         MYSQLI_RESOURCE *mysqli_resource;
    2583          66 :         zend_long flags = 0;
    2584             : 
    2585             : 
    2586          66 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &mysql_link, mysqli_link_class_entry, &flags) == FAILURE) {
    2587           2 :                 return;
    2588             :         }
    2589          64 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    2590             : #if MYSQLI_USE_MYSQLND
    2591          63 :         result = flags & MYSQLI_STORE_RESULT_COPY_DATA? mysqlnd_store_result_ofs(mysql->mysql) : mysqlnd_store_result(mysql->mysql);
    2592             : #else
    2593             :         result = mysql_store_result(mysql->mysql);
    2594             : #endif
    2595          63 :         if (!result) {
    2596          15 :                 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
    2597          15 :                 RETURN_FALSE;
    2598             :         }
    2599          48 :         if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
    2600           0 :                 php_mysqli_report_index("from previous query", mysqli_server_status(mysql->mysql) TSRMLS_CC);
    2601             :         }
    2602             : 
    2603          48 :         mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
    2604          48 :         mysqli_resource->ptr = (void *)result;
    2605          48 :         mysqli_resource->status = MYSQLI_STATUS_VALID;
    2606          48 :         MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
    2607             : }
    2608             : /* }}} */
    2609             : 
    2610             : /* {{{ proto int mysqli_thread_id(object link)
    2611             :    Return the current thread ID */
    2612          79 : PHP_FUNCTION(mysqli_thread_id)
    2613             : {
    2614             :         MY_MYSQL        *mysql;
    2615             :         zval            *mysql_link;
    2616             : 
    2617          79 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
    2618           2 :                 return;
    2619             :         }
    2620          77 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    2621             : 
    2622          68 :         RETURN_LONG((zend_long) mysql_thread_id(mysql->mysql));
    2623             : }
    2624             : /* }}} */
    2625             : 
    2626             : /* {{{ proto bool mysqli_thread_safe(void)
    2627             :    Return whether thread safety is given or not */
    2628           2 : PHP_FUNCTION(mysqli_thread_safe)
    2629             : {
    2630           2 :         RETURN_BOOL(mysql_thread_safe());
    2631             : }
    2632             : /* }}} */
    2633             : 
    2634             : /* {{{ proto mixed mysqli_use_result(object link)
    2635             :    Directly retrieve query results - do not buffer results on client side */
    2636          23 : PHP_FUNCTION(mysqli_use_result)
    2637             : {
    2638             :         MY_MYSQL                *mysql;
    2639             :         MYSQL_RES               *result;
    2640             :         zval                    *mysql_link;
    2641             :         MYSQLI_RESOURCE *mysqli_resource;
    2642             : 
    2643          23 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
    2644           2 :                 return;
    2645             :         }
    2646          21 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    2647             : 
    2648          20 :         if (!(result = mysql_use_result(mysql->mysql))) {
    2649           3 :                 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
    2650           3 :                 RETURN_FALSE;
    2651             :         }
    2652             : 
    2653          17 :         if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
    2654           0 :                 php_mysqli_report_index("from previous query", mysqli_server_status(mysql->mysql) TSRMLS_CC);
    2655             :         }
    2656          17 :         mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
    2657          17 :         mysqli_resource->ptr = (void *)result;
    2658          17 :         mysqli_resource->status = MYSQLI_STATUS_VALID;
    2659          17 :         MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
    2660             : }
    2661             : /* }}} */
    2662             : 
    2663             : /* {{{ proto int mysqli_warning_count (object link)
    2664             :    Return number of warnings from the last query for the given link */
    2665          16 : PHP_FUNCTION(mysqli_warning_count)
    2666             : {
    2667             :         MY_MYSQL        *mysql;
    2668             :         zval            *mysql_link;
    2669             : 
    2670          16 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
    2671           3 :                 return;
    2672             :         }
    2673          13 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    2674             : 
    2675           6 :         RETURN_LONG(mysql_warning_count(mysql->mysql));
    2676             : }
    2677             : /* }}} */
    2678             : 
    2679             : /*
    2680             :  * Local variables:
    2681             :  * tab-width: 4
    2682             :  * c-basic-offset: 4
    2683             :  * End:
    2684             :  * vim600: noet sw=4 ts=4 fdm=marker
    2685             :  * vim<600: noet sw=4 ts=4
    2686             :  */

Generated by: LCOV version 1.10

Generated at Wed, 22 Oct 2014 07:24:51 +0000 (18 hours ago)

Copyright © 2005-2014 The PHP Group
All rights reserved.