Annotation of embedaddon/php/ext/mysqli/mysqli.c, revision 1.1.1.5

1.1       misho       1: /*
                      2:   +----------------------------------------------------------------------+
                      3:   | PHP Version 5                                                        |
                      4:   +----------------------------------------------------------------------+
1.1.1.5 ! misho       5:   | Copyright (c) 1997-2014 The PHP Group                                |
1.1       misho       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: 
1.1.1.2   misho      20:   $Id$
1.1       misho      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 "ext/standard/info.h"
                     32: #include "ext/standard/php_string.h"
1.1.1.2   misho      33: #include "php_mysqli.h"
1.1       misho      34: #include "php_mysqli_structs.h"
                     35: #include "mysqli_priv.h"
                     36: #include "zend_exceptions.h"
1.1.1.2   misho      37: #include "zend_interfaces.h"
1.1       misho      38: 
                     39: ZEND_DECLARE_MODULE_GLOBALS(mysqli)
                     40: static PHP_GINIT_FUNCTION(mysqli);
                     41: 
                     42: #define MYSQLI_ADD_PROPERTIES(a,b) \
                     43: { \
                     44:        int i = 0; \
                     45:        while (b[i].pname != NULL) { \
                     46:                mysqli_add_property((a), (b)[i].pname, (b)[i].pname_length, \
                     47:                                                        (mysqli_read_t)(b)[i].r_func, (mysqli_write_t)(b)[i].w_func TSRMLS_CC); \
                     48:                i++; \
                     49:        }\
                     50: }
                     51: 
                     52: #define MYSQLI_ADD_PROPERTIES_INFO(a,b) \
                     53: { \
                     54:        int i = 0; \
                     55:        while (b[i].name != NULL) { \
                     56:                zend_declare_property_null((a), (b)[i].name, (b)[i].name_length, ZEND_ACC_PUBLIC TSRMLS_CC); \
                     57:                i++; \
                     58:        }\
                     59: }
                     60: 
                     61: 
                     62: 
                     63: static zend_object_handlers mysqli_object_handlers;
                     64: static HashTable classes;
                     65: static HashTable mysqli_driver_properties;
                     66: static HashTable mysqli_link_properties;
                     67: static HashTable mysqli_result_properties;
                     68: static HashTable mysqli_stmt_properties;
                     69: static HashTable mysqli_warning_properties;
                     70: 
                     71: zend_class_entry *mysqli_link_class_entry;
                     72: zend_class_entry *mysqli_stmt_class_entry;
                     73: zend_class_entry *mysqli_result_class_entry;
                     74: zend_class_entry *mysqli_driver_class_entry;
                     75: zend_class_entry *mysqli_warning_class_entry;
                     76: zend_class_entry *mysqli_exception_class_entry;
                     77: 
                     78: 
                     79: typedef int (*mysqli_read_t)(mysqli_object *obj, zval **retval TSRMLS_DC);
                     80: typedef int (*mysqli_write_t)(mysqli_object *obj, zval *newval TSRMLS_DC);
                     81: 
                     82: typedef struct _mysqli_prop_handler {
                     83:        char *name;
                     84:        size_t name_len;
                     85:        mysqli_read_t read_func;
                     86:        mysqli_write_t write_func;
                     87: } mysqli_prop_handler;
                     88: 
                     89: static int le_pmysqli;
                     90: 
                     91: 
                     92: /* Destructor for mysqli entries in free_links/used_links */
                     93: void php_mysqli_dtor_p_elements(void *data)
                     94: {
                     95:        MYSQL *mysql = (MYSQL *) data;
                     96:        TSRMLS_FETCH();
                     97:        mysqli_close(mysql, MYSQLI_CLOSE_IMPLICIT);
                     98: }
                     99: 
                    100: 
                    101: ZEND_RSRC_DTOR_FUNC(php_mysqli_dtor)
                    102: {
                    103:        if (rsrc->ptr) {
                    104:                mysqli_plist_entry *plist = (mysqli_plist_entry *) rsrc->ptr;
                    105:                zend_ptr_stack_clean(&plist->free_links, php_mysqli_dtor_p_elements, 0);
                    106:                zend_ptr_stack_destroy(&plist->free_links);
                    107:                free(plist);
                    108:        }
                    109: }
                    110: 
                    111: 
                    112: int php_le_pmysqli(void)
                    113: {
                    114:        return le_pmysqli;
                    115: }
                    116: 
                    117: #ifndef MYSQLI_USE_MYSQLND
                    118: /* {{{ php_free_stmt_bind_buffer */
                    119: void php_free_stmt_bind_buffer(BIND_BUFFER bbuf, int type)
                    120: {
                    121:        unsigned int i;
                    122: 
                    123:        if (!bbuf.var_cnt) {
                    124:                return;
                    125:        }
                    126: 
                    127:        for (i=0; i < bbuf.var_cnt; i++) {
                    128: 
                    129:                /* free temporary bind buffer */
                    130:                if (type == FETCH_RESULT && bbuf.buf[i].val) {
                    131:                        efree(bbuf.buf[i].val);
                    132:                }
                    133: 
                    134:                if (bbuf.vars[i]) {
                    135:                        zval_ptr_dtor(&bbuf.vars[i]);
                    136:                }
                    137:        }
                    138: 
                    139:        if (bbuf.vars) {
                    140:                efree(bbuf.vars);
                    141:        }
                    142: 
                    143:        /*
                    144:          Don't free bbuf.is_null for FETCH_RESULT since we have allocated
                    145:          is_null and buf in one block so we free only buf, which is the beginning
                    146:          of the block. When FETCH_SIMPLE then buf wasn't allocated together with
                    147:          buf and we have to free it.
                    148:        */
                    149:        if (type == FETCH_RESULT) {
                    150:                efree(bbuf.buf);
                    151:        } else if (type == FETCH_SIMPLE){
                    152:                efree(bbuf.is_null);
                    153:        }
                    154: 
                    155:        bbuf.var_cnt = 0;
                    156: }
                    157: /* }}} */
                    158: #endif
                    159: 
                    160: /* {{{ php_clear_stmt_bind */
                    161: void php_clear_stmt_bind(MY_STMT *stmt TSRMLS_DC)
                    162: {
                    163:        if (stmt->stmt) {
                    164:                if (mysqli_stmt_close(stmt->stmt, TRUE)) {
1.1.1.3   misho     165:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error occurred while closing statement");
1.1       misho     166:                        return;
                    167:                }
                    168:        }
                    169: 
                    170:        /*
                    171:          mysqlnd keeps track of the binding and has freed its
                    172:          structures in stmt_close() above
                    173:        */
                    174: #ifndef MYSQLI_USE_MYSQLND
                    175:        /* Clean param bind */
                    176:        php_free_stmt_bind_buffer(stmt->param, FETCH_SIMPLE);
                    177:        /* Clean output bind */
                    178:        php_free_stmt_bind_buffer(stmt->result, FETCH_RESULT);
                    179: 
1.1.1.5 ! misho     180:        if (stmt->link_handle) {
        !           181:            zend_objects_store_del_ref_by_handle(stmt->link_handle TSRMLS_CC);
        !           182:        }
        !           183: #endif
1.1       misho     184:        if (stmt->query) {
                    185:                efree(stmt->query);
                    186:        }
                    187:        efree(stmt);
                    188: }
                    189: /* }}} */
                    190: 
                    191: /* {{{ php_clear_mysql */
                    192: void php_clear_mysql(MY_MYSQL *mysql) {
                    193:        if (mysql->hash_key) {
                    194:                efree(mysql->hash_key);
                    195:                mysql->hash_key = NULL;
                    196:        }
                    197:        if (mysql->li_read) {
                    198:                zval_ptr_dtor(&(mysql->li_read));
                    199:                mysql->li_read = NULL;
                    200:        }
                    201: }
                    202: /* }}} */
                    203: 
                    204: /* {{{ mysqli_objects_free_storage
                    205:  */
                    206: static void mysqli_objects_free_storage(void *object TSRMLS_DC)
                    207: {
                    208:        zend_object *zo = (zend_object *)object;
                    209:        mysqli_object   *intern = (mysqli_object *)zo;
                    210:        MYSQLI_RESOURCE *my_res = (MYSQLI_RESOURCE *)intern->ptr;
                    211: 
                    212:        my_efree(my_res);
                    213:        zend_object_std_dtor(&intern->zo TSRMLS_CC);
                    214:        efree(intern);
                    215: }
                    216: /* }}} */
                    217: 
                    218: /* mysqli_link_free_storage partly doubles the work of PHP_FUNCTION(mysqli_close) */
                    219: 
                    220: /* {{{ mysqli_link_free_storage
                    221:  */
                    222: static void mysqli_link_free_storage(void *object TSRMLS_DC)
                    223: {
                    224:        zend_object *zo = (zend_object *)object;
                    225:        mysqli_object   *intern = (mysqli_object *)zo;
                    226:        MYSQLI_RESOURCE *my_res = (MYSQLI_RESOURCE *)intern->ptr;
                    227: 
                    228:        if (my_res && my_res->ptr) {
                    229:                MY_MYSQL *mysql = (MY_MYSQL *)my_res->ptr;
                    230:                if (mysql->mysql) {
                    231:                        php_mysqli_close(mysql, MYSQLI_CLOSE_EXPLICIT, my_res->status TSRMLS_CC);
                    232:                }
                    233:                php_clear_mysql(mysql);
                    234:                efree(mysql);
                    235:                my_res->status = MYSQLI_STATUS_UNKNOWN;
                    236:        }
                    237:        mysqli_objects_free_storage(object TSRMLS_CC);
                    238: }
                    239: /* }}} */
                    240: 
                    241: /* {{{ mysql_driver_free_storage */
                    242: static void mysqli_driver_free_storage(void *object TSRMLS_DC)
                    243: {
                    244:        mysqli_objects_free_storage(object TSRMLS_CC);
                    245: }
                    246: /* }}} */
                    247: 
                    248: /* {{{ mysqli_stmt_free_storage
                    249:  */
                    250: static void mysqli_stmt_free_storage(void *object TSRMLS_DC)
                    251: {
                    252:        zend_object *zo = (zend_object *)object;
                    253:        mysqli_object   *intern = (mysqli_object *)zo;
                    254:        MYSQLI_RESOURCE *my_res = (MYSQLI_RESOURCE *)intern->ptr;
                    255: 
                    256:        if (my_res && my_res->ptr) {
                    257:                MY_STMT *stmt = (MY_STMT *)my_res->ptr;
                    258:                php_clear_stmt_bind(stmt TSRMLS_CC);
                    259:        }
                    260:        mysqli_objects_free_storage(object TSRMLS_CC);
                    261: }
                    262: /* }}} */
                    263: 
                    264: /* {{{ mysqli_result_free_storage
                    265:  */
                    266: static void mysqli_result_free_storage(void *object TSRMLS_DC)
                    267: {
                    268:        zend_object *zo = (zend_object *)object;
                    269:        mysqli_object   *intern = (mysqli_object *)zo;
                    270:        MYSQLI_RESOURCE *my_res = (MYSQLI_RESOURCE *)intern->ptr;
                    271: 
                    272:        if (my_res && my_res->ptr) {
                    273:                mysql_free_result(my_res->ptr);
                    274:        }
                    275:        mysqli_objects_free_storage(object TSRMLS_CC);
                    276: }
                    277: /* }}} */
                    278: 
                    279: /* {{{ mysqli_warning_free_storage
                    280:  */
                    281: static void mysqli_warning_free_storage(void *object TSRMLS_DC)
                    282: {
                    283:        zend_object *zo = (zend_object *)object;
                    284:        mysqli_object   *intern = (mysqli_object *)zo;
                    285:        MYSQLI_RESOURCE *my_res = (MYSQLI_RESOURCE *)intern->ptr;
                    286: 
                    287:        if (my_res && my_res->ptr) {
                    288:                php_clear_warnings((MYSQLI_WARNING *)my_res->info);
                    289:                my_res->ptr = NULL;
                    290:        }
                    291:        mysqli_objects_free_storage(object TSRMLS_CC);
                    292: }
                    293: /* }}} */
                    294: 
                    295: /* {{{ mysqli_read_na */
                    296: static int mysqli_read_na(mysqli_object *obj, zval **retval TSRMLS_DC)
                    297: {
                    298:        *retval = NULL;
                    299:        php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot read property");
                    300:        return FAILURE;
                    301: }
                    302: /* }}} */
                    303: 
                    304: /* {{{ mysqli_write_na */
                    305: static int mysqli_write_na(mysqli_object *obj, zval *newval TSRMLS_DC)
                    306: {
                    307:        php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot write property");
                    308:        return FAILURE;
                    309: }
                    310: /* }}} */
                    311: 
                    312: #ifndef Z_ADDREF_P
                    313: /* PHP 5.2, old GC */
                    314: #define Z_ADDREF_P(pz)                         (++(pz)->refcount)
                    315: #define Z_REFCOUNT_P(pz)                       ((pz)->refcount)
                    316: #define Z_SET_REFCOUNT_P(pz, rc)       ((pz)->refcount = rc)
                    317: #endif
                    318: 
                    319: 
                    320: /* {{{ mysqli_read_property */
