Annotation of embedaddon/php/ext/mysqli/mysqli_api.c, revision 1.1.1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>