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