1.1.1.2   misho     321: zval *mysqli_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC)
1.1       misho     322: {
                    323:        zval tmp_member;
                    324:        zval *retval;
                    325:        mysqli_object *obj;
                    326:        mysqli_prop_handler *hnd;
                    327:        int ret;
                    328: 
                    329:        ret = FAILURE;
                    330:        obj = (mysqli_object *)zend_objects_get_address(object TSRMLS_CC);
                    331: 
                    332:        if (member->type != IS_STRING) {
                    333:                tmp_member = *member;
                    334:                zval_copy_ctor(&tmp_member);
                    335:                convert_to_string(&tmp_member);
                    336:                member = &tmp_member;
                    337:        }
                    338: 
                    339:        if (obj->prop_handler != NULL) {
                    340:                ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
                    341:        }
                    342: 
                    343:        if (ret == SUCCESS) {
                    344:                ret = hnd->read_func(obj, &retval TSRMLS_CC);
                    345:                if (ret == SUCCESS) {
                    346:                        /* ensure we're creating a temporary variable */
                    347:                        Z_SET_REFCOUNT_P(retval, 0);
                    348:                } else {
                    349:                        retval = EG(uninitialized_zval_ptr);
                    350:                }
                    351:        } else {
                    352:                zend_object_handlers * std_hnd = zend_get_std_object_handlers();
1.1.1.2   misho     353:                retval = std_hnd->read_property(object, member, type, key TSRMLS_CC);
1.1       misho     354:        }
                    355: 
                    356:        if (member == &tmp_member) {
                    357:                zval_dtor(member);
                    358:        }
                    359:        return(retval);
                    360: }
                    361: /* }}} */
                    362: 
                    363: /* {{{ mysqli_write_property */
1.1.1.2   misho     364: void mysqli_write_property(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC)
1.1       misho     365: {
                    366:        zval tmp_member;
                    367:        mysqli_object *obj;
                    368:        mysqli_prop_handler *hnd;
                    369:        int ret;
                    370: 
                    371:        if (member->type != IS_STRING) {
                    372:                tmp_member = *member;
                    373:                zval_copy_ctor(&tmp_member);
                    374:                convert_to_string(&tmp_member);
                    375:                member = &tmp_member;
                    376:        }
                    377: 
                    378:        ret = FAILURE;
                    379:        obj = (mysqli_object *)zend_objects_get_address(object TSRMLS_CC);
                    380: 
                    381:        if (obj->prop_handler != NULL) {
                    382:                ret = zend_hash_find((HashTable *)obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
                    383:        }
                    384:        if (ret == SUCCESS) {
                    385:                hnd->write_func(obj, value TSRMLS_CC);
                    386:                if (! PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) == 0) {
                    387:                        Z_ADDREF_P(value);
                    388:                        zval_ptr_dtor(&value);
                    389:                }
                    390:        } else {
                    391:                zend_object_handlers * std_hnd = zend_get_std_object_handlers();
1.1.1.2   misho     392:                std_hnd->write_property(object, member, value, key TSRMLS_CC);
1.1       misho     393:        }
                    394: 
                    395:        if (member == &tmp_member) {
                    396:                zval_dtor(member);
                    397:        }
                    398: }
                    399: /* }}} */
                    400: 
                    401: /* {{{ void mysqli_add_property(HashTable *h, char *pname, mysqli_read_t r_func, mysqli_write_t w_func TSRMLS_DC) */
                    402: void mysqli_add_property(HashTable *h, const char *pname, size_t pname_len, mysqli_read_t r_func, mysqli_write_t w_func TSRMLS_DC) {
                    403:        mysqli_prop_handler             p;
                    404: 
                    405:        p.name = (char*) pname;
                    406:        p.name_len = pname_len;
                    407:        p.read_func = (r_func) ? r_func : mysqli_read_na;
                    408:        p.write_func = (w_func) ? w_func : mysqli_write_na;
                    409:        zend_hash_add(h, pname, pname_len + 1, &p, sizeof(mysqli_prop_handler), NULL);
                    410: }
                    411: /* }}} */
                    412: 
1.1.1.2   misho     413: static int mysqli_object_has_property(zval *object, zval *member, int has_set_exists, const zend_literal *key TSRMLS_DC) /* {{{ */
1.1       misho     414: {
                    415:        mysqli_object *obj = (mysqli_object *)zend_objects_get_address(object TSRMLS_CC);
                    416:        mysqli_prop_handler     p;
                    417:        int ret = 0;
                    418: 
                    419:        if (zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member) + 1, (void **)&p) == SUCCESS) {
                    420:                switch (has_set_exists) {
                    421:                        case 2:
                    422:                                ret = 1;
                    423:                                break;
                    424:                        case 1: {
1.1.1.2   misho     425:                                zval *value = mysqli_read_property(object, member, BP_VAR_IS, key TSRMLS_CC);
1.1       misho     426:                                if (value != EG(uninitialized_zval_ptr)) {
                    427:                                        convert_to_boolean(value);
                    428:                                        ret = Z_BVAL_P(value)? 1:0;
                    429:                                        /* refcount is 0 */
                    430:                                        Z_ADDREF_P(value);
                    431:                                        zval_ptr_dtor(&value);
                    432:                                }
                    433:                                break;
                    434:                        }
                    435:                        case 0:{
1.1.1.2   misho     436:                                zval *value = mysqli_read_property(object, member, BP_VAR_IS, key TSRMLS_CC);
1.1       misho     437:                                if (value != EG(uninitialized_zval_ptr)) {
                    438:                                        ret = Z_TYPE_P(value) != IS_NULL? 1:0;
                    439:                                        /* refcount is 0 */
                    440:                                        Z_ADDREF_P(value);
                    441:                                        zval_ptr_dtor(&value);
                    442:                                }
                    443:                                break;
                    444:                        }
                    445:                        default:
                    446:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid value for has_set_exists");
                    447:                }
                    448:        } else {
                    449:                zend_object_handlers * std_hnd = zend_get_std_object_handlers();
1.1.1.2   misho     450:                ret = std_hnd->has_property(object, member, has_set_exists, key TSRMLS_CC);
1.1       misho     451:        }
                    452:        return ret;
                    453: } /* }}} */
                    454: 
                    455: 
                    456: #if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3
                    457: HashTable * mysqli_object_get_debug_info(zval *object, int *is_temp TSRMLS_DC)
                    458: {
                    459:        mysqli_object *obj = (mysqli_object *)zend_objects_get_address(object TSRMLS_CC);
                    460:        HashTable *retval, *props = obj->prop_handler;
                    461:        HashPosition pos;
                    462:        mysqli_prop_handler *entry;
                    463: 
                    464:        ALLOC_HASHTABLE(retval);
                    465:        ZEND_INIT_SYMTABLE_EX(retval, zend_hash_num_elements(props) + 1, 0);
                    466: 
                    467:        zend_hash_internal_pointer_reset_ex(props, &pos);
                    468:        while (zend_hash_get_current_data_ex(props, (void **)&entry, &pos) == SUCCESS) {
                    469:                zval member;
                    470:                zval *value;
                    471:                INIT_ZVAL(member);
                    472:                ZVAL_STRINGL(&member, entry->name, entry->name_len, 0);
1.1.1.2   misho     473:                value = mysqli_read_property(object, &member, BP_VAR_IS, 0 TSRMLS_CC);
1.1       misho     474:                if (value != EG(uninitialized_zval_ptr)) {
                    475:                        Z_ADDREF_P(value);
                    476:                        zend_hash_add(retval, entry->name, entry->name_len + 1, &value, sizeof(zval *), NULL);
                    477:                }
                    478:                zend_hash_move_forward_ex(props, &pos);
                    479:        }
                    480: 
                    481:        *is_temp = 1;
                    482:        return retval;
                    483: }
                    484: #endif
                    485: 
                    486: /* {{{ mysqli_objects_new
                    487:  */
                    488: PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry *class_type TSRMLS_DC)
                    489: {
                    490:        zend_object_value retval;
                    491:        mysqli_object *intern;
                    492:        zend_class_entry *mysqli_base_class;
                    493:        zend_objects_free_object_storage_t free_storage;
                    494: 
                    495:        intern = emalloc(sizeof(mysqli_object));
                    496:        memset(intern, 0, sizeof(mysqli_object));
                    497:        intern->ptr = NULL;
                    498:        intern->prop_handler = NULL;
                    499: 
                    500:        mysqli_base_class = class_type;
                    501:        while (mysqli_base_class->type != ZEND_INTERNAL_CLASS &&
                    502:                   mysqli_base_class->parent != NULL) {
                    503:                mysqli_base_class = mysqli_base_class->parent;
                    504:        }
                    505:        zend_hash_find(&classes, mysqli_base_class->name, mysqli_base_class->name_length + 1,
                    506:                                        (void **) &intern->prop_handler);
                    507: 
                    508:        zend_object_std_init(&intern->zo, class_type TSRMLS_CC);
1.1.1.2   misho     509:        object_properties_init(&intern->zo, class_type);
1.1       misho     510: 
                    511:        /* link object */
                    512:        if (instanceof_function(class_type, mysqli_link_class_entry TSRMLS_CC)) {
                    513:                free_storage = mysqli_link_free_storage;
                    514:        } else if (instanceof_function(class_type, mysqli_driver_class_entry TSRMLS_CC)) { /* driver object */
                    515:                free_storage = mysqli_driver_free_storage;
                    516:        } else if (instanceof_function(class_type, mysqli_stmt_class_entry TSRMLS_CC)) { /* stmt object */
                    517:                free_storage = mysqli_stmt_free_storage;
                    518:        } else if (instanceof_function(class_type, mysqli_result_class_entry TSRMLS_CC)) { /* result object */
                    519:                free_storage = mysqli_result_free_storage;
                    520:        } else if (instanceof_function(class_type, mysqli_warning_class_entry TSRMLS_CC)) { /* warning object */
                    521:                free_storage = mysqli_warning_free_storage;
                    522:        } else {
                    523:                free_storage = mysqli_objects_free_storage;
                    524:        }
                    525: 
                    526:        retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, free_storage, NULL TSRMLS_CC);
                    527:        retval.handlers = &mysqli_object_handlers;
                    528: 
                    529:        return retval;
                    530: }
                    531: /* }}} */
                    532: 
