root/ext/mysqli/mysqli_api.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mysqli_tx_cor_options_to_string
  2. mysqli_escape_string_for_tx_name_in_comment
  3. mysqli_commit_or_rollback_libmysql
  4. PHP_FUNCTION
  5. PHP_FUNCTION
  6. mysqli_stmt_bind_param_do_bind
  7. mysqli_stmt_bind_param_do_bind
  8. PHP_FUNCTION
  9. mysqli_stmt_bind_result_do_bind
  10. mysqli_stmt_bind_result_do_bind
  11. PHP_FUNCTION
  12. PHP_FUNCTION
  13. PHP_FUNCTION
  14. php_mysqli_close
  15. PHP_FUNCTION
  16. PHP_FUNCTION
  17. PHP_FUNCTION
  18. PHP_FUNCTION
  19. PHP_FUNCTION
  20. PHP_FUNCTION
  21. PHP_FUNCTION
  22. PHP_FUNCTION
  23. mysqli_stmt_fetch_libmysql
  24. mysqli_stmt_fetch_mysqlnd
  25. PHP_FUNCTION
  26. php_add_field_properties
  27. PHP_FUNCTION
  28. PHP_FUNCTION
  29. PHP_FUNCTION
  30. PHP_FUNCTION
  31. PHP_FUNCTION
  32. PHP_FUNCTION
  33. PHP_FUNCTION
  34. PHP_FUNCTION
  35. PHP_FUNCTION
  36. PHP_FUNCTION
  37. PHP_FUNCTION
  38. PHP_FUNCTION
  39. PHP_FUNCTION
  40. PHP_FUNCTION
  41. PHP_FUNCTION
  42. PHP_FUNCTION
  43. php_mysqli_init
  44. PHP_FUNCTION
  45. PHP_FUNCTION
  46. PHP_FUNCTION
  47. PHP_FUNCTION
  48. PHP_FUNCTION
  49. PHP_FUNCTION
  50. PHP_FUNCTION
  51. PHP_FUNCTION
  52. PHP_FUNCTION
  53. PHP_FUNCTION
  54. mysqli_options_get_option_zval_type
  55. PHP_FUNCTION
  56. PHP_FUNCTION
  57. PHP_FUNCTION
  58. PHP_FUNCTION
  59. PHP_FUNCTION
  60. PHP_FUNCTION
  61. PHP_FUNCTION
  62. PHP_FUNCTION
  63. PHP_FUNCTION
  64. PHP_FUNCTION
  65. PHP_FUNCTION
  66. PHP_FUNCTION
  67. PHP_FUNCTION
  68. PHP_FUNCTION
  69. PHP_FUNCTION
  70. PHP_FUNCTION
  71. PHP_FUNCTION
  72. PHP_FUNCTION
  73. PHP_FUNCTION
  74. PHP_FUNCTION
  75. PHP_FUNCTION
  76. PHP_FUNCTION
  77. PHP_FUNCTION
  78. PHP_FUNCTION
  79. PHP_FUNCTION
  80. PHP_FUNCTION
  81. PHP_FUNCTION
  82. PHP_FUNCTION
  83. PHP_FUNCTION
  84. PHP_FUNCTION
  85. PHP_FUNCTION
  86. PHP_FUNCTION
  87. PHP_FUNCTION
  88. PHP_FUNCTION
  89. PHP_FUNCTION
  90. PHP_FUNCTION

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

/* [<][>][^][v][top][bottom][index][help] */