Back to index

php5  5.3.10
mysqli_api.c
Go to the documentation of this file.
00001 /*
00002   +----------------------------------------------------------------------+
00003   | PHP Version 5                                                        |
00004   +----------------------------------------------------------------------+
00005   | Copyright (c) 1997-2012 The PHP Group                                |
00006   +----------------------------------------------------------------------+
00007   | This source file is subject to version 3.01 of the PHP license,      |
00008   | that is bundled with this package in the file LICENSE, and is        |
00009   | available through the world-wide-web at the following url:           |
00010   | http://www.php.net/license/3_01.txt                                  |
00011   | If you did not receive a copy of the PHP license and are unable to   |
00012   | obtain it through the world-wide-web, please send a note to          |
00013   | license@php.net so we can mail you a copy immediately.               |
00014   +----------------------------------------------------------------------+
00015   | Authors: Georg Richter <georg@php.net>                               |
00016   |          Andrey Hristov <andrey@php.net>                             |
00017   |          Ulf Wendel <uw@php.net>                                     |
00018   +----------------------------------------------------------------------+
00019 
00020   $Id: mysqli_api.c 321634 2012-01-01 13:15:04Z felipe $
00021 */
00022 
00023 #ifdef HAVE_CONFIG_H
00024 #include "config.h"
00025 #endif
00026 
00027 #include <signal.h>
00028 
00029 #include "php.h"
00030 #include "php_ini.h"
00031 #include "php_globals.h"
00032 #include "ext/standard/info.h"
00033 #include "php_mysqli_structs.h"
00034 #include "mysqli_priv.h"
00035 
00036 /* {{{ proto mixed mysqli_affected_rows(object link)
00037    Get number of affected rows in previous MySQL operation */
00038 PHP_FUNCTION(mysqli_affected_rows)
00039 {
00040        MY_MYSQL             *mysql;
00041        zval                 *mysql_link;
00042        my_ulonglong  rc;
00043 
00044        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
00045               return;
00046        }
00047 
00048        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
00049 
00050        rc = mysql_affected_rows(mysql->mysql);
00051        if (rc == (my_ulonglong) -1) {
00052               RETURN_LONG(-1);
00053        }
00054        MYSQLI_RETURN_LONG_LONG(rc);
00055 }
00056 /* }}} */
00057 
00058 
00059 /* {{{ proto bool mysqli_autocommit(object link, bool mode)
00060    Turn auto commit on or of */
00061 PHP_FUNCTION(mysqli_autocommit)
00062 {
00063        MY_MYSQL      *mysql;
00064        zval          *mysql_link;
00065        zend_bool     automode;
00066 
00067        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ob", &mysql_link, mysqli_link_class_entry, &automode) == FAILURE) {
00068               return;
00069        }
00070        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
00071 
00072        if (mysql_autocommit(mysql->mysql, (my_bool)automode)) {
00073               RETURN_FALSE;
00074        }
00075        RETURN_TRUE;
00076 }
00077 /* }}} */
00078 
00079 /* {{{ mysqli_stmt_bind_param_do_bind */
00080 #ifndef MYSQLI_USE_MYSQLND
00081 static
00082 int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int argc, unsigned int num_vars,
00083                                                            zval ***args, unsigned int start, const char * const types TSRMLS_DC)
00084 {
00085        int                         i, ofs;
00086        MYSQL_BIND           *bind;
00087        unsigned long rc;
00088 
00089        /* prevent leak if variables are already bound */
00090        if (stmt->param.var_cnt) {
00091               php_free_stmt_bind_buffer(stmt->param, FETCH_SIMPLE);
00092        }
00093 
00094        stmt->param.is_null = ecalloc(num_vars, sizeof(char));
00095        bind = (MYSQL_BIND *) ecalloc(num_vars, sizeof(MYSQL_BIND));
00096 
00097        ofs = 0;
00098        for (i = start; i < argc; i++) {
00099 
00100               /* set specified type */
00101               switch (types[ofs]) {
00102                      case 'd': /* Double */
00103                             bind[ofs].buffer_type = MYSQL_TYPE_DOUBLE;
00104                             bind[ofs].buffer = &Z_DVAL_PP(args[i]);
00105                             bind[ofs].is_null = &stmt->param.is_null[ofs];
00106                             break;
00107 
00108                      case 'i': /* Integer */
00109 #if SIZEOF_LONG==8
00110                             bind[ofs].buffer_type = MYSQL_TYPE_LONGLONG;
00111 #elif SIZEOF_LONG==4
00112                             bind[ofs].buffer_type = MYSQL_TYPE_LONG;
00113 #endif
00114                             bind[ofs].buffer = &Z_LVAL_PP(args[i]);
00115                             bind[ofs].is_null = &stmt->param.is_null[ofs];
00116                             break;
00117 
00118                      case 'b': /* Blob (send data) */
00119                             bind[ofs].buffer_type = MYSQL_TYPE_LONG_BLOB;
00120                             /* don't initialize is_null and length to 0 because we use ecalloc */
00121                             break;
00122 
00123                      case 's': /* string */
00124                             bind[ofs].buffer_type = MYSQL_TYPE_VAR_STRING;
00125                             /* don't initialize buffer and buffer_length because we use ecalloc */
00126                             bind[ofs].is_null = &stmt->param.is_null[ofs];
00127                             break;
00128 
00129                      default:
00130                             php_error_docref(NULL TSRMLS_CC, E_WARNING, "Undefined fieldtype %c (parameter %d)", types[ofs], i+1);
00131                             rc = 1;
00132                             goto end_1;
00133               }
00134               ofs++;
00135        }
00136        rc = mysql_stmt_bind_param(stmt->stmt, bind);
00137 
00138 end_1:
00139        if (rc) {
00140               efree(stmt->param.is_null);
00141        } else {
00142               stmt->param.var_cnt = num_vars;
00143               stmt->param.vars = (zval **)safe_emalloc(num_vars, sizeof(zval), 0);
00144               for (i = 0; i < num_vars; i++) {
00145                      if (bind[i].buffer_type  != MYSQL_TYPE_LONG_BLOB) {
00146                             Z_ADDREF_P(*args[i+start]);
00147                             stmt->param.vars[i] = *args[i+start];
00148                      } else {
00149                             stmt->param.vars[i] = NULL;
00150                      }
00151               }
00152        }
00153        efree(bind);
00154 
00155        return rc;
00156 }
00157 #else
00158 static
00159 int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int argc, unsigned int num_vars,
00160                                                            zval ***args, unsigned int start, const char * const types TSRMLS_DC)
00161 {
00162        unsigned int i;
00163        MYSQLND_PARAM_BIND   *params;
00164        enum_func_status     ret = FAIL;
00165 
00166        /* If no params -> skip binding and return directly */
00167        if (argc == start) {
00168               return PASS;
00169        }
00170        params = mysqlnd_stmt_alloc_param_bind(stmt->stmt);
00171        if (!params) {
00172               goto end;
00173        }
00174        for (i = 0; i < (argc - start); i++) {
00175               zend_uchar type;
00176               switch (types[i]) {
00177                      case 'd': /* Double */
00178                             type = MYSQL_TYPE_DOUBLE;
00179                             break;
00180                      case 'i': /* Integer */
00181 #if SIZEOF_LONG==8
00182                             type = MYSQL_TYPE_LONGLONG;
00183 #elif SIZEOF_LONG==4
00184                             type = MYSQL_TYPE_LONG;
00185 #endif
00186                             break;
00187                      case 'b': /* Blob (send data) */
00188                             type = MYSQL_TYPE_LONG_BLOB;
00189                             break;
00190                      case 's': /* string */
00191                             type = MYSQL_TYPE_VAR_STRING;
00192                             break;
00193                      default:
00194                             /* We count parameters from 1 */
00195                             php_error_docref(NULL TSRMLS_CC, E_WARNING, "Undefined fieldtype %c (parameter %d)", types[i], i + start + 1);
00196                             ret = FAIL;
00197                             mysqlnd_stmt_free_param_bind(stmt->stmt, params);
00198                             goto end;
00199               }
00200               params[i].zv = *(args[i + start]);
00201               params[i].type = type;
00202        }
00203        ret = mysqlnd_stmt_bind_param(stmt->stmt, params);
00204 
00205 end:
00206        return ret;
00207 }
00208 #endif
00209 /* }}} */
00210 
00211 /* {{{ proto bool mysqli_stmt_bind_param(object stmt, string types, mixed variable [,mixed,....]) U
00212    Bind variables to a prepared statement as parameters */
00213 PHP_FUNCTION(mysqli_stmt_bind_param)
00214 {
00215        zval                 ***args;
00216        int                         argc = ZEND_NUM_ARGS();
00217        int                         num_vars;
00218        int                         start = 2;
00219        MY_STMT                     *stmt;
00220        zval                 *mysql_stmt;
00221        char                 *types;
00222        int                         types_len;
00223        unsigned long rc;
00224 
00225        /* calculate and check number of parameters */
00226        if (argc < 2) {
00227               /* there has to be at least one pair */
00228               WRONG_PARAM_COUNT;
00229        }
00230 
00231        if (zend_parse_method_parameters((getThis()) ? 1:2 TSRMLS_CC, getThis(), "Os", &mysql_stmt, mysqli_stmt_class_entry,
00232                                                                &types, &types_len) == FAILURE) {
00233               return;
00234        }
00235 
00236        MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
00237 
00238        num_vars = argc - 1;
00239        if (getThis()) {
00240               start = 1;
00241        } else {
00242               /* ignore handle parameter in procedural interface*/
00243               --num_vars;
00244        }
00245        if (!types_len) {
00246               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid type or no types specified");
00247               RETURN_FALSE;
00248        }
00249 
00250        if (types_len != argc - start) {
00251               /* number of bind variables doesn't match number of elements in type definition string */
00252               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of elements in type definition string doesn't match number of bind variables");
00253               RETURN_FALSE;
00254        }
00255 
00256        if (types_len != mysql_stmt_param_count(stmt->stmt)) {
00257               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of variables doesn't match number of parameters in prepared statement");
00258               RETURN_FALSE;
00259        }
00260 
00261        args = (zval ***)safe_emalloc(argc, sizeof(zval **), 0);
00262 
00263        if (zend_get_parameters_array_ex(argc, args) == FAILURE) {
00264               zend_wrong_param_count(TSRMLS_C);
00265               rc = 1;
00266        } else {
00267               rc = mysqli_stmt_bind_param_do_bind(stmt, argc, num_vars, args, start, types TSRMLS_CC);
00268               MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
00269        }
00270 
00271        efree(args);
00272 
00273        RETURN_BOOL(!rc);
00274 }
00275 /* }}} */
00276 
00277 /* {{{ mysqli_stmt_bind_result_do_bind */
00278 #ifndef MYSQLI_USE_MYSQLND
00279 /* TODO:
00280    do_alloca, free_alloca
00281 */
00282 static int
00283 mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval ***args, unsigned int argc, unsigned int start TSRMLS_DC)
00284 {
00285        MYSQL_BIND    *bind;
00286        int                  i, ofs;
00287        int                  var_cnt = argc - start;
00288        long          col_type;
00289        ulong         rc;
00290 
00291        /* prevent leak if variables are already bound */
00292        if (stmt->result.var_cnt) {
00293               php_free_stmt_bind_buffer(stmt->result, FETCH_RESULT);
00294        }
00295 
00296        bind = (MYSQL_BIND *)ecalloc(var_cnt, sizeof(MYSQL_BIND));
00297        {
00298               int size;
00299               char *p= emalloc(size= var_cnt * (sizeof(char) + sizeof(VAR_BUFFER)));
00300               stmt->result.buf = (VAR_BUFFER *) p;
00301               stmt->result.is_null = p + var_cnt * sizeof(VAR_BUFFER);
00302               memset(p, 0, size);
00303        }
00304 
00305        for (i=start; i < var_cnt + start ; i++) {
00306               ofs = i - start;
00307               col_type = (stmt->stmt->fields) ? stmt->stmt->fields[ofs].type : MYSQL_TYPE_STRING;
00308 
00309               switch (col_type) {
00310                      case MYSQL_TYPE_DOUBLE:
00311                      case MYSQL_TYPE_FLOAT:
00312                             convert_to_double_ex(args[i]);
00313                             stmt->result.buf[ofs].type = IS_DOUBLE;
00314                             stmt->result.buf[ofs].buflen = sizeof(double);
00315 
00316                             /* allocate buffer for double */
00317                             stmt->result.buf[ofs].val = (char *)emalloc(sizeof(double));
00318                             bind[ofs].buffer_type = MYSQL_TYPE_DOUBLE;
00319                             bind[ofs].buffer = stmt->result.buf[ofs].val;
00320                             bind[ofs].is_null = &stmt->result.is_null[ofs];
00321                             break;
00322 
00323                      case MYSQL_TYPE_NULL:
00324                             stmt->result.buf[ofs].type = IS_NULL;
00325                             /*
00326                               don't initialize to 0 :
00327                               1. stmt->result.buf[ofs].buflen
00328                               2. bind[ofs].buffer
00329                               3. bind[ofs].buffer_length
00330                               because memory was allocated with ecalloc
00331                             */
00332                             bind[ofs].buffer_type = MYSQL_TYPE_NULL;
00333                             bind[ofs].is_null = &stmt->result.is_null[ofs];
00334                             break;
00335 
00336                      case MYSQL_TYPE_SHORT:
00337                      case MYSQL_TYPE_TINY:
00338                      case MYSQL_TYPE_LONG:
00339                      case MYSQL_TYPE_INT24:
00340                      case MYSQL_TYPE_YEAR:
00341                             convert_to_long_ex(args[i]);
00342                             stmt->result.buf[ofs].type = IS_LONG;
00343                             /* don't set stmt->result.buf[ofs].buflen to 0, we used ecalloc */
00344                             stmt->result.buf[ofs].val = (char *)emalloc(sizeof(int));
00345                             bind[ofs].buffer_type = MYSQL_TYPE_LONG;
00346                             bind[ofs].buffer = stmt->result.buf[ofs].val;
00347                             bind[ofs].is_null = &stmt->result.is_null[ofs];
00348                             bind[ofs].is_unsigned = (stmt->stmt->fields[ofs].flags & UNSIGNED_FLAG) ? 1 : 0;
00349                             break;
00350 
00351                      case MYSQL_TYPE_LONGLONG:
00352 #if MYSQL_VERSION_ID > 50002 || defined(MYSQLI_USE_MYSQLND)
00353                      case MYSQL_TYPE_BIT:
00354 #endif
00355                             stmt->result.buf[ofs].type = IS_STRING;
00356                             stmt->result.buf[ofs].buflen = sizeof(my_ulonglong);
00357                             stmt->result.buf[ofs].val = (char *)emalloc(stmt->result.buf[ofs].buflen);
00358                             bind[ofs].buffer_type = col_type;
00359                             bind[ofs].buffer = stmt->result.buf[ofs].val;
00360                             bind[ofs].is_null = &stmt->result.is_null[ofs];
00361                             bind[ofs].buffer_length = stmt->result.buf[ofs].buflen;
00362                             bind[ofs].is_unsigned = (stmt->stmt->fields[ofs].flags & UNSIGNED_FLAG) ? 1 : 0;
00363                             bind[ofs].length = &stmt->result.buf[ofs].output_len;
00364                             break;
00365 
00366                      case MYSQL_TYPE_DATE:
00367                      case MYSQL_TYPE_TIME:
00368                      case MYSQL_TYPE_DATETIME:
00369                      case MYSQL_TYPE_NEWDATE:
00370                      case MYSQL_TYPE_VAR_STRING:
00371                      case MYSQL_TYPE_STRING:
00372                      case MYSQL_TYPE_TINY_BLOB:
00373                      case MYSQL_TYPE_BLOB:
00374                      case MYSQL_TYPE_MEDIUM_BLOB:
00375                      case MYSQL_TYPE_LONG_BLOB:
00376                      case MYSQL_TYPE_TIMESTAMP:
00377                      case MYSQL_TYPE_DECIMAL:
00378                      case MYSQL_TYPE_GEOMETRY:
00379 #ifdef FIELD_TYPE_NEWDECIMAL
00380                      case MYSQL_TYPE_NEWDECIMAL:
00381 #endif
00382                      {
00383 #if MYSQL_VERSION_ID >= 50107
00384                             /* Changed to my_bool in MySQL 5.1. See MySQL Bug #16144 */
00385                             my_bool tmp;
00386 #else
00387                             uint tmp = 0;
00388 #endif
00389                             stmt->result.buf[ofs].type = IS_STRING;
00390                             /*
00391                                    If the user has called $stmt->store_result() then we have asked
00392                                    max_length to be updated. this is done only for BLOBS because we don't want to allocate
00393                                    big chunkgs of memory 2^16 or 2^24
00394                             */
00395                             if (stmt->stmt->fields[ofs].max_length == 0 &&
00396                                    !mysql_stmt_attr_get(stmt->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &tmp) && !tmp)
00397                             {
00398                                    /*
00399                                      Allocate directly 256 because it's easier to allocate a bit more
00400                                      than update max length even for text columns. Try SELECT UNION SELECT UNION with
00401                                      different lengths and you will see that we get different lengths in stmt->stmt->fields[ofs].length
00402                                      The just take 256 and saves us from realloc-ing.
00403                                    */
00404                                    stmt->result.buf[ofs].buflen =
00405                                           (stmt->stmt->fields) ? (stmt->stmt->fields[ofs].length) ? stmt->stmt->fields[ofs].length + 1: 256: 256;
00406 
00407                             } else {
00408                                    /*
00409                                           the user has called store_result(). if he does not there is no way to determine the
00410                                           libmysql does not allow us to allocate 0 bytes for a buffer so we try 1
00411                                    */
00412                                    if (!(stmt->result.buf[ofs].buflen = stmt->stmt->fields[ofs].max_length))
00413                                           ++stmt->result.buf[ofs].buflen;
00414                             }
00415                             stmt->result.buf[ofs].val = (char *)emalloc(stmt->result.buf[ofs].buflen);
00416                             bind[ofs].buffer_type = MYSQL_TYPE_STRING;
00417                             bind[ofs].buffer = stmt->result.buf[ofs].val;
00418                             bind[ofs].is_null = &stmt->result.is_null[ofs];
00419                             bind[ofs].buffer_length = stmt->result.buf[ofs].buflen;
00420                             bind[ofs].length = &stmt->result.buf[ofs].output_len;
00421                             break;
00422                      }
00423                      default:
00424                             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);
00425                             break;
00426               }
00427        }
00428 
00429        rc = mysql_stmt_bind_result(stmt->stmt, bind);
00430        MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
00431 
00432        if (rc) {
00433               /* dont close the statement or subsequent usage (for example ->execute()) will lead to crash */
00434               for (i=0; i < var_cnt ; i++) {
00435                      if (stmt->result.buf[i].val) {
00436                             efree(stmt->result.buf[i].val);
00437                      }
00438               }
00439               /* Don't free stmt->result.is_null because is_null & buf are one block of memory  */
00440               efree(stmt->result.buf);
00441        } else {
00442               stmt->result.var_cnt = var_cnt;
00443               stmt->result.vars = (zval **)safe_emalloc((var_cnt), sizeof(zval), 0);
00444               for (i = start; i < var_cnt+start; i++) {
00445                      ofs = i-start;
00446                      Z_ADDREF_PP(args[i]);
00447                      stmt->result.vars[ofs] = *args[i];
00448               }
00449        }
00450        efree(bind);
00451 
00452        return rc;
00453 }
00454 #else
00455 static int
00456 mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval ***args, unsigned int argc, unsigned int start TSRMLS_DC)
00457 {
00458        unsigned int i;
00459        MYSQLND_RESULT_BIND * params = mysqlnd_stmt_alloc_result_bind(stmt->stmt);
00460        if (params) {
00461               for (i = 0; i < (argc - start); i++) {
00462                      params[i].zv = *(args[i + start]);
00463               }
00464               return mysqlnd_stmt_bind_result(stmt->stmt, params);
00465        }
00466        return FAIL;
00467 }
00468 #endif
00469 /* }}} */
00470 
00471 /* {{{ proto bool mysqli_stmt_bind_result(object stmt, mixed var, [,mixed, ...]) U
00472    Bind variables to a prepared statement for result storage */
00473 PHP_FUNCTION(mysqli_stmt_bind_result)
00474 {
00475        zval          ***args;
00476        int                  argc = ZEND_NUM_ARGS();
00477        int                  start = 1;
00478        ulong         rc;
00479        MY_STMT              *stmt;
00480        zval          *mysql_stmt;
00481 
00482        if (getThis()) {
00483               start = 0;
00484        }
00485 
00486        if (zend_parse_method_parameters((getThis()) ? 0:1 TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
00487               return;
00488        }
00489 
00490        MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
00491 
00492        if (argc < (getThis() ? 1 : 2)) {
00493               WRONG_PARAM_COUNT;
00494        }
00495 
00496        if ((argc - start) != mysql_stmt_field_count(stmt->stmt)) {
00497               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of bind variables doesn't match number of fields in prepared statement");
00498               RETURN_FALSE;
00499        }
00500 
00501        args = (zval ***)safe_emalloc(argc, sizeof(zval **), 0);
00502 
00503        if (zend_get_parameters_array_ex(argc, args) == FAILURE) {
00504               efree(args);
00505               WRONG_PARAM_COUNT;
00506        }
00507 
00508        rc = mysqli_stmt_bind_result_do_bind(stmt, args, argc, start TSRMLS_CC);
00509 
00510        efree(args);
00511 
00512        RETURN_BOOL(!rc);
00513 }
00514 /* }}} */
00515 
00516 /* {{{ proto bool mysqli_change_user(object link, string user, string password, string database)
00517    Change logged-in user of the active connection */
00518 PHP_FUNCTION(mysqli_change_user)
00519 {
00520        MY_MYSQL      *mysql;
00521        zval          *mysql_link = NULL;
00522        char          *user, *password, *dbname;
00523        int                  user_len, password_len, dbname_len;
00524        ulong         rc;
00525 #if !defined(MYSQLI_USE_MYSQLND) && defined(HAVE_MYSQLI_SET_CHARSET)
00526        const         CHARSET_INFO * old_charset;
00527 #endif
00528 
00529        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) {
00530               return;
00531        }
00532        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
00533 
00534 #if !defined(MYSQLI_USE_MYSQLND) && defined(HAVE_MYSQLI_SET_CHARSET)
00535        old_charset = mysql->mysql->charset;
00536 #endif
00537 
00538        rc = mysql_change_user(mysql->mysql, user, password, dbname);
00539        MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
00540 
00541        if (rc) {
00542               RETURN_FALSE;
00543        }
00544 #if !defined(MYSQLI_USE_MYSQLND) && defined(HAVE_MYSQLI_SET_CHARSET)
00545        if (mysql_get_server_version(mysql->mysql) < 501023L) {
00546               /*
00547                 Request the current charset, or it will be reset to the system one.
00548                 5.0 doesn't support it. Support added in 5.1.23 by fixing the following bug :
00549                 Bug #30472 libmysql doesn't reset charset, insert_id after succ. mysql_change_user() call
00550               */
00551               rc = mysql_set_character_set(mysql->mysql, old_charset->csname);
00552        }
00553 #endif
00554 
00555        RETURN_TRUE;
00556 }
00557 /* }}} */
00558 
00559 /* {{{ proto string mysqli_character_set_name(object link)
00560    Returns the name of the character set used for this connection */
00561 PHP_FUNCTION(mysqli_character_set_name)
00562 {
00563        MY_MYSQL      *mysql;
00564        zval          *mysql_link;
00565 
00566        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
00567               return;
00568        }
00569 
00570        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
00571 
00572        RETURN_STRING((char *)mysql_character_set_name(mysql->mysql), 1);
00573 }
00574 /* }}} */
00575 
00576 
00577 /* {{{ php_mysqli_close */
00578 void php_mysqli_close(MY_MYSQL * mysql, int close_type, int resource_status TSRMLS_DC)
00579 {
00580        if (resource_status > MYSQLI_STATUS_INITIALIZED) {
00581               MyG(num_links)--;
00582        }
00583 
00584        if (!mysql->persistent) {
00585               mysqli_close(mysql->mysql, close_type);
00586        } else {
00587               zend_rsrc_list_entry *le;
00588               if (zend_hash_find(&EG(persistent_list), mysql->hash_key, strlen(mysql->hash_key) + 1, (void **)&le) == SUCCESS) {
00589                      if (Z_TYPE_P(le) == php_le_pmysqli()) {
00590                             mysqli_plist_entry *plist = (mysqli_plist_entry *) le->ptr;
00591 #if defined(MYSQLI_USE_MYSQLND)
00592                             mysqlnd_end_psession(mysql->mysql);
00593 #endif
00594                             zend_ptr_stack_push(&plist->free_links, mysql->mysql);
00595 
00596                             MyG(num_active_persistent)--;
00597                             MyG(num_inactive_persistent)++;
00598                      }
00599               }
00600               mysql->persistent = FALSE;
00601        }
00602        mysql->mysql = NULL;
00603 
00604        php_clear_mysql(mysql);
00605 }
00606 /* }}} */
00607 
00608 
00609 /* {{{ proto bool mysqli_close(object link)
00610    Close connection */
00611 PHP_FUNCTION(mysqli_close)
00612 {
00613        zval          *mysql_link;
00614        MY_MYSQL      *mysql;
00615 
00616        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
00617               return;
00618        }
00619 
00620        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_INITIALIZED);
00621 
00622        php_mysqli_close(mysql, MYSQLI_CLOSE_EXPLICIT, ((MYSQLI_RESOURCE *)((mysqli_object *)zend_object_store_get_object(mysql_link TSRMLS_CC))->ptr)->status TSRMLS_CC);
00623        ((MYSQLI_RESOURCE *)((mysqli_object *)zend_object_store_get_object(mysql_link TSRMLS_CC))->ptr)->status = MYSQLI_STATUS_UNKNOWN;
00624 
00625        MYSQLI_CLEAR_RESOURCE(&mysql_link);
00626        efree(mysql);
00627        RETURN_TRUE;
00628 }
00629 /* }}} */
00630 
00631 /* {{{ proto bool mysqli_commit(object link)
00632    Commit outstanding actions and close transaction */
00633 PHP_FUNCTION(mysqli_commit)
00634 {
00635        MY_MYSQL      *mysql;
00636        zval          *mysql_link;
00637 
00638        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
00639               return;
00640        }
00641        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
00642        if (mysql_commit(mysql->mysql)) {
00643               RETURN_FALSE;
00644        }
00645        RETURN_TRUE;
00646 }
00647 /* }}} */
00648 
00649 /* {{{ proto bool mysqli_data_seek(object result, int offset)
00650    Move internal result pointer */
00651 PHP_FUNCTION(mysqli_data_seek)
00652 {
00653        MYSQL_RES     *result;
00654        zval          *mysql_result;
00655        long          offset;
00656 
00657        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_result, mysqli_result_class_entry, &offset) == FAILURE) {
00658               return;
00659        }
00660 
00661        MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
00662 
00663        if (mysqli_result_is_unbuffered(result)) {
00664               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function cannot be used with MYSQL_USE_RESULT");
00665               RETURN_FALSE;
00666        }
00667 
00668        if (offset < 0 || offset >= mysql_num_rows(result)) {
00669               RETURN_FALSE;
00670        }
00671 
00672        mysql_data_seek(result, offset);
00673        RETURN_TRUE;
00674 }
00675 /* }}} */
00676 
00677 /* {{{ proto void mysqli_debug(string debug) U
00678 */
00679 PHP_FUNCTION(mysqli_debug)
00680 {
00681        char   *debug;
00682        int           debug_len;
00683 
00684        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &debug, &debug_len) == FAILURE) {
00685               return;
00686        }
00687 
00688        mysql_debug(debug);
00689        RETURN_TRUE;
00690 }
00691 /* }}} */
00692 
00693 
00694 /* {{{ proto bool mysqli_dump_debug_info(object link)
00695 */
00696 PHP_FUNCTION(mysqli_dump_debug_info)
00697 {
00698        MY_MYSQL      *mysql;
00699        zval          *mysql_link;
00700 
00701        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
00702               return;
00703        }
00704        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
00705 
00706        RETURN_BOOL(!mysql_dump_debug_info(mysql->mysql))
00707 }
00708 /* }}} */
00709 
00710 /* {{{ proto int mysqli_errno(object link)
00711    Returns the numerical value of the error message from previous MySQL operation */
00712 PHP_FUNCTION(mysqli_errno)
00713 {
00714        MY_MYSQL      *mysql;
00715        zval          *mysql_link;
00716 
00717        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
00718               return;
00719        }
00720        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
00721        RETURN_LONG(mysql_errno(mysql->mysql));
00722 }
00723 /* }}} */
00724 
00725 /* {{{ proto string mysqli_error(object link)
00726    Returns the text of the error message from previous MySQL operation */
00727 PHP_FUNCTION(mysqli_error)
00728 {
00729        MY_MYSQL      *mysql;
00730        zval          *mysql_link;
00731 
00732        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
00733               return;
00734        }
00735        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
00736        RETURN_STRING((char *)mysql_error(mysql->mysql),1);
00737 }
00738 /* }}} */
00739 
00740 #ifndef MYSQLI_USE_MYSQLND
00741 /* {{{ php_mysqli_stmt_copy_it */
00742 static void
00743 php_mysqli_stmt_copy_it(zval *** copies, zval *original, uint param_count, uint current)
00744 {
00745        if (!*copies) {
00746               *copies = ecalloc(param_count, sizeof(zval *));
00747        }
00748        MAKE_STD_ZVAL((*copies)[current]);
00749        *(*copies)[current] = *original;
00750        Z_SET_REFCOUNT_P((*copies)[current], 1);
00751        zval_copy_ctor((*copies)[current]);
00752 }
00753 /* }}} */
00754 #endif
00755 
00756 /* {{{ proto bool mysqli_stmt_execute(object stmt)
00757    Execute a prepared statement */
00758 PHP_FUNCTION(mysqli_stmt_execute)
00759 {
00760        MY_STMT              *stmt;
00761        zval          *mysql_stmt;
00762 #ifndef MYSQLI_USE_MYSQLND
00763        unsigned int  i;
00764        zval          **copies = NULL;
00765 #endif
00766 
00767        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
00768               return;
00769        }
00770        MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
00771 
00772 #ifndef MYSQLI_USE_MYSQLND
00773        if (stmt->param.var_cnt) {
00774               int j;
00775               for (i = 0; i < stmt->param.var_cnt; i++) {
00776                      for (j = i + 1; j < stmt->param.var_cnt; j++) {
00777                             /* Oops, someone binding the same variable - clone */
00778                             if (stmt->param.vars[j] == stmt->param.vars[i] && stmt->param.vars[i]) {
00779                                    php_mysqli_stmt_copy_it(&copies, stmt->param.vars[i], stmt->param.var_cnt, i);
00780                                    break;
00781                             }
00782                      }
00783               }
00784        }
00785        for (i = 0; i < stmt->param.var_cnt; i++) {
00786               if (stmt->param.vars[i]) {
00787                      if ( !(stmt->param.is_null[i] = (stmt->param.vars[i]->type == IS_NULL)) ) {
00788                             zval *the_var = copies && copies[i]? copies[i]:stmt->param.vars[i];
00789                             switch (stmt->stmt->params[i].buffer_type) {
00790                                    case MYSQL_TYPE_VAR_STRING:
00791                                           if (the_var == stmt->param.vars[i] && Z_TYPE_P(stmt->param.vars[i]) != IS_STRING) {
00792                                                  php_mysqli_stmt_copy_it(&copies, stmt->param.vars[i], stmt->param.var_cnt, i);
00793                                                  the_var = copies[i];
00794                                           }
00795                                           convert_to_string_ex(&the_var);
00796                                           stmt->stmt->params[i].buffer = Z_STRVAL_P(the_var);
00797                                           stmt->stmt->params[i].buffer_length = Z_STRLEN_P(the_var);
00798                                           break;
00799                                    case MYSQL_TYPE_DOUBLE:
00800                                           if (the_var == stmt->param.vars[i] && Z_TYPE_P(stmt->param.vars[i]) != IS_DOUBLE) {
00801                                                  php_mysqli_stmt_copy_it(&copies, stmt->param.vars[i], stmt->param.var_cnt, i);
00802                                                  the_var = copies[i];
00803                                           }
00804                                           convert_to_double_ex(&the_var);
00805                                           stmt->stmt->params[i].buffer = &Z_DVAL_P(the_var);
00806                                           break;
00807                                    case MYSQL_TYPE_LONGLONG:
00808                                    case MYSQL_TYPE_LONG:
00809                                           if (the_var == stmt->param.vars[i] && Z_TYPE_P(stmt->param.vars[i]) != IS_LONG) {
00810                                                  php_mysqli_stmt_copy_it(&copies, stmt->param.vars[i], stmt->param.var_cnt, i);
00811                                                  the_var = copies[i];
00812                                           }
00813                                           convert_to_long_ex(&the_var);
00814                                           stmt->stmt->params[i].buffer = &Z_LVAL_P(the_var);
00815                                           break;
00816                                    default:
00817                                           break;
00818                             }
00819                      }
00820               }
00821        }
00822 #endif
00823 
00824        if (mysql_stmt_execute(stmt->stmt)) {
00825               MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
00826               RETVAL_FALSE;
00827        } else {
00828               RETVAL_TRUE;
00829        }
00830 
00831 #ifndef MYSQLI_USE_MYSQLND
00832        if (copies) {
00833               for (i = 0; i < stmt->param.var_cnt; i++) {
00834                      if (copies[i]) {
00835                             zval_ptr_dtor(&copies[i]);
00836                      }
00837               }
00838               efree(copies);
00839        }
00840 #endif
00841 
00842        if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
00843               php_mysqli_report_index(stmt->query, mysqli_stmt_server_status(stmt->stmt) TSRMLS_CC);
00844        }
00845 }
00846 /* }}} */
00847 
00848 #ifndef MYSQLI_USE_MYSQLND
00849 /* {{{ void mysqli_stmt_fetch_libmysql
00850    Fetch results from a prepared statement into the bound variables */
00851 void mysqli_stmt_fetch_libmysql(INTERNAL_FUNCTION_PARAMETERS)
00852 {
00853        MY_STMT              *stmt;
00854        zval                 *mysql_stmt;
00855        unsigned int  i;
00856        ulong                ret;
00857        unsigned int  uval;
00858        my_ulonglong  llval;
00859 
00860 
00861        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
00862               return;
00863        }
00864        MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
00865 
00866        /* reset buffers */
00867        for (i = 0; i < stmt->result.var_cnt; i++) {
00868               if (stmt->result.buf[i].type == IS_STRING) {
00869                      memset(stmt->result.buf[i].val, 0, stmt->result.buf[i].buflen);
00870               }
00871        }
00872        ret = mysql_stmt_fetch(stmt->stmt);
00873 #ifdef MYSQL_DATA_TRUNCATED
00874        if (!ret || ret == MYSQL_DATA_TRUNCATED) {
00875 #else
00876        if (!ret) {
00877 #endif
00878               for (i = 0; i < stmt->result.var_cnt; i++) {
00879                      /*
00880                        QQ: Isn't it quite better to call zval_dtor(). What if the user has
00881                        assigned a resource, or an array to the bound variable? We are going
00882                        to leak probably. zval_dtor() will handle also Unicode/Non-unicode mode.
00883                      */
00884                      /* Even if the string is of length zero there is one byte alloced so efree() in all cases */
00885                      if (Z_TYPE_P(stmt->result.vars[i]) == IS_STRING) {
00886                             efree(stmt->result.vars[i]->value.str.val);
00887                      }
00888                      if (!stmt->result.is_null[i]) {
00889                             switch (stmt->result.buf[i].type) {
00890                                    case IS_LONG:
00891                                           if ((stmt->stmt->fields[i].type == MYSQL_TYPE_LONG)
00892                                               && (stmt->stmt->fields[i].flags & UNSIGNED_FLAG))
00893                                           {
00894                                                  /* unsigned int (11) */
00895                                                  uval= *(unsigned int *) stmt->result.buf[i].val;
00896 #if SIZEOF_LONG==4
00897                                                  if (uval > INT_MAX) {
00898                                                         char *tmp, *p;
00899                                                         int j=10;
00900                                                         tmp= emalloc(11);
00901                                                         p= &tmp[9];
00902                                                         do {
00903                                                                *p-- = (uval % 10) + 48;
00904                                                                uval = uval / 10;
00905                                                         } while (--j > 0);
00906                                                         tmp[10]= '\0';
00907                                                         /* unsigned int > INT_MAX is 10 digits - ALWAYS */
00908                                                         ZVAL_STRINGL(stmt->result.vars[i], tmp, 10, 0);
00909                                                         break;
00910                                                  }
00911 #endif
00912                                           }
00913                                           if (stmt->stmt->fields[i].flags & UNSIGNED_FLAG) {
00914                                                  ZVAL_LONG(stmt->result.vars[i], *(unsigned int *)stmt->result.buf[i].val);
00915                                           } else {
00916                                                  ZVAL_LONG(stmt->result.vars[i], *(int *)stmt->result.buf[i].val);
00917                                           }
00918                                           break;
00919                                    case IS_DOUBLE:
00920                                           ZVAL_DOUBLE(stmt->result.vars[i], *(double *)stmt->result.buf[i].val);
00921                                           break;
00922                                    case IS_STRING:
00923                                           if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_LONGLONG
00924 #if MYSQL_VERSION_ID > 50002
00925                                            || stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_BIT
00926 #endif
00927                                            ) {
00928                                                  my_bool uns= (stmt->stmt->fields[i].flags & UNSIGNED_FLAG)? 1:0;
00929 #if MYSQL_VERSION_ID > 50002
00930                                                  if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_BIT) {
00931                                                         switch (stmt->result.buf[i].output_len) {
00932                                                                case 8:llval = (my_ulonglong)  bit_uint8korr(stmt->result.buf[i].val);break;
00933                                                                case 7:llval = (my_ulonglong)  bit_uint7korr(stmt->result.buf[i].val);break;
00934                                                                case 6:llval = (my_ulonglong)  bit_uint6korr(stmt->result.buf[i].val);break;
00935                                                                case 5:llval = (my_ulonglong)  bit_uint5korr(stmt->result.buf[i].val);break;
00936                                                                case 4:llval = (my_ulonglong)  bit_uint4korr(stmt->result.buf[i].val);break;
00937                                                                case 3:llval = (my_ulonglong)  bit_uint3korr(stmt->result.buf[i].val);break;
00938                                                                case 2:llval = (my_ulonglong)  bit_uint2korr(stmt->result.buf[i].val);break;
00939                                                                case 1:llval = (my_ulonglong)  uint1korr(stmt->result.buf[i].val);break;
00940                                                         }
00941                                                  } else
00942 #endif
00943                                                  {
00944                                                         llval= *(my_ulonglong *) stmt->result.buf[i].val;
00945                                                  }
00946 #if SIZEOF_LONG==8
00947                                                  if (uns && llval > 9223372036854775807L) {
00948 #elif SIZEOF_LONG==4
00949                                                  if ((uns && llval > L64(2147483647)) ||
00950                                                         (!uns && (( L64(2147483647) < (my_longlong) llval) ||
00951                                                         (L64(-2147483648) > (my_longlong) llval))))
00952                                                  {
00953 #endif
00954                                                         char tmp[22];
00955                                                         /* even though lval is declared as unsigned, the value
00956                                                          * may be negative. Therefor we cannot use MYSQLI_LLU_SPEC and must
00957                                                          * use MYSQLI_LL_SPEC.
00958                                                          */
00959                                                         snprintf(tmp, sizeof(tmp), (stmt->stmt->fields[i].flags & UNSIGNED_FLAG)? MYSQLI_LLU_SPEC : MYSQLI_LL_SPEC, llval);
00960                                                         ZVAL_STRING(stmt->result.vars[i], tmp, 1);
00961                                                  } else {
00962                                                         ZVAL_LONG(stmt->result.vars[i], llval);
00963                                                  }
00964                                           } else {
00965 #if defined(MYSQL_DATA_TRUNCATED) && MYSQL_VERSION_ID > 50002
00966                                                  if (ret == MYSQL_DATA_TRUNCATED && *(stmt->stmt->bind[i].error) != 0) {
00967                                                         /* result was truncated */
00968                                                         ZVAL_STRINGL(stmt->result.vars[i], stmt->result.buf[i].val,
00969                                                                               stmt->stmt->bind[i].buffer_length, 1);
00970                                                  } else {
00971 #else
00972                                                  {
00973 #endif
00974                                                         ZVAL_STRINGL(stmt->result.vars[i], stmt->result.buf[i].val,
00975                                                                               stmt->result.buf[i].output_len, 1);
00976                                                  }
00977                                           }
00978                                           break;
00979                                    default:
00980                                           break;
00981                             }
00982                      } else {
00983                             ZVAL_NULL(stmt->result.vars[i]);
00984                      }
00985               }
00986        } else {
00987               MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
00988        }
00989 
00990        switch (ret) {
00991               case 0:
00992 #ifdef MYSQL_DATA_TRUNCATED
00993               /* according to SQL standard truncation (e.g. loss of precision is
00994                  not an error) - for detecting possible truncation you have to
00995                  check mysqli_stmt_warning
00996               */
00997               case MYSQL_DATA_TRUNCATED:
00998 #endif
00999                      RETURN_TRUE;
01000               break;
01001               case 1:
01002                      RETURN_FALSE;
01003               break;
01004               default:
01005                      RETURN_NULL();
01006               break;
01007        }
01008 }
01009 /* }}} */
01010 #else
01011 /* {{{ mixed mysqli_stmt_fetch_mysqlnd */
01012 void mysqli_stmt_fetch_mysqlnd(INTERNAL_FUNCTION_PARAMETERS)
01013 {
01014        MY_STMT              *stmt;
01015        zval          *mysql_stmt;
01016        zend_bool     fetched_anything;
01017 
01018        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
01019               return;
01020        }
01021        MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
01022 
01023        if (FAIL  == mysqlnd_stmt_fetch(stmt->stmt, &fetched_anything)) {
01024               RETURN_BOOL(FALSE);
01025        } else if (fetched_anything == TRUE) {
01026               RETURN_BOOL(TRUE);
01027        } else {
01028               RETURN_NULL();
01029        }
01030 }
01031 #endif
01032 /* }}} */
01033 
01034 
01035 /* {{{ proto mixed mysqli_stmt_fetch(object stmt) U
01036    Fetch results from a prepared statement into the bound variables */
01037 PHP_FUNCTION(mysqli_stmt_fetch)
01038 {
01039 #if !defined(MYSQLI_USE_MYSQLND)
01040        mysqli_stmt_fetch_libmysql(INTERNAL_FUNCTION_PARAM_PASSTHRU);
01041 #else
01042        mysqli_stmt_fetch_mysqlnd(INTERNAL_FUNCTION_PARAM_PASSTHRU);
01043 #endif
01044 }
01045 /* }}} */
01046 
01047 /* {{{  php_add_field_properties */
01048 static void php_add_field_properties(zval *value, const MYSQL_FIELD *field TSRMLS_DC)
01049 {
01050        add_property_string(value, "name", (char *) (field->name ? field->name : ""), 1);
01051        add_property_string(value, "orgname", (char *) (field->org_name ? field->org_name : ""), 1);
01052        add_property_string(value, "table", (char *) (field->table ? field->table : ""), 1);
01053        add_property_string(value, "orgtable", (char *) (field->org_table ? field->org_table : ""), 1);
01054        add_property_string(value, "def", (field->def ? field->def : ""), 1);
01055        add_property_string(value, "db", (field->db ? field->db : ""), 1);
01056 
01057        /* FIXME: manually set the catalog to "def" due to bug in
01058         * libmysqlclient which does not initialize field->catalog
01059         * and in addition, the catalog is always be "def"
01060         */
01061        add_property_string(value, "catalog", "def", 1);
01062 
01063        add_property_long(value, "max_length", field->max_length);
01064        add_property_long(value, "length", field->length);
01065        add_property_long(value, "charsetnr", field->charsetnr);
01066        add_property_long(value, "flags", field->flags);
01067        add_property_long(value, "type", field->type);
01068        add_property_long(value, "decimals", field->decimals);
01069 }
01070 /* }}} */
01071 
01072 /* {{{ proto mixed mysqli_fetch_field (object result)
01073    Get column information from a result and return as an object */
01074 PHP_FUNCTION(mysqli_fetch_field)
01075 {
01076        MYSQL_RES     *result;
01077        zval          *mysql_result;
01078        const MYSQL_FIELD    *field;
01079 
01080        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
01081               return;
01082        }
01083 
01084        MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
01085 
01086        if (!(field = mysql_fetch_field(result))) {
01087               RETURN_FALSE;
01088        }
01089 
01090        object_init(return_value);
01091        php_add_field_properties(return_value, field TSRMLS_CC);
01092 }
01093 /* }}} */
01094 
01095 /* {{{ proto mixed mysqli_fetch_fields (object result)
01096    Return array of objects containing field meta-data */
01097 PHP_FUNCTION(mysqli_fetch_fields)
01098 {
01099        MYSQL_RES     *result;
01100        zval          *mysql_result;
01101        zval          *obj;
01102 
01103        unsigned int i;
01104 
01105        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
01106               return;
01107        }
01108 
01109        MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
01110 
01111        array_init(return_value);
01112 
01113        for (i = 0; i < mysql_num_fields(result); i++) {
01114               const MYSQL_FIELD *field = mysql_fetch_field_direct(result, i);
01115 
01116               MAKE_STD_ZVAL(obj);
01117               object_init(obj);
01118 
01119               php_add_field_properties(obj, field TSRMLS_CC);
01120               add_index_zval(return_value, i, obj);
01121        }
01122 }
01123 /* }}} */
01124 
01125 /* {{{ proto mixed mysqli_fetch_field_direct (object result, int offset)
01126    Fetch meta-data for a single field */
01127 PHP_FUNCTION(mysqli_fetch_field_direct)
01128 {
01129        MYSQL_RES     *result;
01130        zval          *mysql_result;
01131        const MYSQL_FIELD    *field;
01132        long          offset;
01133 
01134        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_result, mysqli_result_class_entry, &offset) == FAILURE) {
01135               return;
01136        }
01137 
01138        MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
01139 
01140        if (offset < 0 || offset >= (long) mysql_num_fields(result)) {
01141               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Field offset is invalid for resultset");
01142               RETURN_FALSE;
01143        }
01144 
01145        if (!(field = mysql_fetch_field_direct(result,offset))) {
01146               RETURN_FALSE;
01147        }
01148 
01149        object_init(return_value);
01150        php_add_field_properties(return_value, field TSRMLS_CC);
01151 }
01152 /* }}} */
01153 
01154 /* {{{ proto mixed mysqli_fetch_lengths (object result)
01155    Get the length of each output in a result */
01156 PHP_FUNCTION(mysqli_fetch_lengths)
01157 {
01158        MYSQL_RES            *result;
01159        zval                 *mysql_result;
01160        unsigned int  i;
01161        unsigned long *ret;
01162 
01163        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
01164               return;
01165        }
01166 
01167        MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
01168 
01169        if (!(ret = mysql_fetch_lengths(result))) {
01170               RETURN_FALSE;
01171        }
01172 
01173        array_init(return_value);
01174 
01175        for (i = 0; i < mysql_num_fields(result); i++) {
01176               add_index_long(return_value, i, ret[i]);
01177        }
01178 }
01179 /* }}} */
01180 
01181 /* {{{ proto array mysqli_fetch_row (object result)
01182    Get a result row as an enumerated array */
01183 PHP_FUNCTION(mysqli_fetch_row)
01184 {
01185        php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_NUM, 0);
01186 }
01187 /* }}} */
01188 
01189 /* {{{ proto int mysqli_field_count(object link)
01190    Fetch the number of fields returned by the last query for the given link
01191 */
01192 PHP_FUNCTION(mysqli_field_count)
01193 {
01194        MY_MYSQL      *mysql;
01195        zval          *mysql_link;
01196 
01197        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
01198               return;
01199        }
01200        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
01201 
01202        RETURN_LONG(mysql_field_count(mysql->mysql));
01203 }
01204 /* }}} */
01205 
01206 /* {{{ proto int mysqli_field_seek(object result, int fieldnr)
01207    Set result pointer to a specified field offset
01208 */
01209 PHP_FUNCTION(mysqli_field_seek)
01210 {
01211        MYSQL_RES            *result;
01212        zval                 *mysql_result;
01213        unsigned long fieldnr;
01214 
01215        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_result, mysqli_result_class_entry, &fieldnr) == FAILURE) {
01216               return;
01217        }
01218        MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
01219 
01220        if (fieldnr < 0 || fieldnr >= mysql_num_fields(result)) {
01221               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid field offset");
01222               RETURN_FALSE;
01223        }
01224 
01225        mysql_field_seek(result, fieldnr);
01226        RETURN_TRUE;
01227 }
01228 /* }}} */
01229 
01230 /* {{{ proto int mysqli_field_tell(object result)
01231    Get current field offset of result pointer */
01232 PHP_FUNCTION(mysqli_field_tell)
01233 {
01234        MYSQL_RES     *result;
01235        zval          *mysql_result;
01236 
01237        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
01238               return;
01239        }
01240        MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
01241 
01242        RETURN_LONG(mysql_field_tell(result));
01243 }
01244 /* }}} */
01245 
01246 /* {{{ proto void mysqli_free_result(object result)
01247    Free query result memory for the given result handle */
01248 PHP_FUNCTION(mysqli_free_result)
01249 {
01250        MYSQL_RES     *result;
01251        zval          *mysql_result;
01252 
01253        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
01254               return;
01255        }
01256        MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
01257 
01258        mysqli_free_result(result, FALSE);
01259        MYSQLI_CLEAR_RESOURCE(&mysql_result);
01260 }
01261 /* }}} */
01262 
01263 /* {{{ proto string mysqli_get_client_info(void)
01264    Get MySQL client info */
01265 PHP_FUNCTION(mysqli_get_client_info)
01266 {
01267        RETURN_STRING((char *)mysql_get_client_info(), 1);
01268 }
01269 /* }}} */
01270 
01271 /* {{{ proto int mysqli_get_client_version(void)
01272    Get MySQL client info */
01273 PHP_FUNCTION(mysqli_get_client_version)
01274 {
01275        RETURN_LONG((long)mysql_get_client_version());
01276 }
01277 /* }}} */
01278 
01279 /* {{{ proto string mysqli_get_host_info (object link)
01280    Get MySQL host info */
01281 PHP_FUNCTION(mysqli_get_host_info)
01282 {
01283        MY_MYSQL      *mysql;
01284        zval          *mysql_link = NULL;
01285 
01286        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
01287               return;
01288        }
01289        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
01290 
01291        RETURN_STRING((mysql->mysql->host_info) ? mysql->mysql->host_info : "", 1);
01292 }
01293 /* }}} */
01294 
01295 /* {{{ proto int mysqli_get_proto_info(object link)
01296    Get MySQL protocol information */
01297 PHP_FUNCTION(mysqli_get_proto_info)
01298 {
01299        MY_MYSQL      *mysql;
01300        zval          *mysql_link = NULL;
01301 
01302        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
01303               return;
01304        }
01305        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
01306        RETURN_LONG(mysql_get_proto_info(mysql->mysql));
01307 }
01308 /* }}} */
01309 
01310 /* {{{ proto string mysqli_get_server_info(object link)
01311    Get MySQL server info */
01312 PHP_FUNCTION(mysqli_get_server_info)
01313 {
01314        MY_MYSQL      *mysql;
01315        zval          *mysql_link = NULL;
01316 
01317        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
01318               return;
01319        }
01320        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
01321 
01322        RETURN_STRING((char *)mysql_get_server_info(mysql->mysql), 1);
01323 }
01324 
01325 /* }}} */
01326 
01327 /* {{{ proto int mysqli_get_server_version(object link)
01328    Return the MySQL version for the server referenced by the given link */
01329 PHP_FUNCTION(mysqli_get_server_version)
01330 {
01331        MY_MYSQL      *mysql;
01332        zval          *mysql_link = NULL;
01333 
01334        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
01335               return;
01336        }
01337        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
01338 
01339        RETURN_LONG(mysql_get_server_version(mysql->mysql));
01340 }
01341 /* }}} */
01342 
01343 /* {{{ proto string mysqli_info(object link)
01344    Get information about the most recent query */
01345 PHP_FUNCTION(mysqli_info)
01346 {
01347        MY_MYSQL      *mysql;
01348        zval          *mysql_link = NULL;
01349        const char    *info;
01350 
01351        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
01352               return;
01353        }
01354        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
01355 
01356        info = mysql_info(mysql->mysql);
01357        RETURN_STRING((info) ? (char *)info : "", 1);
01358 }
01359 /* }}} */
01360 
01361 
01362 /* {{{ php_mysqli_init() */
01363 void php_mysqli_init(INTERNAL_FUNCTION_PARAMETERS)
01364 {
01365        MYSQLI_RESOURCE *mysqli_resource;
01366        MY_MYSQL *mysql;
01367 
01368        if (getThis() && ((mysqli_object *) zend_object_store_get_object(getThis() TSRMLS_CC))->ptr) {
01369               return;
01370        }
01371 
01372        mysql = (MY_MYSQL *)ecalloc(1, sizeof(MY_MYSQL));
01373 
01374 #if !defined(MYSQLI_USE_MYSQLND)
01375        if (!(mysql->mysql = mysql_init(NULL)))
01376 #else
01377        /*
01378          We create always persistent, as if the user want to connecto
01379          to p:somehost, we can't convert the handle then
01380        */
01381        if (!(mysql->mysql = mysql_init(TRUE)))
01382 #endif
01383        {
01384               efree(mysql);
01385               RETURN_FALSE;
01386        }
01387 
01388        mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
01389        mysqli_resource->ptr = (void *)mysql;
01390        mysqli_resource->status = MYSQLI_STATUS_INITIALIZED;
01391 
01392        if (!getThis() || !instanceof_function(Z_OBJCE_P(getThis()), mysqli_link_class_entry TSRMLS_CC)) {
01393               MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_link_class_entry);
01394        } else {
01395               ((mysqli_object *) zend_object_store_get_object(getThis() TSRMLS_CC))->ptr = mysqli_resource;
01396        }
01397 }
01398 /* }}} */
01399 
01400 
01401 /* {{{ proto resource mysqli_init(void)
01402    Initialize mysqli and return a resource for use with mysql_real_connect */
01403 PHP_FUNCTION(mysqli_init)
01404 {
01405        php_mysqli_init(INTERNAL_FUNCTION_PARAM_PASSTHRU);
01406 }
01407 /* }}} */
01408 
01409 /* {{{ proto mixed mysqli_insert_id(object link)
01410    Get the ID generated from the previous INSERT operation */
01411 PHP_FUNCTION(mysqli_insert_id)
01412 {
01413        MY_MYSQL             *mysql;
01414        my_ulonglong  rc;
01415        zval                 *mysql_link;
01416 
01417        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
01418               return;
01419        }
01420        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
01421        rc = mysql_insert_id(mysql->mysql);
01422        MYSQLI_RETURN_LONG_LONG(rc)
01423 }
01424 /* }}} */
01425 
01426 /* {{{ proto bool mysqli_kill(object link, int processid)
01427    Kill a mysql process on the server */
01428 PHP_FUNCTION(mysqli_kill)
01429 {
01430        MY_MYSQL      *mysql;
01431        zval          *mysql_link;
01432        long          processid;
01433 
01434        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_link, mysqli_link_class_entry, &processid) == FAILURE) {
01435               return;
01436        }
01437        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
01438 
01439        if (processid <= 0) {
01440               php_error_docref(NULL TSRMLS_CC, E_WARNING, "processid should have positive value");
01441               RETURN_FALSE;
01442        }
01443 
01444        if (mysql_kill(mysql->mysql, processid)) {
01445               MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
01446               RETURN_FALSE;
01447        }
01448        RETURN_TRUE;
01449 }
01450 /* }}} */
01451 
01452 /* {{{ proto void mysqli_set_local_infile_default(object link)
01453    unsets user defined handler for load local infile command */
01454 #if !defined(MYSQLI_USE_MYSQLND)
01455 PHP_FUNCTION(mysqli_set_local_infile_default)
01456 {
01457        MY_MYSQL      *mysql;
01458        zval          *mysql_link;
01459 
01460        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
01461               return;
01462        }
01463 
01464        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
01465 
01466        if (mysql->li_read) {
01467               zval_ptr_dtor(&(mysql->li_read));
01468               mysql->li_read = NULL;
01469        }
01470 }
01471 /* }}} */
01472 
01473 /* {{{ proto bool mysqli_set_local_infile_handler(object link, callback read_func)
01474    Set callback functions for LOAD DATA LOCAL INFILE */
01475 PHP_FUNCTION(mysqli_set_local_infile_handler)
01476 {
01477        MY_MYSQL      *mysql;
01478        zval          *mysql_link;
01479        char          *callback_name;
01480        zval          *callback_func;
01481 
01482        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oz", &mysql_link, mysqli_link_class_entry,
01483                      &callback_func) == FAILURE) {
01484               return;
01485        }
01486 
01487        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
01488 
01489        /* check callback function */
01490        if (!zend_is_callable(callback_func, 0, &callback_name TSRMLS_CC)) {
01491               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not a valid callback function %s", callback_name);
01492               efree(callback_name);
01493               RETURN_FALSE;
01494        }
01495        efree(callback_name);
01496 
01497        /* save callback function */
01498        if (!mysql->li_read) {
01499               MAKE_STD_ZVAL(mysql->li_read);
01500        } else {
01501               zval_dtor(mysql->li_read);
01502        }
01503        ZVAL_ZVAL(mysql->li_read, callback_func, 1, 0);
01504 
01505        RETURN_TRUE;
01506 }
01507 #endif
01508 /* }}} */
01509 
01510 /* {{{ proto bool mysqli_more_results(object link)
01511    check if there any more query results from a multi query */
01512 PHP_FUNCTION(mysqli_more_results)
01513 {
01514        MY_MYSQL      *mysql;
01515        zval          *mysql_link;
01516 
01517        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
01518               return;
01519        }
01520        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
01521 
01522        RETURN_BOOL(mysql_more_results(mysql->mysql));
01523 }
01524 /* }}} */
01525 
01526 /* {{{ proto bool mysqli_next_result(object link)
01527    read next result from multi_query */
01528 PHP_FUNCTION(mysqli_next_result) {
01529        MY_MYSQL      *mysql;
01530        zval          *mysql_link;
01531 
01532        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
01533               return;
01534        }
01535        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
01536 
01537        if (!mysql_more_results(mysql->mysql)) {
01538               php_error_docref(NULL TSRMLS_CC, E_STRICT, "There is no next result set. "
01539                                           "Please, call mysqli_more_results()/mysqli::more_results() to check "
01540                                           "whether to call this function/method");
01541        }
01542 
01543        RETURN_BOOL(!mysql_next_result(mysql->mysql));
01544 }
01545 /* }}} */
01546 
01547 #if defined(HAVE_STMT_NEXT_RESULT) && defined(MYSQLI_USE_MYSQLND)
01548 /* {{{ proto bool mysqli_stmt_next_result(object link)
01549    check if there any more query results from a multi query */
01550 PHP_FUNCTION(mysqli_stmt_more_results)
01551 {
01552        MY_STMT              *stmt;
01553        zval          *mysql_stmt;
01554 
01555        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
01556               return;
01557        }
01558        MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
01559 
01560        RETURN_BOOL(mysqlnd_stmt_more_results(stmt->stmt));
01561 }
01562 /* }}} */
01563 
01564 
01565 /* {{{ proto bool mysqli_stmt_next_result(object link)
01566    read next result from multi_query */
01567 PHP_FUNCTION(mysqli_stmt_next_result) {
01568        MY_STMT              *stmt;
01569        zval          *mysql_stmt;
01570 
01571        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
01572               return;
01573        }
01574        MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
01575 
01576        if (!mysqlnd_stmt_more_results(stmt->stmt)) {
01577               php_error_docref(NULL TSRMLS_CC, E_STRICT, "There is no next result set. "
01578                                           "Please, call mysqli_stmt_more_results()/mysqli_stmt::more_results() to check "
01579                                           "whether to call this function/method");
01580        }
01581 
01582        RETURN_BOOL(!mysql_stmt_next_result(stmt->stmt));
01583 }
01584 /* }}} */
01585 #endif
01586 
01587 
01588 /* {{{ proto int mysqli_num_fields(object result)
01589    Get number of fields in result */
01590 PHP_FUNCTION(mysqli_num_fields)
01591 {
01592        MYSQL_RES     *result;
01593        zval          *mysql_result;
01594 
01595        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
01596               return;
01597        }
01598        MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
01599 
01600        RETURN_LONG(mysql_num_fields(result));
01601 }
01602 /* }}} */
01603 
01604 /* {{{ proto mixed mysqli_num_rows(object result)
01605    Get number of rows in result */
01606 PHP_FUNCTION(mysqli_num_rows)
01607 {
01608        MYSQL_RES     *result;
01609        zval          *mysql_result;
01610 
01611        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
01612               return;
01613        }
01614        MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
01615 
01616        if (mysqli_result_is_unbuffered_and_not_everything_is_fetched(result)) {
01617               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function cannot be used with MYSQL_USE_RESULT");
01618               RETURN_LONG(0);
01619        }
01620 
01621        MYSQLI_RETURN_LONG_LONG(mysql_num_rows(result));
01622 }
01623 /* }}} */
01624 
01625 /* {{{ mysqli_options_get_option_zval_type */
01626 static int mysqli_options_get_option_zval_type(int option)
01627 {
01628        switch (option) {
01629 #ifdef MYSQLI_USE_MYSQLND
01630 #if PHP_MAJOR_VERSION >= 6
01631               case MYSQLND_OPT_NUMERIC_AND_DATETIME_AS_UNICODE:
01632 #endif
01633               case MYSQLND_OPT_NET_CMD_BUFFER_SIZE:
01634               case MYSQLND_OPT_NET_READ_BUFFER_SIZE:
01635 #ifdef MYSQLND_STRING_TO_INT_CONVERSION
01636               case MYSQLND_OPT_INT_AND_FLOAT_NATIVE:
01637 #endif
01638 #endif /* MYSQLI_USE_MYSQLND */
01639               case MYSQL_OPT_CONNECT_TIMEOUT:
01640 #ifdef MYSQL_REPORT_DATA_TRUNCATION
01641                 case MYSQL_REPORT_DATA_TRUNCATION:
01642 #endif
01643                 case MYSQL_OPT_LOCAL_INFILE:
01644                 case MYSQL_OPT_NAMED_PIPE:
01645 #ifdef MYSQL_OPT_PROTOCOL
01646                 case MYSQL_OPT_PROTOCOL:
01647 #endif /* MySQL 4.1.0 */
01648 #ifdef MYSQL_OPT_READ_TIMEOUT
01649               case MYSQL_OPT_READ_TIMEOUT:
01650               case MYSQL_OPT_WRITE_TIMEOUT:
01651               case MYSQL_OPT_GUESS_CONNECTION:
01652               case MYSQL_OPT_USE_EMBEDDED_CONNECTION:
01653               case MYSQL_OPT_USE_REMOTE_CONNECTION:
01654               case MYSQL_SECURE_AUTH:
01655 #endif /* MySQL 4.1.1 */
01656 #ifdef MYSQL_OPT_RECONNECT
01657               case MYSQL_OPT_RECONNECT:
01658 #endif /* MySQL 5.0.13 */
01659 #ifdef MYSQL_OPT_SSL_VERIFY_SERVER_CERT
01660                 case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
01661 #endif /* MySQL 5.0.23 */
01662 #ifdef MYSQL_OPT_COMPRESS
01663               case MYSQL_OPT_COMPRESS:
01664 #endif /* mysqlnd @ PHP 5.3.2 */
01665 #ifdef MYSQL_OPT_SSL_VERIFY_SERVER_CERT
01666        REGISTER_LONG_CONSTANT("MYSQLI_OPT_SSL_VERIFY_SERVER_CERT", MYSQL_OPT_SSL_VERIFY_SERVER_CERT, CONST_CS | CONST_PERSISTENT);
01667 #endif /* MySQL 5.1.1., mysqlnd @ PHP 5.3.3 */
01668                      return IS_LONG;
01669 
01670 #ifdef MYSQL_SHARED_MEMORY_BASE_NAME
01671                 case MYSQL_SHARED_MEMORY_BASE_NAME:
01672 #endif /* MySQL 4.1.0 */
01673 #ifdef MYSQL_SET_CLIENT_IP
01674               case MYSQL_SET_CLIENT_IP:
01675 #endif /* MySQL 4.1.1 */
01676               case MYSQL_READ_DEFAULT_FILE:
01677               case MYSQL_READ_DEFAULT_GROUP:
01678               case MYSQL_INIT_COMMAND:
01679               case MYSQL_SET_CHARSET_NAME:
01680               case MYSQL_SET_CHARSET_DIR:
01681                      return IS_STRING;
01682 
01683               default:
01684                      return IS_NULL;
01685        }
01686 }
01687 /* }}} */
01688 
01689 
01690 /* {{{ proto bool mysqli_options(object link, int flags, mixed values)
01691    Set options */
01692 PHP_FUNCTION(mysqli_options)
01693 {
01694        MY_MYSQL             *mysql;
01695        zval                 *mysql_link = NULL;
01696        zval                 **mysql_value;
01697        long                 mysql_option;
01698        unsigned int  l_value;
01699        long                 ret;
01700        int                         expected_type;
01701 
01702        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OlZ", &mysql_link, mysqli_link_class_entry, &mysql_option, &mysql_value) == FAILURE) {
01703               return;
01704        }
01705        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_INITIALIZED);
01706 
01707 #if PHP_API_VERSION < 20100412
01708        if ((PG(open_basedir) && PG(open_basedir)[0] != '\0') || PG(safe_mode)) {
01709 #else
01710        if (PG(open_basedir) && PG(open_basedir)[0] != '\0') {
01711 #endif
01712               if(mysql_option == MYSQL_OPT_LOCAL_INFILE) {
01713                      RETURN_FALSE;
01714               }
01715        }
01716        expected_type = mysqli_options_get_option_zval_type(mysql_option);
01717        if (expected_type != Z_TYPE_PP(mysql_value)) {
01718               switch (expected_type) {
01719                      case IS_STRING:
01720                             convert_to_string_ex(mysql_value);
01721                             break;
01722                      case IS_LONG:
01723                             convert_to_long_ex(mysql_value);
01724                             break;
01725                      default:
01726                             break;
01727               }
01728        }
01729        switch (expected_type) {
01730               case IS_STRING:
01731                      ret = mysql_options(mysql->mysql, mysql_option, Z_STRVAL_PP(mysql_value));
01732                      break;
01733               case IS_LONG:
01734                      l_value = Z_LVAL_PP(mysql_value);
01735                      ret = mysql_options(mysql->mysql, mysql_option, (char *)&l_value);
01736                      break;
01737               default:
01738                      ret = 1;
01739                      break;
01740        }
01741 
01742        RETURN_BOOL(!ret);
01743 }
01744 /* }}} */
01745 
01746 
01747 /* {{{ proto bool mysqli_ping(object link)
01748    Ping a server connection or reconnect if there is no connection */
01749 PHP_FUNCTION(mysqli_ping)
01750 {
01751        MY_MYSQL      *mysql;
01752        zval          *mysql_link;
01753        long          rc;
01754 
01755        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
01756               return;
01757        }
01758        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
01759        rc = mysql_ping(mysql->mysql);
01760        MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
01761 
01762        RETURN_BOOL(!rc);
01763 }
01764 /* }}} */
01765 
01766 /* {{{ proto mixed mysqli_prepare(object link, string query)
01767    Prepare a SQL statement for execution */
01768 PHP_FUNCTION(mysqli_prepare)
01769 {
01770        MY_MYSQL             *mysql;
01771        MY_STMT                     *stmt;
01772        char                 *query = NULL;
01773        int                         query_len;
01774        zval                 *mysql_link;
01775        MYSQLI_RESOURCE      *mysqli_resource;
01776 
01777        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os",&mysql_link, mysqli_link_class_entry, &query, &query_len) == FAILURE) {
01778               return;
01779        }
01780        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
01781 
01782 #if !defined(MYSQLI_USE_MYSQLND)
01783        if (mysql->mysql->status == MYSQL_STATUS_GET_RESULT) {
01784               php_error_docref(NULL TSRMLS_CC, E_WARNING, "All data must be fetched before a new statement prepare takes place");
01785               RETURN_FALSE;
01786        }
01787 #endif
01788 
01789        stmt = (MY_STMT *)ecalloc(1,sizeof(MY_STMT));
01790 
01791        if ((stmt->stmt = mysql_stmt_init(mysql->mysql))) {
01792               if (mysql_stmt_prepare(stmt->stmt, query, query_len)) {
01793                      /* mysql_stmt_close() clears errors, so we have to store them temporarily */
01794 #if !defined(MYSQLI_USE_MYSQLND)
01795                      char  last_error[MYSQL_ERRMSG_SIZE];
01796                      char  sqlstate[SQLSTATE_LENGTH+1];
01797                      unsigned int last_errno;
01798 
01799                      last_errno = stmt->stmt->last_errno;
01800                      memcpy(last_error, stmt->stmt->last_error, MYSQL_ERRMSG_SIZE);
01801                      memcpy(sqlstate, mysql->mysql->net.sqlstate, SQLSTATE_LENGTH+1);
01802 #else
01803                      MYSQLND_ERROR_INFO error_info = mysql->mysql->error_info;
01804 #endif
01805                      mysqli_stmt_close(stmt->stmt, FALSE);
01806                      stmt->stmt = NULL;
01807 
01808                      /* restore error messages */
01809 #if !defined(MYSQLI_USE_MYSQLND)
01810                      mysql->mysql->net.last_errno = last_errno;
01811                      memcpy(mysql->mysql->net.last_error, last_error, MYSQL_ERRMSG_SIZE);
01812                      memcpy(mysql->mysql->net.sqlstate, sqlstate, SQLSTATE_LENGTH+1);
01813 #else
01814                      mysql->mysql->error_info = error_info;
01815 #endif
01816               }
01817        }
01818 
01819        /* don't initialize stmt->query with NULL, we ecalloc()-ed the memory */
01820        /* Get performance boost if reporting is switched off */
01821        if (stmt->stmt && query_len && (MyG(report_mode) & MYSQLI_REPORT_INDEX)) {
01822               stmt->query = (char *)emalloc(query_len + 1);
01823               memcpy(stmt->query, query, query_len);
01824               stmt->query[query_len] = '\0';
01825        }
01826 
01827        /* don't join to the previous if because it won't work if mysql_stmt_prepare_fails */
01828        if (!stmt->stmt) {
01829               MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
01830               efree(stmt);
01831               RETURN_FALSE;
01832        }
01833 
01834        mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
01835        mysqli_resource->ptr = (void *)stmt;
01836 
01837        /* change status */
01838        mysqli_resource->status = MYSQLI_STATUS_VALID;
01839        MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_stmt_class_entry);
01840 }
01841 /* }}} */
01842 
01843 
01844 /* {{{ proto bool mysqli_real_connect(object link [,string hostname [,string username [,string passwd [,string dbname [,int port [,string socket [,int flags]]]]]]])
01845    Open a connection to a mysql server */
01846 PHP_FUNCTION(mysqli_real_connect)
01847 {
01848        mysqli_common_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, TRUE, FALSE);
01849 }
01850 /* }}} */
01851 
01852 
01853 /* {{{ proto bool mysqli_real_query(object link, string query)
01854    Binary-safe version of mysql_query() */
01855 PHP_FUNCTION(mysqli_real_query)
01856 {
01857        MY_MYSQL      *mysql;
01858        zval          *mysql_link;
01859        char          *query = NULL;
01860        int                  query_len;
01861 
01862        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &query, &query_len) == FAILURE) {
01863               return;
01864        }
01865        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
01866 
01867        MYSQLI_DISABLE_MQ; /* disable multi statements/queries */
01868 
01869        if (mysql_real_query(mysql->mysql, query, query_len)) {
01870               MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
01871               RETURN_FALSE;
01872        }
01873 
01874        if (!mysql_field_count(mysql->mysql)) {
01875               if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
01876                      php_mysqli_report_index(query, mysqli_server_status(mysql->mysql) TSRMLS_CC);
01877               }
01878        }
01879 
01880        RETURN_TRUE;
01881 }
01882 /* }}} */
01883 
01884 /* {{{ proto string mysqli_real_escape_string(object link, string escapestr)
01885    Escapes special characters in a string for use in a SQL statement, taking into account the current charset of the connection */
01886 PHP_FUNCTION(mysqli_real_escape_string) {
01887        MY_MYSQL      *mysql;
01888        zval          *mysql_link = NULL;
01889        char          *escapestr, *newstr;
01890        int                  escapestr_len, newstr_len;
01891 
01892        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &escapestr, &escapestr_len) == FAILURE) {
01893               return;
01894        }
01895        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
01896 
01897        newstr = safe_emalloc(2, escapestr_len, 1);
01898        newstr_len = mysql_real_escape_string(mysql->mysql, newstr, escapestr, escapestr_len);
01899        newstr = erealloc(newstr, newstr_len + 1);
01900 
01901        RETURN_STRINGL(newstr, newstr_len, 0);
01902 }
01903 /* }}} */
01904 
01905 /* {{{ proto bool mysqli_rollback(object link)
01906    Undo actions from current transaction */
01907 PHP_FUNCTION(mysqli_rollback)
01908 {
01909        MY_MYSQL      *mysql;
01910        zval          *mysql_link;
01911 
01912        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
01913               return;
01914        }
01915        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
01916 
01917        if (mysql_rollback(mysql->mysql)) {
01918               RETURN_FALSE;
01919        }
01920        RETURN_TRUE;
01921 }
01922 /* }}} */
01923 
01924 /* {{{ proto bool mysqli_stmt_send_long_data(object stmt, int param_nr, string data)
01925 */
01926 PHP_FUNCTION(mysqli_stmt_send_long_data)
01927 {
01928        MY_STMT *stmt;
01929        zval   *mysql_stmt;
01930        char   *data;
01931        long   param_nr;
01932        int           data_len;
01933 
01934        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ols", &mysql_stmt, mysqli_stmt_class_entry, &param_nr, &data, &data_len) == FAILURE) {
01935               return;
01936        }
01937        MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
01938 
01939        if (param_nr < 0) {
01940               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid parameter number");
01941               RETURN_FALSE;
01942        }
01943        if (mysql_stmt_send_long_data(stmt->stmt, param_nr, data, data_len)) {
01944               RETURN_FALSE;
01945        }
01946        RETURN_TRUE;
01947 }
01948 /* }}} */
01949 
01950 
01951 /* {{{ proto mixed mysqli_stmt_affected_rows(object stmt)
01952    Return the number of rows affected in the last query for the given link */
01953 PHP_FUNCTION(mysqli_stmt_affected_rows)
01954 {
01955        MY_STMT                     *stmt;
01956        zval                 *mysql_stmt;
01957        my_ulonglong  rc;
01958 
01959        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
01960               return;
01961        }
01962        MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
01963 
01964        rc = mysql_stmt_affected_rows(stmt->stmt);
01965        if (rc == (my_ulonglong) -1) {
01966               RETURN_LONG(-1);
01967        }
01968        MYSQLI_RETURN_LONG_LONG(rc)
01969 }
01970 /* }}} */
01971 
01972 /* {{{ proto bool mysqli_stmt_close(object stmt)
01973    Close statement */
01974 PHP_FUNCTION(mysqli_stmt_close)
01975 {
01976        MY_STMT              *stmt;
01977        zval          *mysql_stmt;
01978 
01979        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
01980               return;
01981        }
01982        MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
01983 
01984        mysqli_stmt_close(stmt->stmt, FALSE);
01985        stmt->stmt = NULL;
01986        php_clear_stmt_bind(stmt TSRMLS_CC);
01987        MYSQLI_CLEAR_RESOURCE(&mysql_stmt);
01988        RETURN_TRUE;
01989 }
01990 /* }}} */
01991 
01992 /* {{{ proto void mysqli_stmt_data_seek(object stmt, int offset)
01993    Move internal result pointer */
01994 PHP_FUNCTION(mysqli_stmt_data_seek)
01995 {
01996        MY_STMT              *stmt;
01997        zval          *mysql_stmt;
01998        long          offset;
01999 
02000        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_stmt, mysqli_stmt_class_entry, &offset) == FAILURE) {
02001               return;
02002        }
02003        if (offset < 0) {
02004               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset must be positive");
02005               RETURN_FALSE;
02006        }
02007 
02008        MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
02009 
02010        mysql_stmt_data_seek(stmt->stmt, offset);
02011 }
02012 /* }}} */
02013 
02014 /* {{{ proto int mysqli_stmt_field_count(object stmt) {
02015    Return the number of result columns for the given statement */
02016 PHP_FUNCTION(mysqli_stmt_field_count)
02017 {
02018        MY_STMT              *stmt;
02019        zval          *mysql_stmt;
02020 
02021        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
02022               return;
02023        }
02024        MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
02025 
02026        RETURN_LONG(mysql_stmt_field_count(stmt->stmt));
02027 }
02028 /* }}} */
02029 
02030 /* {{{ proto void mysqli_stmt_free_result(object stmt)
02031    Free stored result memory for the given statement handle */
02032 PHP_FUNCTION(mysqli_stmt_free_result)
02033 {
02034        MY_STMT              *stmt;
02035        zval          *mysql_stmt;
02036 
02037        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
02038               return;
02039        }
02040 
02041        MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
02042 
02043        mysql_stmt_free_result(stmt->stmt);
02044 }
02045 /* }}} */
02046 
02047 /* {{{ proto mixed mysqli_stmt_insert_id(object stmt)
02048    Get the ID generated from the previous INSERT operation */
02049 PHP_FUNCTION(mysqli_stmt_insert_id)
02050 {
02051        MY_STMT                     *stmt;
02052        my_ulonglong  rc;
02053        zval                 *mysql_stmt;
02054 
02055        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
02056               return;
02057        }
02058        MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
02059        rc = mysql_stmt_insert_id(stmt->stmt);
02060        MYSQLI_RETURN_LONG_LONG(rc)
02061 }
02062 /* }}} */
02063 
02064 /* {{{ proto int mysqli_stmt_param_count(object stmt)
02065    Return the number of parameter for the given statement */
02066 PHP_FUNCTION(mysqli_stmt_param_count)
02067 {
02068        MY_STMT              *stmt;
02069        zval          *mysql_stmt;
02070 
02071        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
02072               return;
02073        }
02074        MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
02075 
02076        RETURN_LONG(mysql_stmt_param_count(stmt->stmt));
02077 }
02078 /* }}} */
02079 
02080 /* {{{ proto bool mysqli_stmt_reset(object stmt)
02081    reset a prepared statement */
02082 PHP_FUNCTION(mysqli_stmt_reset)
02083 {
02084        MY_STMT              *stmt;
02085        zval          *mysql_stmt;
02086 
02087        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
02088               return;
02089        }
02090 
02091        MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
02092 
02093        if (mysql_stmt_reset(stmt->stmt)) {
02094               RETURN_FALSE;
02095        }
02096        RETURN_TRUE;
02097 }
02098 /* }}} */
02099 
02100 /* {{{ proto mixed mysqli_stmt_num_rows(object stmt)
02101    Return the number of rows in statements result set */
02102 PHP_FUNCTION(mysqli_stmt_num_rows)
02103 {
02104        MY_STMT                     *stmt;
02105        zval                 *mysql_stmt;
02106        my_ulonglong  rc;
02107 
02108        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
02109               return;
02110        }
02111 
02112        MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
02113 
02114        rc = mysql_stmt_num_rows(stmt->stmt);
02115        MYSQLI_RETURN_LONG_LONG(rc)
02116 }
02117 /* }}} */
02118 
02119 /* {{{ proto bool mysqli_select_db(object link, string dbname)
02120    Select a MySQL database */
02121 PHP_FUNCTION(mysqli_select_db)
02122 {
02123        MY_MYSQL      *mysql;
02124        zval          *mysql_link;
02125        char          *dbname;
02126        int                  dbname_len;
02127 
02128        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &dbname, &dbname_len) == FAILURE) {
02129               return;
02130        }
02131        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
02132 
02133        if (mysql_select_db(mysql->mysql, dbname)) {
02134               MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
02135               RETURN_FALSE;
02136        }
02137        RETURN_TRUE;
02138 }
02139 /* }}} */
02140 
02141 /* {{{ proto string mysqli_sqlstate(object link)
02142    Returns the SQLSTATE error from previous MySQL operation */
02143 PHP_FUNCTION(mysqli_sqlstate)
02144 {
02145        MY_MYSQL      *mysql;
02146        zval          *mysql_link;
02147 
02148        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
02149               return;
02150        }
02151        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
02152        RETURN_STRING((char *)mysql_sqlstate(mysql->mysql),1);
02153 }
02154 /* }}} */
02155 
02156 /* {{{ proto bool mysqli_ssl_set(object link ,string key ,string cert ,string ca ,string capath ,string cipher]) U
02157 */
02158 PHP_FUNCTION(mysqli_ssl_set)
02159 {
02160        MY_MYSQL      *mysql;
02161        zval          *mysql_link;
02162        char          *ssl_parm[5];
02163        int                  ssl_parm_len[5], i;
02164 
02165        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) {
02166               return;
02167        }
02168        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_INITIALIZED);
02169 
02170        for (i = 0; i < 5; i++) {
02171               if (!ssl_parm_len[i]) {
02172                      ssl_parm[i] = NULL;
02173               }
02174        }
02175 
02176        mysql_ssl_set(mysql->mysql, ssl_parm[0], ssl_parm[1], ssl_parm[2], ssl_parm[3], ssl_parm[4]);
02177 
02178        RETURN_TRUE;
02179 }
02180 /* }}} */
02181 
02182 /* {{{ proto mixed mysqli_stat(object link)
02183    Get current system status */
02184 PHP_FUNCTION(mysqli_stat)
02185 {
02186        MY_MYSQL      *mysql;
02187        zval          *mysql_link;
02188        char          *stat;
02189 #if defined(MYSQLI_USE_MYSQLND)
02190        uint          stat_len;
02191 #endif
02192 
02193        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
02194               return;
02195        }
02196        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
02197 
02198 #if !defined(MYSQLI_USE_MYSQLND)
02199        if ((stat = (char *)mysql_stat(mysql->mysql)))
02200        {
02201               RETURN_STRING(stat, 1);
02202 #else
02203        if (mysqlnd_stat(mysql->mysql, &stat, &stat_len) == PASS)
02204        {
02205               RETURN_STRINGL(stat, stat_len, 0);
02206 #endif
02207        } else {
02208               RETURN_FALSE;
02209        }
02210 }
02211 
02212 /* }}} */
02213 
02214 /* {{{ proto bool mysqli_refresh(object link, long options)
02215    Flush tables or caches, or reset replication server information */
02216 PHP_FUNCTION(mysqli_refresh)
02217 {
02218        MY_MYSQL *mysql;
02219        zval *mysql_link = NULL;
02220        long options;
02221 
02222        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_link, mysqli_link_class_entry, &options) == FAILURE) {
02223               return;
02224        }
02225        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_INITIALIZED);
02226 #ifdef MYSQLI_USE_MYSQLND
02227        RETURN_BOOL(!mysql_refresh(mysql->mysql, (uint8_t) options));
02228 #else
02229        RETURN_BOOL(!mysql_refresh(mysql->mysql, options));
02230 #endif
02231 }
02232 /* }}} */
02233 
02234 /* {{{ proto int mysqli_stmt_attr_set(object stmt, long attr, long mode)
02235 */
02236 PHP_FUNCTION(mysqli_stmt_attr_set)
02237 {
02238        MY_STMT       *stmt;
02239        zval   *mysql_stmt;
02240        long   mode_in;
02241 #if MYSQL_VERSION_ID >= 50107
02242        my_bool       mode_b;
02243 #endif
02244        ulong  mode;
02245        ulong  attr;
02246        void   *mode_p;
02247 
02248        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll", &mysql_stmt, mysqli_stmt_class_entry, &attr, &mode_in) == FAILURE) {
02249               return;
02250        }
02251        MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
02252 
02253        if (mode_in < 0) {
02254               php_error_docref(NULL TSRMLS_CC, E_WARNING, "mode should be non-negative, %ld passed", mode_in);
02255               RETURN_FALSE;
02256        }
02257 
02258        switch (attr) {
02259 #if MYSQL_VERSION_ID >= 50107
02260        case STMT_ATTR_UPDATE_MAX_LENGTH:
02261               mode_b = (my_bool) mode_in;
02262               mode_p = &mode_b;
02263               break;
02264 #endif
02265        default:
02266               mode = mode_in;
02267               mode_p = &mode;
02268               break;
02269        }
02270 #if !defined(MYSQLI_USE_MYSQLND)
02271        if (mysql_stmt_attr_set(stmt->stmt, attr, mode_p)) {
02272 #else
02273        if (FAIL == mysql_stmt_attr_set(stmt->stmt, attr, mode_p)) {
02274 #endif
02275               RETURN_FALSE;
02276        }
02277        RETURN_TRUE;
02278 }
02279 /* }}} */
02280 
02281 /* {{{ proto int mysqli_stmt_attr_get(object stmt, long attr)
02282 */
02283 PHP_FUNCTION(mysqli_stmt_attr_get)
02284 {
02285        MY_STMT       *stmt;
02286        zval   *mysql_stmt;
02287        ulong  value = 0;
02288        ulong  attr;
02289        int           rc;
02290 
02291        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_stmt, mysqli_stmt_class_entry, &attr) == FAILURE) {
02292               return;
02293        }
02294        MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
02295 
02296        if ((rc = mysql_stmt_attr_get(stmt->stmt, attr, &value))) {
02297               RETURN_FALSE;
02298        }
02299 
02300 #if MYSQL_VERSION_ID >= 50107
02301        if (attr == STMT_ATTR_UPDATE_MAX_LENGTH)
02302               value = *((my_bool *)&value);
02303 #endif
02304        RETURN_LONG((long)value);
02305 }
02306 /* }}} */
02307 
02308 /* {{{ proto int mysqli_stmt_errno(object stmt)
02309 */
02310 PHP_FUNCTION(mysqli_stmt_errno)
02311 {
02312        MY_STMT       *stmt;
02313        zval   *mysql_stmt;
02314 
02315        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
02316               return;
02317        }
02318        MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_INITIALIZED);
02319 
02320        RETURN_LONG(mysql_stmt_errno(stmt->stmt));
02321 }
02322 /* }}} */
02323 
02324 /* {{{ proto string mysqli_stmt_error(object stmt)
02325 */
02326 PHP_FUNCTION(mysqli_stmt_error)
02327 {
02328        MY_STMT       *stmt;
02329        zval   *mysql_stmt;
02330 
02331        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
02332               return;
02333        }
02334        MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_INITIALIZED);
02335 
02336        RETURN_STRING((char *)mysql_stmt_error(stmt->stmt),1);
02337 }
02338 /* }}} */
02339 
02340 /* {{{ proto mixed mysqli_stmt_init(object link)
02341    Initialize statement object
02342 */
02343 PHP_FUNCTION(mysqli_stmt_init)
02344 {
02345        MY_MYSQL             *mysql;
02346        MY_STMT                     *stmt;
02347        zval                 *mysql_link;
02348        MYSQLI_RESOURCE      *mysqli_resource;
02349 
02350        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",&mysql_link, mysqli_link_class_entry) == FAILURE) {
02351               return;
02352        }
02353        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
02354 
02355        stmt = (MY_STMT *)ecalloc(1,sizeof(MY_STMT));
02356 
02357        if (!(stmt->stmt = mysql_stmt_init(mysql->mysql))) {
02358               efree(stmt);
02359               RETURN_FALSE;
02360        }
02361 
02362        mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
02363        mysqli_resource->status = MYSQLI_STATUS_INITIALIZED;
02364        mysqli_resource->ptr = (void *)stmt;
02365        MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_stmt_class_entry);
02366 }
02367 /* }}} */
02368 
02369 /* {{{ proto bool mysqli_stmt_prepare(object stmt, string query)
02370    prepare server side statement with query
02371 */
02372 PHP_FUNCTION(mysqli_stmt_prepare)
02373 {
02374        MY_STMT       *stmt;
02375        zval   *mysql_stmt;
02376        char   *query;
02377        int           query_len;
02378 
02379        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_stmt, mysqli_stmt_class_entry, &query, &query_len) == FAILURE) {
02380               return;
02381        }
02382        MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_INITIALIZED);
02383 
02384        if (mysql_stmt_prepare(stmt->stmt, query, query_len)) {
02385               MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
02386               RETURN_FALSE;
02387        }
02388        /* change status */
02389        MYSQLI_SET_STATUS(&mysql_stmt, MYSQLI_STATUS_VALID);
02390        RETURN_TRUE;
02391 }
02392 /* }}} */
02393 
02394 /* {{{ proto mixed mysqli_stmt_result_metadata(object stmt)
02395    return result set from statement */
02396 PHP_FUNCTION(mysqli_stmt_result_metadata)
02397 {
02398        MY_STMT                     *stmt;
02399        MYSQL_RES            *result;
02400        zval                 *mysql_stmt;
02401        MYSQLI_RESOURCE      *mysqli_resource;
02402 
02403        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
02404               return;
02405        }
02406        MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
02407 
02408        if (!(result = mysql_stmt_result_metadata(stmt->stmt))){
02409               MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
02410               RETURN_FALSE;
02411        }
02412 
02413        mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
02414        mysqli_resource->ptr = (void *)result;
02415        mysqli_resource->status = MYSQLI_STATUS_VALID;
02416        MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
02417 }
02418 /* }}} */
02419 
02420 /* {{{ proto bool mysqli_stmt_store_result(stmt)
02421 */
02422 PHP_FUNCTION(mysqli_stmt_store_result)
02423 {
02424        MY_STMT       *stmt;
02425        zval   *mysql_stmt;
02426 
02427        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
02428               return;
02429        }
02430        MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
02431 
02432 #if !defined(MYSQLI_USE_MYSQLND)
02433        {
02434               /*
02435                 If the user wants to store the data and we have BLOBs/TEXTs we try to allocate
02436                 not the maximal length of the type (which is 16MB even for LONGBLOB) but
02437                 the maximal length of the field in the result set. If he/she has quite big
02438                 BLOB/TEXT columns after calling store_result() the memory usage of PHP will
02439                 double - but this is a known problem of the simple MySQL API ;)
02440               */
02441               int    i = 0;
02442 
02443               for (i = mysql_stmt_field_count(stmt->stmt) - 1; i >=0; --i) {
02444                      if (stmt->stmt->fields && (stmt->stmt->fields[i].type == MYSQL_TYPE_BLOB ||
02445                             stmt->stmt->fields[i].type == MYSQL_TYPE_MEDIUM_BLOB ||
02446                             stmt->stmt->fields[i].type == MYSQL_TYPE_LONG_BLOB ||
02447                             stmt->stmt->fields[i].type == MYSQL_TYPE_GEOMETRY))
02448                      {
02449 #if MYSQL_VERSION_ID >= 50107
02450                             my_bool       tmp=1;
02451 #else
02452                             uint tmp=1;
02453 #endif
02454                             mysql_stmt_attr_set(stmt->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &tmp);
02455                             break;
02456                      }
02457               }
02458        }
02459 #endif
02460 
02461        if (mysql_stmt_store_result(stmt->stmt)){
02462               MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
02463               RETURN_FALSE;
02464        }
02465        RETURN_TRUE;
02466 }
02467 /* }}} */
02468 
02469 /* {{{ proto string mysqli_stmt_sqlstate(object stmt)
02470 */
02471 PHP_FUNCTION(mysqli_stmt_sqlstate)
02472 {
02473        MY_STMT       *stmt;
02474        zval   *mysql_stmt;
02475 
02476        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
02477               return;
02478        }
02479        MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
02480 
02481        RETURN_STRING((char *)mysql_stmt_sqlstate(stmt->stmt),1);
02482 }
02483 /* }}} */
02484 
02485 /* {{{ proto object mysqli_store_result(object link)
02486    Buffer result set on client */
02487 PHP_FUNCTION(mysqli_store_result)
02488 {
02489        MY_MYSQL             *mysql;
02490        MYSQL_RES            *result;
02491        zval                 *mysql_link;
02492        MYSQLI_RESOURCE      *mysqli_resource;
02493 
02494        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
02495               return;
02496        }
02497        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
02498 
02499        if (!(result = mysql_store_result(mysql->mysql))) {
02500               MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
02501               RETURN_FALSE;
02502        }
02503        if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
02504               php_mysqli_report_index("from previous query", mysqli_server_status(mysql->mysql) TSRMLS_CC);
02505        }
02506 
02507        mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
02508        mysqli_resource->ptr = (void *)result;
02509        mysqli_resource->status = MYSQLI_STATUS_VALID;
02510        MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
02511 }
02512 /* }}} */
02513 
02514 
02515 /* {{{ proto int mysqli_thread_id(object link)
02516    Return the current thread ID */
02517 PHP_FUNCTION(mysqli_thread_id)
02518 {
02519        MY_MYSQL      *mysql;
02520        zval          *mysql_link;
02521 
02522        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
02523               return;
02524        }
02525        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
02526 
02527        RETURN_LONG((long) mysql_thread_id(mysql->mysql));
02528 }
02529 /* }}} */
02530 
02531 /* {{{ proto bool mysqli_thread_safe(void)
02532    Return whether thread safety is given or not */
02533 PHP_FUNCTION(mysqli_thread_safe)
02534 {
02535        RETURN_BOOL(mysql_thread_safe());
02536 }
02537 /* }}} */
02538 
02539 /* {{{ proto mixed mysqli_use_result(object link)
02540    Directly retrieve query results - do not buffer results on client side */
02541 PHP_FUNCTION(mysqli_use_result)
02542 {
02543        MY_MYSQL             *mysql;
02544        MYSQL_RES            *result;
02545        zval                 *mysql_link;
02546        MYSQLI_RESOURCE      *mysqli_resource;
02547 
02548        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
02549               return;
02550        }
02551        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
02552 
02553        if (!(result = mysql_use_result(mysql->mysql))) {
02554               MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
02555               RETURN_FALSE;
02556        }
02557 
02558        if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
02559               php_mysqli_report_index("from previous query", mysqli_server_status(mysql->mysql) TSRMLS_CC);
02560        }
02561        mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
02562        mysqli_resource->ptr = (void *)result;
02563        mysqli_resource->status = MYSQLI_STATUS_VALID;
02564        MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
02565 }
02566 /* }}} */
02567 
02568 /* {{{ proto int mysqli_warning_count (object link)
02569    Return number of warnings from the last query for the given link */
02570 PHP_FUNCTION(mysqli_warning_count)
02571 {
02572        MY_MYSQL      *mysql;
02573        zval          *mysql_link;
02574 
02575        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
02576               return;
02577        }
02578        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
02579 
02580        RETURN_LONG(mysql_warning_count(mysql->mysql));
02581 }
02582 /* }}} */
02583 
02584 /*
02585  * Local variables:
02586  * tab-width: 4
02587  * c-basic-offset: 4
02588  * End:
02589  * vim600: noet sw=4 ts=4 fdm=marker
02590  * vim<600: noet sw=4 ts=4
02591  */