1.1.1.2   misho     533: #ifdef MYSQLI_USE_MYSQLND
                    534: #include "ext/mysqlnd/mysqlnd_reverse_api.h"
                    535: static MYSQLND *mysqli_convert_zv_to_mysqlnd(zval * zv TSRMLS_DC)
                    536: {
1.1.1.4   misho     537:        if (Z_TYPE_P(zv) == IS_OBJECT && instanceof_function(Z_OBJCE_P(zv), mysqli_link_class_entry TSRMLS_CC)) {
1.1.1.2   misho     538:                MY_MYSQL * mysql;
                    539:                MYSQLI_RESOURCE  * my_res;
                    540:                mysqli_object * intern = (mysqli_object *)zend_object_store_get_object(zv TSRMLS_CC);
                    541:                if (!(my_res = (MYSQLI_RESOURCE *)intern->ptr)) {
                    542:                        /* We know that we have a mysqli object, so this failure should be emitted */
                    543:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %s", intern->zo.ce->name);
                    544:                        return NULL;
                    545:                }
                    546:                mysql = (MY_MYSQL *)(my_res->ptr);
                    547:                return mysql ? mysql->mysql : NULL;
                    548:        }
                    549:        return NULL;
                    550: }
                    551: 
                    552: static MYSQLND_REVERSE_API mysqli_reverse_api = {
                    553:        &mysqli_module_entry,
                    554:        mysqli_convert_zv_to_mysqlnd
                    555: };
                    556: #endif
