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

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