1.1       misho     557: 
                    558: /* {{{ PHP_INI_BEGIN
                    559: */
                    560: PHP_INI_BEGIN()
                    561:        STD_PHP_INI_ENTRY_EX("mysqli.max_links",                        "-1",   PHP_INI_SYSTEM,         OnUpdateLong,           max_links,                      zend_mysqli_globals,            mysqli_globals, display_link_numbers)
                    562:        STD_PHP_INI_ENTRY_EX("mysqli.max_persistent",           "-1",   PHP_INI_SYSTEM,         OnUpdateLong,           max_persistent,         zend_mysqli_globals,            mysqli_globals, display_link_numbers)
                    563:        STD_PHP_INI_BOOLEAN("mysqli.allow_persistent",          "1",    PHP_INI_SYSTEM,         OnUpdateLong,           allow_persistent,       zend_mysqli_globals,            mysqli_globals)
                    564:        STD_PHP_INI_ENTRY("mysqli.default_host",                        NULL,   PHP_INI_ALL,            OnUpdateString,         default_host,           zend_mysqli_globals,            mysqli_globals)
                    565:        STD_PHP_INI_ENTRY("mysqli.default_user",                        NULL,   PHP_INI_ALL,            OnUpdateString,         default_user,           zend_mysqli_globals,            mysqli_globals)
                    566:        STD_PHP_INI_ENTRY("mysqli.default_pw",                          NULL,   PHP_INI_ALL,            OnUpdateString,         default_pw,                     zend_mysqli_globals,            mysqli_globals)
                    567:        STD_PHP_INI_ENTRY("mysqli.default_port",                        "3306", PHP_INI_ALL,            OnUpdateLong,           default_port,           zend_mysqli_globals,            mysqli_globals)
                    568: #ifdef PHP_MYSQL_UNIX_SOCK_ADDR
                    569:        STD_PHP_INI_ENTRY("mysqli.default_socket",                      MYSQL_UNIX_ADDR,PHP_INI_ALL,OnUpdateStringUnempty,      default_socket, zend_mysqli_globals,            mysqli_globals)
                    570: #else
                    571:        STD_PHP_INI_ENTRY("mysqli.default_socket",                      NULL,   PHP_INI_ALL,            OnUpdateStringUnempty,  default_socket, zend_mysqli_globals,            mysqli_globals)
                    572: #endif
                    573:        STD_PHP_INI_BOOLEAN("mysqli.reconnect",                         "0",    PHP_INI_SYSTEM,         OnUpdateLong,           reconnect,                      zend_mysqli_globals,            mysqli_globals)
                    574:        STD_PHP_INI_BOOLEAN("mysqli.allow_local_infile",        "1",    PHP_INI_SYSTEM,         OnUpdateLong,           allow_local_infile,     zend_mysqli_globals,            mysqli_globals)
                    575: PHP_INI_END()
                    576: /* }}} */
                    577: 
                    578: 
                    579: /* {{{ PHP_GINIT_FUNCTION
                    580:  */
                    581: static PHP_GINIT_FUNCTION(mysqli)
                    582: {
                    583:        mysqli_globals->num_links = 0;
                    584:        mysqli_globals->num_active_persistent = 0;
                    585:        mysqli_globals->num_inactive_persistent = 0;
                    586:        mysqli_globals->max_links = -1;
                    587:        mysqli_globals->max_persistent = -1;
                    588:        mysqli_globals->allow_persistent = 1;
                    589:        mysqli_globals->default_port = 0;
                    590:        mysqli_globals->default_host = NULL;
                    591:        mysqli_globals->default_user = NULL;
                    592:        mysqli_globals->default_pw = NULL;
                    593:        mysqli_globals->default_socket = NULL;
                    594:        mysqli_globals->reconnect = 0;
                    595:        mysqli_globals->report_mode = 0;
                    596:        mysqli_globals->report_ht = 0;
                    597:        mysqli_globals->allow_local_infile = 1;
                    598: #ifdef HAVE_EMBEDDED_MYSQLI
                    599:        mysqli_globals->embedded = 1;
                    600: #else
                    601:        mysqli_globals->embedded = 0;
                    602: #endif
                    603: }
                    604: /* }}} */
                    605: 
                    606: /* {{{ PHP_MINIT_FUNCTION
                    607:  */
                    608: PHP_MINIT_FUNCTION(mysqli)
                    609: {
                    610:        zend_class_entry *ce,cex;
                    611:        zend_object_handlers *std_hnd = zend_get_std_object_handlers();
                    612: 
                    613:        REGISTER_INI_ENTRIES();
                    614: #ifndef MYSQLI_USE_MYSQLND
                    615: #if MYSQL_VERSION_ID >= 40000
                    616:        if (mysql_server_init(0, NULL, NULL)) {
                    617:                return FAILURE;
                    618:        }
                    619: #endif
                    620: #endif
                    621: 
                    622:        memcpy(&mysqli_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
                    623:        mysqli_object_handlers.clone_obj = NULL;
                    624:        mysqli_object_handlers.read_property = mysqli_read_property;
                    625:        mysqli_object_handlers.write_property = mysqli_write_property;
                    626:        mysqli_object_handlers.get_property_ptr_ptr = std_hnd->get_property_ptr_ptr;
                    627:        mysqli_object_handlers.has_property = mysqli_object_has_property;
                    628: #if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3
                    629:        mysqli_object_handlers.get_debug_info = mysqli_object_get_debug_info;
                    630: #endif
                    631: 
                    632:        zend_hash_init(&classes, 0, NULL, NULL, 1);
                    633: 
                    634:        /* persistent connections */
                    635:        le_pmysqli = zend_register_list_destructors_ex(NULL, php_mysqli_dtor,
                    636:                "MySqli persistent connection", module_number);
                    637: 
                    638:        INIT_CLASS_ENTRY(cex, "mysqli_sql_exception", mysqli_exception_methods);
                    639: #ifdef HAVE_SPL
                    640:        mysqli_exception_class_entry = zend_register_internal_class_ex(&cex, spl_ce_RuntimeException, NULL TSRMLS_CC);
                    641: #else
                    642:        mysqli_exception_class_entry = zend_register_internal_class_ex(&cex, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
                    643: #endif
                    644:        mysqli_exception_class_entry->ce_flags |= ZEND_ACC_FINAL;
                    645:        zend_declare_property_long(mysqli_exception_class_entry, "code", sizeof("code")-1, 0, ZEND_ACC_PROTECTED TSRMLS_CC);
                    646:        zend_declare_property_string(mysqli_exception_class_entry, "sqlstate", sizeof("sqlstate")-1, "00000", ZEND_ACC_PROTECTED TSRMLS_CC);
                    647: 
                    648:        REGISTER_MYSQLI_CLASS_ENTRY("mysqli_driver", mysqli_driver_class_entry, mysqli_driver_methods);
                    649:        ce = mysqli_driver_class_entry;
                    650:        zend_hash_init(&mysqli_driver_properties, 0, NULL, NULL, 1);
                    651:        MYSQLI_ADD_PROPERTIES(&mysqli_driver_properties, mysqli_driver_property_entries);
                    652:        MYSQLI_ADD_PROPERTIES_INFO(ce, mysqli_driver_property_info_entries);
                    653:        zend_hash_add(&classes, ce->name, ce->name_length+1, &mysqli_driver_properties, sizeof(mysqli_driver_properties), NULL);
                    654:        ce->ce_flags |= ZEND_ACC_FINAL_CLASS;
                    655: 
                    656:        REGISTER_MYSQLI_CLASS_ENTRY("mysqli", mysqli_link_class_entry, mysqli_link_methods);
                    657:        ce = mysqli_link_class_entry;
                    658:        zend_hash_init(&mysqli_link_properties, 0, NULL, NULL, 1);
                    659:        MYSQLI_ADD_PROPERTIES(&mysqli_link_properties, mysqli_link_property_entries);
                    660:        MYSQLI_ADD_PROPERTIES_INFO(ce, mysqli_link_property_info_entries);
                    661:        zend_hash_add(&classes, ce->name, ce->name_length+1, &mysqli_link_properties, sizeof(mysqli_link_properties), NULL);
                    662: 
                    663:        REGISTER_MYSQLI_CLASS_ENTRY("mysqli_warning", mysqli_warning_class_entry, mysqli_warning_methods);
                    664:        ce = mysqli_warning_class_entry;
                    665:        ce->ce_flags |= ZEND_ACC_FINAL_CLASS | ZEND_ACC_PROTECTED;
                    666:        zend_hash_init(&mysqli_warning_properties, 0, NULL, NULL, 1);
                    667:        MYSQLI_ADD_PROPERTIES(&mysqli_warning_properties, mysqli_warning_property_entries);
                    668:        MYSQLI_ADD_PROPERTIES_INFO(ce, mysqli_warning_property_info_entries);
                    669:        zend_hash_add(&classes, ce->name, ce->name_length+1, &mysqli_warning_properties, sizeof(mysqli_warning_properties), NULL);
                    670: 
                    671:        REGISTER_MYSQLI_CLASS_ENTRY("mysqli_result", mysqli_result_class_entry, mysqli_result_methods);
                    672:        ce = mysqli_result_class_entry;
                    673:        zend_hash_init(&mysqli_result_properties, 0, NULL, NULL, 1);
                    674:        MYSQLI_ADD_PROPERTIES(&mysqli_result_properties, mysqli_result_property_entries);
                    675:        MYSQLI_ADD_PROPERTIES_INFO(ce, mysqli_result_property_info_entries);
1.1.1.2   misho     676:        mysqli_result_class_entry->get_iterator = php_mysqli_result_get_iterator;
                    677:        mysqli_result_class_entry->iterator_funcs.funcs = &php_mysqli_result_iterator_funcs;
                    678:        zend_class_implements(mysqli_result_class_entry TSRMLS_CC, 1, zend_ce_traversable);
1.1       misho     679:        zend_hash_add(&classes, ce->name, ce->name_length+1, &mysqli_result_properties, sizeof(mysqli_result_properties), NULL);
                    680: 
                    681:        REGISTER_MYSQLI_CLASS_ENTRY("mysqli_stmt", mysqli_stmt_class_entry, mysqli_stmt_methods);
                    682:        ce = mysqli_stmt_class_entry;
                    683:        zend_hash_init(&mysqli_stmt_properties, 0, NULL, NULL, 1);
                    684:        MYSQLI_ADD_PROPERTIES(&mysqli_stmt_properties, mysqli_stmt_property_entries);
                    685:        MYSQLI_ADD_PROPERTIES_INFO(ce, mysqli_stmt_property_info_entries);
                    686:        zend_hash_add(&classes, ce->name, ce->name_length+1, &mysqli_stmt_properties, sizeof(mysqli_stmt_properties), NULL);
                    687: 
                    688:        /* mysqli_options */
                    689:        REGISTER_LONG_CONSTANT("MYSQLI_READ_DEFAULT_GROUP", MYSQL_READ_DEFAULT_GROUP, CONST_CS | CONST_PERSISTENT);
                    690:        REGISTER_LONG_CONSTANT("MYSQLI_READ_DEFAULT_FILE", MYSQL_READ_DEFAULT_FILE, CONST_CS | CONST_PERSISTENT);
                    691:        REGISTER_LONG_CONSTANT("MYSQLI_OPT_CONNECT_TIMEOUT", MYSQL_OPT_CONNECT_TIMEOUT, CONST_CS | CONST_PERSISTENT);
                    692:        REGISTER_LONG_CONSTANT("MYSQLI_OPT_LOCAL_INFILE", MYSQL_OPT_LOCAL_INFILE, CONST_CS | CONST_PERSISTENT);
                    693:        REGISTER_LONG_CONSTANT("MYSQLI_INIT_COMMAND", MYSQL_INIT_COMMAND, CONST_CS | CONST_PERSISTENT);
                    694: #if defined(MYSQLI_USE_MYSQLND)
                    695:        REGISTER_LONG_CONSTANT("MYSQLI_OPT_NET_CMD_BUFFER_SIZE", MYSQLND_OPT_NET_CMD_BUFFER_SIZE, CONST_CS | CONST_PERSISTENT);
                    696:        REGISTER_LONG_CONSTANT("MYSQLI_OPT_NET_READ_BUFFER_SIZE", MYSQLND_OPT_NET_READ_BUFFER_SIZE, CONST_CS | CONST_PERSISTENT);
                    697: #endif
                    698: #ifdef MYSQLND_STRING_TO_INT_CONVERSION
                    699:        REGISTER_LONG_CONSTANT("MYSQLI_OPT_INT_AND_FLOAT_NATIVE", MYSQLND_OPT_INT_AND_FLOAT_NATIVE, CONST_CS | CONST_PERSISTENT);
                    700: #endif
                    701: #if MYSQL_VERSION_ID > 50110 || defined(MYSQLI_USE_MYSQLND)
                    702:        REGISTER_LONG_CONSTANT("MYSQLI_OPT_SSL_VERIFY_SERVER_CERT", MYSQL_OPT_SSL_VERIFY_SERVER_CERT, CONST_CS | CONST_PERSISTENT);
                    703: #endif
                    704: 
                    705:        /* mysqli_real_connect flags */
                    706:        REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_SSL", CLIENT_SSL, CONST_CS | CONST_PERSISTENT);
                    707:        REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_COMPRESS",CLIENT_COMPRESS, CONST_CS | CONST_PERSISTENT);
                    708:        REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_INTERACTIVE", CLIENT_INTERACTIVE, CONST_CS | CONST_PERSISTENT);
                    709:        REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_IGNORE_SPACE", CLIENT_IGNORE_SPACE, CONST_CS | CONST_PERSISTENT);
                    710:        REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_NO_SCHEMA", CLIENT_NO_SCHEMA, CONST_CS | CONST_PERSISTENT);
                    711:        REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_FOUND_ROWS", CLIENT_FOUND_ROWS, CONST_CS | CONST_PERSISTENT);
                    712: 
                    713:        /* for mysqli_query */
                    714:        REGISTER_LONG_CONSTANT("MYSQLI_STORE_RESULT", MYSQLI_STORE_RESULT, CONST_CS | CONST_PERSISTENT);
                    715:        REGISTER_LONG_CONSTANT("MYSQLI_USE_RESULT", MYSQLI_USE_RESULT, CONST_CS | CONST_PERSISTENT);
                    716: #if defined (MYSQLI_USE_MYSQLND)
                    717:        REGISTER_LONG_CONSTANT("MYSQLI_ASYNC", MYSQLI_ASYNC, CONST_CS | CONST_PERSISTENT);
                    718: #endif
                    719: 
                    720:        /* for mysqli_fetch_assoc */
                    721:        REGISTER_LONG_CONSTANT("MYSQLI_ASSOC", MYSQLI_ASSOC, CONST_CS | CONST_PERSISTENT);
                    722:        REGISTER_LONG_CONSTANT("MYSQLI_NUM", MYSQLI_NUM, CONST_CS | CONST_PERSISTENT);
                    723:        REGISTER_LONG_CONSTANT("MYSQLI_BOTH", MYSQLI_BOTH, CONST_CS | CONST_PERSISTENT);
                    724: 
                    725:        /* for mysqli_stmt_set_attr */
                    726:        REGISTER_LONG_CONSTANT("MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH", STMT_ATTR_UPDATE_MAX_LENGTH, CONST_CS | CONST_PERSISTENT);
                    727: 
                    728: #if MYSQL_VERSION_ID > 50003 || defined(MYSQLI_USE_MYSQLND)
                    729:        REGISTER_LONG_CONSTANT("MYSQLI_STMT_ATTR_CURSOR_TYPE", STMT_ATTR_CURSOR_TYPE, CONST_CS | CONST_PERSISTENT);
                    730:        REGISTER_LONG_CONSTANT("MYSQLI_CURSOR_TYPE_NO_CURSOR", CURSOR_TYPE_NO_CURSOR, CONST_CS | CONST_PERSISTENT);
                    731:        REGISTER_LONG_CONSTANT("MYSQLI_CURSOR_TYPE_READ_ONLY", CURSOR_TYPE_READ_ONLY, CONST_CS | CONST_PERSISTENT);
                    732:        REGISTER_LONG_CONSTANT("MYSQLI_CURSOR_TYPE_FOR_UPDATE", CURSOR_TYPE_FOR_UPDATE, CONST_CS | CONST_PERSISTENT);
                    733:        REGISTER_LONG_CONSTANT("MYSQLI_CURSOR_TYPE_SCROLLABLE", CURSOR_TYPE_SCROLLABLE, CONST_CS | CONST_PERSISTENT);
                    734: #endif
                    735: 
                    736: #if MYSQL_VERSION_ID > 50007 || defined(MYSQLI_USE_MYSQLND)
                    737:        REGISTER_LONG_CONSTANT("MYSQLI_STMT_ATTR_PREFETCH_ROWS", STMT_ATTR_PREFETCH_ROWS, CONST_CS | CONST_PERSISTENT);
                    738: #endif
                    739: 
                    740:        /* column information */
                    741:        REGISTER_LONG_CONSTANT("MYSQLI_NOT_NULL_FLAG", NOT_NULL_FLAG, CONST_CS | CONST_PERSISTENT);
                    742:        REGISTER_LONG_CONSTANT("MYSQLI_PRI_KEY_FLAG", PRI_KEY_FLAG, CONST_CS | CONST_PERSISTENT);
                    743:        REGISTER_LONG_CONSTANT("MYSQLI_UNIQUE_KEY_FLAG", UNIQUE_KEY_FLAG, CONST_CS | CONST_PERSISTENT);
                    744:        REGISTER_LONG_CONSTANT("MYSQLI_MULTIPLE_KEY_FLAG", MULTIPLE_KEY_FLAG, CONST_CS | CONST_PERSISTENT);
                    745:        REGISTER_LONG_CONSTANT("MYSQLI_BLOB_FLAG", BLOB_FLAG, CONST_CS | CONST_PERSISTENT);
                    746:        REGISTER_LONG_CONSTANT("MYSQLI_UNSIGNED_FLAG", UNSIGNED_FLAG, CONST_CS | CONST_PERSISTENT);
                    747:        REGISTER_LONG_CONSTANT("MYSQLI_ZEROFILL_FLAG", ZEROFILL_FLAG, CONST_CS | CONST_PERSISTENT);
                    748:        REGISTER_LONG_CONSTANT("MYSQLI_AUTO_INCREMENT_FLAG", AUTO_INCREMENT_FLAG, CONST_CS | CONST_PERSISTENT);
                    749:        REGISTER_LONG_CONSTANT("MYSQLI_TIMESTAMP_FLAG", TIMESTAMP_FLAG, CONST_CS | CONST_PERSISTENT);
                    750:        REGISTER_LONG_CONSTANT("MYSQLI_SET_FLAG", SET_FLAG, CONST_CS | CONST_PERSISTENT);
                    751:        REGISTER_LONG_CONSTANT("MYSQLI_NUM_FLAG", NUM_FLAG, CONST_CS | CONST_PERSISTENT);
                    752:        REGISTER_LONG_CONSTANT("MYSQLI_PART_KEY_FLAG", PART_KEY_FLAG, CONST_CS | CONST_PERSISTENT);
                    753:        REGISTER_LONG_CONSTANT("MYSQLI_GROUP_FLAG", GROUP_FLAG, CONST_CS | CONST_PERSISTENT);
                    754:        REGISTER_LONG_CONSTANT("MYSQLI_ENUM_FLAG", ENUM_FLAG, CONST_CS | CONST_PERSISTENT);
                    755:        REGISTER_LONG_CONSTANT("MYSQLI_BINARY_FLAG", BINARY_FLAG, CONST_CS | CONST_PERSISTENT);
                    756: #if MYSQL_VERSION_ID > 50001 || defined(MYSQLI_USE_MYSQLND)
                    757:        REGISTER_LONG_CONSTANT("MYSQLI_NO_DEFAULT_VALUE_FLAG", NO_DEFAULT_VALUE_FLAG, CONST_CS | CONST_PERSISTENT);
                    758: #endif
                    759: 
                    760: #if (MYSQL_VERSION_ID > 51122 && MYSQL_VERSION_ID < 60000) || (MYSQL_VERSION_ID > 60003) || defined(MYSQLI_USE_MYSQLND)
                    761:        REGISTER_LONG_CONSTANT("MYSQLI_ON_UPDATE_NOW_FLAG", ON_UPDATE_NOW_FLAG, CONST_CS | CONST_PERSISTENT);
                    762: #endif
                    763: 
                    764:        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_DECIMAL", FIELD_TYPE_DECIMAL, CONST_CS | CONST_PERSISTENT);
                    765:        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_TINY", FIELD_TYPE_TINY, CONST_CS | CONST_PERSISTENT);
                    766:        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_SHORT", FIELD_TYPE_SHORT, CONST_CS | CONST_PERSISTENT);
                    767:        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_LONG", FIELD_TYPE_LONG, CONST_CS | CONST_PERSISTENT);
                    768:        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_FLOAT", FIELD_TYPE_FLOAT, CONST_CS | CONST_PERSISTENT);
                    769:        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_DOUBLE", FIELD_TYPE_DOUBLE, CONST_CS | CONST_PERSISTENT);
                    770:        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_NULL", FIELD_TYPE_NULL, CONST_CS | CONST_PERSISTENT);
                    771:        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_TIMESTAMP", FIELD_TYPE_TIMESTAMP, CONST_CS | CONST_PERSISTENT);
                    772:        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_LONGLONG", FIELD_TYPE_LONGLONG, CONST_CS | CONST_PERSISTENT);
                    773:        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_INT24", FIELD_TYPE_INT24, CONST_CS | CONST_PERSISTENT);
                    774:        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_DATE", FIELD_TYPE_DATE, CONST_CS | CONST_PERSISTENT);
                    775:        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_TIME", FIELD_TYPE_TIME, CONST_CS | CONST_PERSISTENT);
                    776:        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_DATETIME", FIELD_TYPE_DATETIME      , CONST_CS | CONST_PERSISTENT);
                    777:        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_YEAR", FIELD_TYPE_YEAR, CONST_CS | CONST_PERSISTENT);
                    778:        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_NEWDATE", FIELD_TYPE_NEWDATE, CONST_CS | CONST_PERSISTENT);
                    779:        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_ENUM", FIELD_TYPE_ENUM, CONST_CS | CONST_PERSISTENT);
                    780:        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_SET", FIELD_TYPE_SET, CONST_CS | CONST_PERSISTENT);
                    781:        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_TINY_BLOB", FIELD_TYPE_TINY_BLOB, CONST_CS | CONST_PERSISTENT);
                    782:        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_MEDIUM_BLOB", FIELD_TYPE_MEDIUM_BLOB, CONST_CS | CONST_PERSISTENT);
                    783:        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_LONG_BLOB", FIELD_TYPE_LONG_BLOB, CONST_CS | CONST_PERSISTENT);
                    784:        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_BLOB", FIELD_TYPE_BLOB, CONST_CS | CONST_PERSISTENT);
                    785:        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_VAR_STRING", FIELD_TYPE_VAR_STRING, CONST_CS | CONST_PERSISTENT);
                    786:        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_STRING", FIELD_TYPE_STRING, CONST_CS | CONST_PERSISTENT);
                    787:        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_CHAR", FIELD_TYPE_CHAR, CONST_CS | CONST_PERSISTENT);
                    788:        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_INTERVAL", FIELD_TYPE_INTERVAL, CONST_CS | CONST_PERSISTENT);
                    789:        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_GEOMETRY", FIELD_TYPE_GEOMETRY, CONST_CS | CONST_PERSISTENT);
                    790: 
                    791: #if MYSQL_VERSION_ID > 50002 || defined(MYSQLI_USE_MYSQLND)
                    792:        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_NEWDECIMAL", FIELD_TYPE_NEWDECIMAL, CONST_CS | CONST_PERSISTENT);
                    793:        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_BIT", FIELD_TYPE_BIT, CONST_CS | CONST_PERSISTENT);
                    794: #endif
                    795: 
                    796:        REGISTER_LONG_CONSTANT("MYSQLI_SET_CHARSET_NAME", MYSQL_SET_CHARSET_NAME, CONST_CS | CONST_PERSISTENT);
                    797:        REGISTER_LONG_CONSTANT("MYSQLI_SET_CHARSET_DIR", MYSQL_SET_CHARSET_DIR, CONST_CS | CONST_PERSISTENT);
                    798: 
                    799:        /* bind support */
                    800:        REGISTER_LONG_CONSTANT("MYSQLI_NO_DATA", MYSQL_NO_DATA, CONST_CS | CONST_PERSISTENT);
                    801: #ifdef MYSQL_DATA_TRUNCATED
                    802:        REGISTER_LONG_CONSTANT("MYSQLI_DATA_TRUNCATED", MYSQL_DATA_TRUNCATED, CONST_CS | CONST_PERSISTENT);
                    803: #endif
                    804: 
                    805:        /* reporting */
                    806:        REGISTER_LONG_CONSTANT("MYSQLI_REPORT_INDEX", MYSQLI_REPORT_INDEX, CONST_CS | CONST_PERSISTENT);
                    807:        REGISTER_LONG_CONSTANT("MYSQLI_REPORT_ERROR", MYSQLI_REPORT_ERROR, CONST_CS | CONST_PERSISTENT);
                    808:        REGISTER_LONG_CONSTANT("MYSQLI_REPORT_STRICT", MYSQLI_REPORT_STRICT, CONST_CS | CONST_PERSISTENT);
                    809:        REGISTER_LONG_CONSTANT("MYSQLI_REPORT_ALL", MYSQLI_REPORT_ALL, CONST_CS | CONST_PERSISTENT);
                    810:        REGISTER_LONG_CONSTANT("MYSQLI_REPORT_OFF", 0, CONST_CS | CONST_PERSISTENT);
                    811: 
                    812:        /* We use non-nested macros with expansion, as VC has problems */
                    813: #ifdef MYSQLI_USE_MYSQLND
                    814:        REGISTER_LONG_CONSTANT("MYSQLI_DEBUG_TRACE_ENABLED", MYSQLND_DBG_ENABLED, CONST_CS | CONST_PERSISTENT);
                    815: #else
1.1.1.2   misho     816: #ifdef DBUG_ON
1.1       misho     817:        REGISTER_LONG_CONSTANT("MYSQLI_DEBUG_TRACE_ENABLED", 1, CONST_CS | CONST_PERSISTENT);
1.1.1.2   misho     818: #else
                    819:        REGISTER_LONG_CONSTANT("MYSQLI_DEBUG_TRACE_ENABLED", 0, CONST_CS | CONST_PERSISTENT);
1.1       misho     820: #endif
                    821: #endif
                    822: 
                    823:        REGISTER_LONG_CONSTANT("MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED", SERVER_QUERY_NO_GOOD_INDEX_USED, CONST_CS | CONST_PERSISTENT);
                    824:        REGISTER_LONG_CONSTANT("MYSQLI_SERVER_QUERY_NO_INDEX_USED", SERVER_QUERY_NO_INDEX_USED, CONST_CS | CONST_PERSISTENT);
                    825: #ifdef SERVER_QUERY_WAS_SLOW
                    826:        REGISTER_LONG_CONSTANT("MYSQLI_SERVER_QUERY_WAS_SLOW", SERVER_QUERY_WAS_SLOW, CONST_CS | CONST_PERSISTENT);
                    827: #endif
                    828: #ifdef SERVER_PS_OUT_PARAMS
                    829:        REGISTER_LONG_CONSTANT("MYSQLI_SERVER_PS_OUT_PARAMS", SERVER_PS_OUT_PARAMS, CONST_CS | CONST_PERSISTENT);
                    830: #endif
                    831: 
                    832:        REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_GRANT",      REFRESH_GRANT, CONST_CS | CONST_PERSISTENT);
                    833:        REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_LOG",        REFRESH_LOG, CONST_CS | CONST_PERSISTENT);
                    834:        REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_TABLES",     REFRESH_TABLES, CONST_CS | CONST_PERSISTENT);
                    835:        REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_HOSTS",      REFRESH_HOSTS, CONST_CS | CONST_PERSISTENT);
                    836:        REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_STATUS",     REFRESH_STATUS, CONST_CS | CONST_PERSISTENT);
                    837:        REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_THREADS",    REFRESH_THREADS, CONST_CS | CONST_PERSISTENT);
                    838:        REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_SLAVE",      REFRESH_SLAVE, CONST_CS | CONST_PERSISTENT);
                    839:        REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_MASTER",     REFRESH_MASTER, CONST_CS | CONST_PERSISTENT);
                    840: #ifdef REFRESH_BACKUP_LOG
                    841:        REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_BACKUP_LOG", REFRESH_BACKUP_LOG, CONST_CS | CONST_PERSISTENT);
                    842: #endif
                    843: 
1.1.1.3   misho     844: #if MYSQL_VERSION_ID >= 50611 || defined(MYSQLI_USE_MYSQLND)
                    845:        REGISTER_LONG_CONSTANT("MYSQLI_OPT_CAN_HANDLE_EXPIRED_PASSWORDS", MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, CONST_CS | CONST_PERSISTENT);
                    846: #endif
1.1.1.2   misho     847: 
                    848: #ifdef MYSQLI_USE_MYSQLND
                    849:        mysqlnd_reverse_api_register_api(&mysqli_reverse_api TSRMLS_CC);
                    850: #endif
                    851: 
1.1       misho     852:        return SUCCESS;
                    853: }
                    854: /* }}} */
                    855: 
                    856: /* {{{ PHP_MSHUTDOWN_FUNCTION
                    857:  */
                    858: PHP_MSHUTDOWN_FUNCTION(mysqli)
                    859: {
                    860: #ifndef MYSQLI_USE_MYSQLND
                    861: #if MYSQL_VERSION_ID >= 40000
                    862: #ifdef PHP_WIN32
                    863:        unsigned long client_ver = mysql_get_client_version();
                    864:        /*
                    865:          Can't call mysql_server_end() multiple times prior to 5.0.46 on Windows.
                    866:          PHP bug#41350 MySQL bug#25621
                    867:        */
                    868:        if ((client_ver >= 50046 && client_ver < 50100) || client_ver > 50122) {
                    869:                mysql_server_end();
                    870:        }
                    871: #else
                    872:        mysql_server_end();
                    873: #endif
                    874: #endif
                    875: #endif
                    876: 
                    877:        zend_hash_destroy(&mysqli_driver_properties);
                    878:        zend_hash_destroy(&mysqli_result_properties);
                    879:        zend_hash_destroy(&mysqli_stmt_properties);
                    880:        zend_hash_destroy(&mysqli_warning_properties);
                    881:        zend_hash_destroy(&mysqli_link_properties);
                    882:        zend_hash_destroy(&classes);
                    883: 
                    884:        UNREGISTER_INI_ENTRIES();
                    885:        return SUCCESS;
                    886: }
                    887: /* }}} */
                    888: 
                    889: /* {{{ PHP_RINIT_FUNCTION
                    890:  */
                    891: PHP_RINIT_FUNCTION(mysqli)
                    892: {
                    893: #if !defined(MYSQLI_USE_MYSQLND) && defined(ZTS) && MYSQL_VERSION_ID >= 40000
                    894:        if (mysql_thread_init()) {
                    895:                return FAILURE;
                    896:        }
                    897: #endif
                    898:        MyG(error_msg) = NULL;
                    899:        MyG(error_no) = 0;
                    900:        MyG(report_mode) = 0;
                    901: 
                    902:        return SUCCESS;
                    903: }
                    904: /* }}} */
                    905: 
                    906: #if defined(A0) && defined(MYSQLI_USE_MYSQLND)
                    907: static void php_mysqli_persistent_helper_for_every(void *p)
                    908: {
                    909:        TSRMLS_FETCH();
                    910:        mysqlnd_end_psession((MYSQLND *) p);
                    911: } /* }}} */
                    912: 
                    913: 
                    914: static int php_mysqli_persistent_helper_once(zend_rsrc_list_entry *le TSRMLS_DC)
                    915: {
                    916:        if (le->type == php_le_pmysqli()) {
                    917:                mysqli_plist_entry *plist = (mysqli_plist_entry *) le->ptr;
                    918:                zend_ptr_stack_apply(&plist->free_links, php_mysqli_persistent_helper_for_every);
                    919:        }
                    920:        return ZEND_HASH_APPLY_KEEP;
                    921: } /* }}} */
                    922: #endif
                    923: 
                    924: 
                    925: /* {{{ PHP_RSHUTDOWN_FUNCTION
                    926:  */
                    927: PHP_RSHUTDOWN_FUNCTION(mysqli)
                    928: {
                    929:        /* check persistent connections, move used to free */
                    930: 
                    931: #if !defined(MYSQLI_USE_MYSQLND) && defined(ZTS) && MYSQL_VERSION_ID >= 40000
                    932:        mysql_thread_end();
                    933: #endif
                    934:        if (MyG(error_msg)) {
                    935:                efree(MyG(error_msg));
                    936:        }
                    937: #if defined(A0) && defined(MYSQLI_USE_MYSQLND)
                    938:        /* psession is being called when the connection is freed - explicitly or implicitly */
                    939:        zend_hash_apply(&EG(persistent_list), (apply_func_t) php_mysqli_persistent_helper_once TSRMLS_CC);
                    940: #endif
                    941:        return SUCCESS;
                    942: }
                    943: /* }}} */
                    944: 
                    945: 
                    946: /* {{{ PHP_MINFO_FUNCTION
                    947:  */
                    948: PHP_MINFO_FUNCTION(mysqli)
                    949: {
                    950:        char buf[32];
                    951: 
                    952:        php_info_print_table_start();
                    953:        php_info_print_table_header(2, "MysqlI Support", "enabled");
                    954:        php_info_print_table_row(2, "Client API library version", mysql_get_client_info());
                    955:        snprintf(buf, sizeof(buf), "%ld", MyG(num_active_persistent));
                    956:        php_info_print_table_row(2, "Active Persistent Links", buf);
                    957:        snprintf(buf, sizeof(buf), "%ld", MyG(num_inactive_persistent));
                    958:        php_info_print_table_row(2, "Inactive Persistent Links", buf);
                    959:        snprintf(buf, sizeof(buf), "%ld", MyG(num_links));
                    960:        php_info_print_table_row(2, "Active Links", buf);
                    961: #if !defined(MYSQLI_USE_MYSQLND)
                    962:        php_info_print_table_row(2, "Client API header version", MYSQL_SERVER_VERSION);
                    963:        php_info_print_table_row(2, "MYSQLI_SOCKET", MYSQL_UNIX_ADDR);
                    964: #endif
                    965:        php_info_print_table_end();
                    966: 
                    967:        DISPLAY_INI_ENTRIES();
                    968: }
                    969: /* }}} */
                    970: 
                    971: 
                    972: /* Dependancies */
                    973: static const  zend_module_dep mysqli_deps[] = {
                    974: #if defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1))
                    975:        ZEND_MOD_REQUIRED("spl")
                    976: #endif
                    977: #if defined(MYSQLI_USE_MYSQLND)
                    978:        ZEND_MOD_REQUIRED("mysqlnd")
                    979: #endif
                    980:        ZEND_MOD_END
                    981: };
                    982: 
                    983: /* {{{ mysqli_module_entry
                    984:  */
                    985: zend_module_entry mysqli_module_entry = {
                    986: #if ZEND_MODULE_API_NO >= 20050922
                    987:        STANDARD_MODULE_HEADER_EX, NULL,
                    988:        mysqli_deps,
                    989: #elif ZEND_MODULE_API_NO >= 20010901
                    990:        STANDARD_MODULE_HEADER,
                    991: #endif
                    992:        "mysqli",
                    993:        mysqli_functions,
                    994:        PHP_MINIT(mysqli),
                    995:        PHP_MSHUTDOWN(mysqli),
                    996:        PHP_RINIT(mysqli),
                    997:        PHP_RSHUTDOWN(mysqli),
                    998:        PHP_MINFO(mysqli),
                    999:        "0.1", /* Replace with version number for your extension */
                   1000:        PHP_MODULE_GLOBALS(mysqli),
                   1001:        PHP_GINIT(mysqli),
                   1002:        NULL,
                   1003:        NULL,
                   1004:        STANDARD_MODULE_PROPERTIES_EX
                   1005: };
                   1006: /* }}} */
                   1007: 
                   1008: #ifdef COMPILE_DL_MYSQLI
                   1009: ZEND_GET_MODULE(mysqli)
                   1010: #endif
                   1011: 
                   1012: 
                   1013: /* {{{ mixed mysqli_stmt_construct()
                   1014: constructor for statement object.
                   1015: Parameters:
                   1016:   object -> mysqli_stmt_init
                   1017:   object, query -> mysqli_prepare
                   1018: */
                   1019: PHP_FUNCTION(mysqli_stmt_construct)
                   1020: {
                   1021:        MY_MYSQL                        *mysql;
                   1022:        zval                            *mysql_link;
                   1023:        MY_STMT                         *stmt;
                   1024:        MYSQLI_RESOURCE         *mysqli_resource;
                   1025:        char                            *statement;
                   1026:        int                                     statement_len;
                   1027: 
                   1028:        switch (ZEND_NUM_ARGS())
                   1029:        {
                   1030:                case 1:  /* mysql_stmt_init */
                   1031:                        if (zend_parse_parameters(1 TSRMLS_CC, "O", &mysql_link, mysqli_link_class_entry)==FAILURE) {
                   1032:                                return;
                   1033:                        }
                   1034:                        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
                   1035: 
                   1036:                        stmt = (MY_STMT *)ecalloc(1,sizeof(MY_STMT));
                   1037: 
                   1038:                        stmt->stmt = mysql_stmt_init(mysql->mysql);
                   1039:                break;
                   1040:                case 2:
                   1041:                        if (zend_parse_parameters(2 TSRMLS_CC, "Os", &mysql_link, mysqli_link_class_entry, &statement, &statement_len)==FAILURE) {
                   1042:                                return;
                   1043:                        }
                   1044:                        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
                   1045: 
                   1046:                        stmt = (MY_STMT *)ecalloc(1,sizeof(MY_STMT));
                   1047: 
                   1048:                        if ((stmt->stmt = mysql_stmt_init(mysql->mysql))) {
                   1049:                                mysql_stmt_prepare(stmt->stmt, (char *)statement, statement_len);
                   1050:                        }
                   1051:                break;
                   1052:                default:
                   1053:                        WRONG_PARAM_COUNT;
                   1054:                break;
                   1055:        }
                   1056: 
                   1057:        if (!stmt->stmt) {
                   1058:                efree(stmt);
                   1059:                RETURN_FALSE;
                   1060:        }
1.1.1.5 ! misho    1061: #ifndef MYSQLI_USE_MYSQLND
        !          1062:        stmt->link_handle = Z_OBJ_HANDLE(*mysql_link);
        !          1063:        zend_objects_store_add_ref_by_handle(stmt->link_handle TSRMLS_CC);
        !          1064: #endif
1.1       misho    1065: 
                   1066:        mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
                   1067:        mysqli_resource->ptr = (void *)stmt;
                   1068:        mysqli_resource->status = (ZEND_NUM_ARGS() == 1) ? MYSQLI_STATUS_INITIALIZED : MYSQLI_STATUS_VALID;
                   1069: 
                   1070:        ((mysqli_object *) zend_object_store_get_object(getThis() TSRMLS_CC))->ptr = mysqli_resource;
                   1071: }
                   1072: /* }}} */
                   1073: 
                   1074: /* {{{ mixed mysqli_result_construct()
                   1075: constructor for result object.
                   1076: Parameters:
                   1077:   object [, mode] -> mysqli_store/use_result
                   1078: */
                   1079: PHP_FUNCTION(mysqli_result_construct)
                   1080: {
                   1081:        MY_MYSQL                        *mysql;
                   1082:        MYSQL_RES                       *result = NULL;
                   1083:        zval                            *mysql_link;
                   1084:        MYSQLI_RESOURCE         *mysqli_resource;
                   1085:        long                            resmode = MYSQLI_STORE_RESULT;
                   1086: 
                   1087:        switch (ZEND_NUM_ARGS()) {
                   1088:                case 1:
                   1089:                        if (zend_parse_parameters(1 TSRMLS_CC, "O", &mysql_link, mysqli_link_class_entry)==FAILURE) {
                   1090:                                return;
                   1091:                        }
                   1092:                        break;
                   1093:                case 2:
                   1094:                        if (zend_parse_parameters(2 TSRMLS_CC, "Ol", &mysql_link, mysqli_link_class_entry, &resmode)==FAILURE) {
                   1095:                                return;
                   1096:                        }
                   1097:                        break;
                   1098:                default:
                   1099:                        WRONG_PARAM_COUNT;
                   1100:        }
                   1101: 
                   1102:        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
                   1103: 
                   1104:        switch (resmode) {
                   1105:                case MYSQLI_STORE_RESULT:
                   1106:                        result = mysql_store_result(mysql->mysql);
                   1107:                        break;
                   1108:                case MYSQLI_USE_RESULT:
                   1109:                        result = mysql_use_result(mysql->mysql);
                   1110:                        break;
                   1111:                default:
                   1112:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid value for resultmode");
                   1113:        }
                   1114: 
                   1115:        if (!result) {
                   1116:                RETURN_FALSE;
                   1117:        }
                   1118: 
                   1119:        mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
                   1120:        mysqli_resource->ptr = (void *)result;
                   1121:        mysqli_resource->status = MYSQLI_STATUS_VALID;
                   1122: 
                   1123:        ((mysqli_object *) zend_object_store_get_object(getThis() TSRMLS_CC))->ptr = mysqli_resource;
                   1124: 
                   1125: }
                   1126: /* }}} */
                   1127: 
1.1.1.2   misho    1128: 
                   1129: /* {{{ php_mysqli_fetch_into_hash_aux
1.1       misho    1130:  */
1.1.1.2   misho    1131: void php_mysqli_fetch_into_hash_aux(zval *return_value, MYSQL_RES * result, long fetchtype TSRMLS_DC)
1.1       misho    1132: {
                   1133: #if !defined(MYSQLI_USE_MYSQLND)
1.1.1.2   misho    1134:        MYSQL_ROW row;
1.1       misho    1135:        unsigned int    i;
                   1136:        MYSQL_FIELD             *fields;
                   1137:        unsigned long   *field_len;
1.1.1.2   misho    1138:        
1.1       misho    1139:        if (!(row = mysql_fetch_row(result))) {
                   1140:                RETURN_NULL();
                   1141:        }
                   1142: 
                   1143:        if (fetchtype & MYSQLI_ASSOC) {
                   1144:                fields = mysql_fetch_fields(result);
                   1145:        }
                   1146: 
                   1147:        array_init(return_value);
                   1148:        field_len = mysql_fetch_lengths(result);
                   1149: 
                   1150:        for (i = 0; i < mysql_num_fields(result); i++) {
                   1151:                if (row[i]) {
                   1152:                        zval *res;
                   1153: 
                   1154:                        MAKE_STD_ZVAL(res);
                   1155: 
                   1156: #if MYSQL_VERSION_ID > 50002
                   1157:                        if (mysql_fetch_field_direct(result, i)->type == MYSQL_TYPE_BIT) {
                   1158:                                my_ulonglong llval;
                   1159:                                char tmp[22];
                   1160:                                switch (field_len[i]) {
                   1161:                                        case 8:llval = (my_ulonglong)  bit_uint8korr(row[i]);break;
                   1162:                                        case 7:llval = (my_ulonglong)  bit_uint7korr(row[i]);break;
                   1163:                                        case 6:llval = (my_ulonglong)  bit_uint6korr(row[i]);break;
                   1164:                                        case 5:llval = (my_ulonglong)  bit_uint5korr(row[i]);break;
                   1165:                                        case 4:llval = (my_ulonglong)  bit_uint4korr(row[i]);break;
                   1166:                                        case 3:llval = (my_ulonglong)  bit_uint3korr(row[i]);break;
                   1167:                                        case 2:llval = (my_ulonglong)  bit_uint2korr(row[i]);break;
                   1168:                                        case 1:llval = (my_ulonglong)  uint1korr(row[i]);break;
                   1169:                                }
                   1170:                                /* even though lval is declared as unsigned, the value
                   1171:                                 * may be negative. Therefor we cannot use MYSQLI_LLU_SPEC and must
                   1172:                                 * use MYSQLI_LL_SPEC.
                   1173:                                 */
                   1174:                                snprintf(tmp, sizeof(tmp), (mysql_fetch_field_direct(result, i)->flags & UNSIGNED_FLAG)? MYSQLI_LLU_SPEC : MYSQLI_LL_SPEC, llval);
                   1175:                                ZVAL_STRING(res, tmp, 1);
                   1176:                        } else
                   1177: #endif
                   1178:                        {
                   1179: 
1.1.1.2   misho    1180: #if PHP_API_VERSION < 20100412
1.1       misho    1181:                                /* check if we need magic quotes */
                   1182:                                if (PG(magic_quotes_runtime)) {
                   1183:                                        Z_TYPE_P(res) = IS_STRING;
                   1184:                                        Z_STRVAL_P(res) = php_addslashes(row[i], field_len[i], &Z_STRLEN_P(res), 0 TSRMLS_CC);
                   1185:                                } else {
1.1.1.2   misho    1186: #endif
1.1       misho    1187:                                        ZVAL_STRINGL(res, row[i], field_len[i], 1);
1.1.1.2   misho    1188: #if PHP_API_VERSION < 20100412
1.1       misho    1189:                                }
1.1.1.2   misho    1190: #endif
1.1       misho    1191:                        }
                   1192: 
                   1193:                        if (fetchtype & MYSQLI_NUM) {
                   1194:                                add_index_zval(return_value, i, res);
                   1195:                        }
                   1196:                        if (fetchtype & MYSQLI_ASSOC) {
                   1197:                                if (fetchtype & MYSQLI_NUM) {
                   1198:                                        Z_ADDREF_P(res);
                   1199:                                }
                   1200:                                add_assoc_zval(return_value, fields[i].name, res);
                   1201:                        }
                   1202:                } else {
                   1203:                        if (fetchtype & MYSQLI_NUM) {
                   1204:                                add_index_null(return_value, i);
                   1205:                        }
                   1206:                        if (fetchtype & MYSQLI_ASSOC) {
                   1207:                                add_assoc_null(return_value, fields[i].name);
                   1208:                        }
                   1209:                }
                   1210:        }
                   1211: #else
1.1.1.2   misho    1212:        mysqlnd_fetch_into(result, ((fetchtype & MYSQLI_NUM)? MYSQLND_FETCH_NUM:0) | ((fetchtype & MYSQLI_ASSOC)? MYSQLND_FETCH_ASSOC:0), return_value, MYSQLND_MYSQLI);
                   1213: #endif
                   1214: }
                   1215: /* }}} */
                   1216: 
                   1217: 
                   1218: /* {{{ php_mysqli_fetch_into_hash
                   1219:  */
                   1220: void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags, int into_object)
                   1221: {
                   1222:        MYSQL_RES               *result;
                   1223:        zval                    *mysql_result;
                   1224:        long                    fetchtype;
                   1225:        zval                    *ctor_params = NULL;
                   1226:        zend_class_entry *ce = NULL;
                   1227: 
                   1228:        if (into_object) {
                   1229:                char *class_name;
                   1230:                int class_name_len;
                   1231: 
                   1232:                if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|sz", &mysql_result, mysqli_result_class_entry, &class_name, &class_name_len, &ctor_params) == FAILURE) {
                   1233:                        return;
                   1234:                }
                   1235:                if (ZEND_NUM_ARGS() < (getThis() ? 1 : 2)) {
                   1236:                        ce = zend_standard_class_def;
1.1       misho    1237:                } else {
1.1.1.2   misho    1238:                        ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
1.1       misho    1239:                }
1.1.1.2   misho    1240:                if (!ce) {
                   1241:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not find class '%s'", class_name);
                   1242:                        return;
                   1243:                }
                   1244:                fetchtype = MYSQLI_ASSOC;
1.1       misho    1245:        } else {
1.1.1.2   misho    1246:                if (override_flags) {
                   1247:                        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
                   1248:                                return;
                   1249:                        }
                   1250:                        fetchtype = override_flags;
                   1251:                } else {
                   1252:                        fetchtype = MYSQLI_BOTH;
                   1253:                        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &mysql_result, mysqli_result_class_entry, &fetchtype) == FAILURE) {
                   1254:                                return;
                   1255:                        }
                   1256:                }
1.1       misho    1257:        }
1.1.1.2   misho    1258:        MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
1.1       misho    1259: 
1.1.1.2   misho    1260:        if (fetchtype < MYSQLI_ASSOC || fetchtype > MYSQLI_BOTH) {
                   1261:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "The result type should be either MYSQLI_NUM, MYSQLI_ASSOC or MYSQLI_BOTH");
                   1262:                RETURN_FALSE;
                   1263:        }
                   1264: 
                   1265:        php_mysqli_fetch_into_hash_aux(return_value, result, fetchtype TSRMLS_CC);
1.1       misho    1266: 
1.1.1.3   misho    1267:        if (into_object && Z_TYPE_P(return_value) == IS_ARRAY) {
1.1       misho    1268:                zval dataset = *return_value;
                   1269:                zend_fcall_info fci;
                   1270:                zend_fcall_info_cache fcc;
                   1271:                zval *retval_ptr;
                   1272: 
                   1273:                object_and_properties_init(return_value, ce, NULL);
                   1274:                zend_merge_properties(return_value, Z_ARRVAL(dataset), 1 TSRMLS_CC);
                   1275: 
                   1276:                if (ce->constructor) {
                   1277:                        fci.size = sizeof(fci);
                   1278:                        fci.function_table = &ce->function_table;
                   1279:                        fci.function_name = NULL;
                   1280:                        fci.symbol_table = NULL;
                   1281:                        fci.object_ptr = return_value;
                   1282:                        fci.retval_ptr_ptr = &retval_ptr;
                   1283:                        if (ctor_params && Z_TYPE_P(ctor_params) != IS_NULL) {
                   1284:                                if (Z_TYPE_P(ctor_params) == IS_ARRAY) {
                   1285:                                        HashTable *params_ht = Z_ARRVAL_P(ctor_params);
                   1286:                                        Bucket *p;
                   1287: 
                   1288:                                        fci.param_count = 0;
                   1289:                                        fci.params = safe_emalloc(sizeof(zval*), params_ht->nNumOfElements, 0);
                   1290:                                        p = params_ht->pListHead;
                   1291:                                        while (p != NULL) {
                   1292:                                                fci.params[fci.param_count++] = (zval**)p->pData;
                   1293:                                                p = p->pListNext;
                   1294:                                        }
                   1295:                                } else {
                   1296:                                        /* Two problems why we throw exceptions here: PHP is typeless
                   1297:                                         * and hence passing one argument that's not an array could be
                   1298:                                         * by mistake and the other way round is possible, too. The
                   1299:                                         * single value is an array. Also we'd have to make that one
                   1300:                                         * argument passed by reference.
                   1301:                                         */
                   1302:                                        zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Parameter ctor_params must be an array", 0 TSRMLS_CC);
                   1303:                                        return;
                   1304:                                }
                   1305:                        } else {
                   1306:                                fci.param_count = 0;
                   1307:                                fci.params = NULL;
                   1308:                        }
                   1309:                        fci.no_separation = 1;
                   1310: 
                   1311:                        fcc.initialized = 1;
                   1312:                        fcc.function_handler = ce->constructor;
                   1313:                        fcc.calling_scope = EG(scope);
                   1314:                        fcc.called_scope = Z_OBJCE_P(return_value);
                   1315:                        fcc.object_ptr = return_value;
                   1316: 
                   1317:                        if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
                   1318:                                zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Could not execute %s::%s()", ce->name, ce->constructor->common.function_name);
                   1319:                        } else {
                   1320:                                if (retval_ptr) {
                   1321:                                        zval_ptr_dtor(&retval_ptr);
                   1322:                                }
                   1323:                        }
                   1324:                        if (fci.params) {
                   1325:                                efree(fci.params);
                   1326:                        }
                   1327:                } else if (ctor_params) {
                   1328:                        zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Class %s does not have a constructor hence you cannot use ctor_params", ce->name);
                   1329:                }
                   1330:        }
                   1331: }
                   1332: /* }}} */
                   1333: 
                   1334: 
                   1335: #if !defined(MYSQLI_USE_MYSQLND)
                   1336: 
                   1337: #define ALLOC_CALLBACK_ARGS(a, b, c)\
                   1338: if (c) {\
                   1339:        a = (zval ***)safe_emalloc(c, sizeof(zval **), 0);\
                   1340:        for (i = b; i < c; i++) {\
                   1341:                a[i] = emalloc(sizeof(zval *));\
                   1342:                MAKE_STD_ZVAL(*a[i]);\
                   1343:        }\
                   1344: }
                   1345: 
                   1346: #define FREE_CALLBACK_ARGS(a, b, c)\
                   1347: if (a) {\
                   1348:        for (i=b; i < c; i++) {\
                   1349:                zval_ptr_dtor(a[i]);\
                   1350:                efree(a[i]);\
                   1351:        }\
                   1352:        efree(a);\
                   1353: }
                   1354: 
                   1355: #define LOCAL_INFILE_ERROR_MSG(source,dest)\
                   1356:        memset(source, 0, LOCAL_INFILE_ERROR_LEN);\
                   1357:        memcpy(source, dest, MIN(strlen(dest), LOCAL_INFILE_ERROR_LEN-1));\
                   1358:        php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", dest);
                   1359: 
                   1360: 
                   1361: /* {{{ php_local_infile_init
                   1362:  */
                   1363: static int php_local_infile_init(void **ptr, const char *filename, void *userdata)
                   1364: {
                   1365:        mysqli_local_infile                     *data;
                   1366:        MY_MYSQL                                        *mysql;
                   1367:        php_stream_context                      *context = NULL;
                   1368: 
                   1369:        TSRMLS_FETCH();
                   1370: 
                   1371:        /* save pointer to MY_MYSQL structure (userdata) */
                   1372:        if (!(*ptr= data= ((mysqli_local_infile *)calloc(1, sizeof(mysqli_local_infile))))) {
                   1373:                return 1;
                   1374:        }
                   1375: 
                   1376:        if (!(mysql = (MY_MYSQL *)userdata)) {
                   1377:                LOCAL_INFILE_ERROR_MSG(data->error_msg, ER(CR_UNKNOWN_ERROR));
                   1378:                return 1;
                   1379:        }
                   1380: 
                   1381:        /* check open_basedir */
                   1382:        if (PG(open_basedir)) {
                   1383:                if (php_check_open_basedir_ex(filename, 0 TSRMLS_CC) == -1) {
                   1384:                        LOCAL_INFILE_ERROR_MSG(data->error_msg, "open_basedir restriction in effect. Unable to open file");
                   1385:                        return 1;
                   1386:                }
                   1387:        }
                   1388: 
                   1389:        mysql->li_stream = php_stream_open_wrapper_ex((char *)filename, "r", 0, NULL, context);
                   1390: 
                   1391:        if (mysql->li_stream == NULL) {
                   1392:                snprintf((char *)data->error_msg, sizeof(data->error_msg), "Can't find file '%-.64s'.", filename);
                   1393:                return 1;
                   1394:        }
                   1395: 
                   1396:        data->userdata = mysql;
                   1397: 
                   1398:        return 0;
                   1399: }
                   1400: /* }}} */
                   1401: 
                   1402: /* {{{ int php_local_infile_read */
                   1403: static int php_local_infile_read(void *ptr, char *buf, uint buf_len)
                   1404: {
                   1405:        mysqli_local_infile                     *data;
                   1406:        MY_MYSQL                                        *mysql;
                   1407:        zval                                            ***callback_args;
                   1408:        zval                                            *retval;
                   1409:        zval                                            *fp;
                   1410:        int                                                     argc = 4;
                   1411:        int                                                     i;
                   1412:        long                                            rc;
                   1413: 
                   1414:        TSRMLS_FETCH();
                   1415: 
                   1416:        data= (mysqli_local_infile *)ptr;
                   1417:        mysql = data->userdata;
                   1418: 
                   1419:        /* default processing */
                   1420:        if (!mysql->li_read) {
                   1421:                int count = (int)php_stream_read(mysql->li_stream, buf, buf_len);
                   1422: 
                   1423:                if (count < 0) {
                   1424:                        LOCAL_INFILE_ERROR_MSG(data->error_msg, ER(2));
                   1425:                }
                   1426: 
                   1427:                return count;
                   1428:        }
                   1429: 
                   1430:        ALLOC_CALLBACK_ARGS(callback_args, 1, argc);
                   1431: 
                   1432:        /* set parameters: filepointer, buffer, buffer_len, errormsg */
                   1433: 
                   1434:        MAKE_STD_ZVAL(fp);
                   1435:        php_stream_to_zval(mysql->li_stream, fp);
                   1436:        callback_args[0] = &fp;
                   1437:        ZVAL_STRING(*callback_args[1], "", 1);
                   1438:        ZVAL_LONG(*callback_args[2], buf_len);
                   1439:        ZVAL_STRING(*callback_args[3], "", 1);
                   1440: 
                   1441:        if (call_user_function_ex(EG(function_table),
                   1442:                                                NULL,
                   1443:                                                mysql->li_read,
                   1444:                                                &retval,
                   1445:                                                argc,
                   1446:                                                callback_args,
                   1447:                                                0,
                   1448:                                                NULL TSRMLS_CC) == SUCCESS) {
                   1449: 
                   1450:                rc = Z_LVAL_P(retval);
                   1451:                zval_ptr_dtor(&retval);
                   1452: 
                   1453:                if (rc > 0) {
                   1454:                        if (rc >= 0 && rc != Z_STRLEN_P(*callback_args[1])) {
                   1455:                                LOCAL_INFILE_ERROR_MSG(data->error_msg,
                   1456:                                                        "Mismatch between the return value of the callback and the content "
                   1457:                                                        "length of the buffer.");
                   1458:                                rc = -1;
                   1459:                        } else if (rc > buf_len) {
                   1460:                                /* check buffer overflow */
                   1461:                                LOCAL_INFILE_ERROR_MSG(data->error_msg, "Too much data returned");
                   1462:                                rc = -1;
                   1463:                        } else {
                   1464:                                memcpy(buf, Z_STRVAL_P(*callback_args[1]), MIN(rc, Z_STRLEN_P(*callback_args[1])));
                   1465:                        }
                   1466:                } else if (rc < 0) {
                   1467:                        LOCAL_INFILE_ERROR_MSG(data->error_msg, Z_STRVAL_P(*callback_args[3]));
                   1468:                }
                   1469:        } else {
                   1470:                LOCAL_INFILE_ERROR_MSG(data->error_msg, "Can't execute load data local init callback function");
                   1471:                rc = -1;
                   1472:        }
                   1473:        /*
                   1474:          If the (ab)user has closed the file handle we should
                   1475:          not try to use it anymore or even close it
                   1476:        */
                   1477:        if (!zend_rsrc_list_get_rsrc_type(Z_LVAL_P(fp) TSRMLS_CC)) {
                   1478:                LOCAL_INFILE_ERROR_MSG(data->error_msg, "File handle closed");
                   1479:                rc = -1;
                   1480:                /* Thus the end handler won't try to free already freed memory */
                   1481:                mysql->li_stream = NULL;
                   1482:        }
                   1483: 
                   1484:        FREE_CALLBACK_ARGS(callback_args, 1, argc);
                   1485:        efree(fp);
                   1486:        return rc;
                   1487: }
                   1488: /* }}} */
                   1489: 
                   1490: /* {{{ php_local_infile_error
                   1491:  */
                   1492: static int php_local_infile_error(void *ptr, char *error_msg, uint error_msg_len)
                   1493: {
                   1494:        mysqli_local_infile *data = (mysqli_local_infile *) ptr;
                   1495: 
                   1496:        if (data) {
                   1497:                strlcpy(error_msg, data->error_msg, error_msg_len);
                   1498:                return 2000;
                   1499:        }
                   1500:        strlcpy(error_msg, ER(CR_OUT_OF_MEMORY), error_msg_len);
                   1501:        return CR_OUT_OF_MEMORY;
                   1502: }
                   1503: /* }}} */
                   1504: 
                   1505: /* {{{ php_local_infile_end
                   1506:  */
                   1507: static void php_local_infile_end(void *ptr)
                   1508: {
                   1509:        mysqli_local_infile             *data;
                   1510:        MY_MYSQL                                *mysql;
                   1511: 
                   1512:        TSRMLS_FETCH();
                   1513: 
                   1514:        data= (mysqli_local_infile *)ptr;
                   1515: 
                   1516:        if (!data || !(mysql = data->userdata)) {
                   1517:                if (data) {
                   1518:                        free(data);
                   1519:                }
                   1520:                return;
                   1521:        }
                   1522: 
                   1523:        if (mysql->li_stream) {
                   1524:                php_stream_close(mysql->li_stream);
                   1525:        }
                   1526:        free(data);
                   1527:        return;
                   1528: }
                   1529: /* }}} */
                   1530: 
                   1531: 
                   1532: /* {{{ void php_set_local_infile_handler_default
                   1533: */
                   1534: void php_set_local_infile_handler_default(MY_MYSQL *mysql) {
                   1535:        /* register internal callback functions */
                   1536:        mysql_set_local_infile_handler(mysql->mysql, &php_local_infile_init, &php_local_infile_read,
                   1537:                                &php_local_infile_end, &php_local_infile_error, (void *)mysql);
                   1538:        if (mysql->li_read) {
                   1539:                zval_ptr_dtor(&mysql->li_read);
                   1540:                mysql->li_read = NULL;
                   1541:        }
                   1542: }
                   1543: /* }}} */
                   1544: #endif
                   1545: 
                   1546: /*
                   1547:  * Local variables:
                   1548:  * tab-width: 4
                   1549:  * c-basic-offset: 4
                   1550:  * End:
                   1551:  * vim600: noet sw=4 ts=4 fdm=marker
                   1552:  * vim<600: noet sw=4 ts=4
                   1553:  */

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