Back to index

php5  5.3.10
mysqli.c
Go to the documentation of this file.
00001 /*
00002   +----------------------------------------------------------------------+
00003   | PHP Version 5                                                        |
00004   +----------------------------------------------------------------------+
00005   | Copyright (c) 1997-2012 The PHP Group                                |
00006   +----------------------------------------------------------------------+
00007   | This source file is subject to version 3.01 of the PHP license,      |
00008   | that is bundled with this package in the file LICENSE, and is        |
00009   | available through the world-wide-web at the following url:           |
00010   | http://www.php.net/license/3_01.txt                                  |
00011   | If you did not receive a copy of the PHP license and are unable to   |
00012   | obtain it through the world-wide-web, please send a note to          |
00013   | license@php.net so we can mail you a copy immediately.               |
00014   +----------------------------------------------------------------------+
00015   | Authors: Georg Richter <georg@php.net>                               |
00016   |          Andrey Hristov <andrey@php.net>                             |
00017   |          Ulf Wendel <uw@php.net>                                     |
00018   +----------------------------------------------------------------------+
00019 
00020   $Id: mysqli.c 321634 2012-01-01 13:15:04Z felipe $
00021 */
00022 
00023 #ifdef HAVE_CONFIG_H
00024 #include "config.h"
00025 #endif
00026 
00027 #include <signal.h>
00028 
00029 #include "php.h"
00030 #include "php_ini.h"
00031 #include "ext/standard/info.h"
00032 #include "ext/standard/php_string.h"
00033 #include "php_mysqli_structs.h"
00034 #include "mysqli_priv.h"
00035 #include "zend_exceptions.h"
00036 
00037 ZEND_DECLARE_MODULE_GLOBALS(mysqli)
00038 static PHP_GINIT_FUNCTION(mysqli);
00039 
00040 #define MYSQLI_ADD_PROPERTIES(a,b) \
00041 { \
00042        int i = 0; \
00043        while (b[i].pname != NULL) { \
00044               mysqli_add_property((a), (b)[i].pname, (b)[i].pname_length, \
00045                                                  (mysqli_read_t)(b)[i].r_func, (mysqli_write_t)(b)[i].w_func TSRMLS_CC); \
00046               i++; \
00047        }\
00048 }
00049 
00050 #define MYSQLI_ADD_PROPERTIES_INFO(a,b) \
00051 { \
00052        int i = 0; \
00053        while (b[i].name != NULL) { \
00054               zend_declare_property_null((a), (b)[i].name, (b)[i].name_length, ZEND_ACC_PUBLIC TSRMLS_CC); \
00055               i++; \
00056        }\
00057 }
00058 
00059 
00060 
00061 static zend_object_handlers mysqli_object_handlers;
00062 static HashTable classes;
00063 static HashTable mysqli_driver_properties;
00064 static HashTable mysqli_link_properties;
00065 static HashTable mysqli_result_properties;
00066 static HashTable mysqli_stmt_properties;
00067 static HashTable mysqli_warning_properties;
00068 
00069 zend_class_entry *mysqli_link_class_entry;
00070 zend_class_entry *mysqli_stmt_class_entry;
00071 zend_class_entry *mysqli_result_class_entry;
00072 zend_class_entry *mysqli_driver_class_entry;
00073 zend_class_entry *mysqli_warning_class_entry;
00074 zend_class_entry *mysqli_exception_class_entry;
00075 
00076 
00077 typedef int (*mysqli_read_t)(mysqli_object *obj, zval **retval TSRMLS_DC);
00078 typedef int (*mysqli_write_t)(mysqli_object *obj, zval *newval TSRMLS_DC);
00079 
00080 typedef struct _mysqli_prop_handler {
00081        char *name;
00082        size_t name_len;
00083        mysqli_read_t read_func;
00084        mysqli_write_t write_func;
00085 } mysqli_prop_handler;
00086 
00087 static int le_pmysqli;
00088 
00089 
00090 /* Destructor for mysqli entries in free_links/used_links */
00091 void php_mysqli_dtor_p_elements(void *data)
00092 {
00093        MYSQL *mysql = (MYSQL *) data;
00094        TSRMLS_FETCH();
00095        mysqli_close(mysql, MYSQLI_CLOSE_IMPLICIT);
00096 }
00097 
00098 
00099 ZEND_RSRC_DTOR_FUNC(php_mysqli_dtor)
00100 {
00101        if (rsrc->ptr) {
00102               mysqli_plist_entry *plist = (mysqli_plist_entry *) rsrc->ptr;
00103               zend_ptr_stack_clean(&plist->free_links, php_mysqli_dtor_p_elements, 0);
00104               zend_ptr_stack_destroy(&plist->free_links);
00105               free(plist);
00106        }
00107 }
00108 
00109 
00110 int php_le_pmysqli(void)
00111 {
00112        return le_pmysqli;
00113 }
00114 
00115 #ifndef MYSQLI_USE_MYSQLND
00116 /* {{{ php_free_stmt_bind_buffer */
00117 void php_free_stmt_bind_buffer(BIND_BUFFER bbuf, int type)
00118 {
00119        unsigned int i;
00120 
00121        if (!bbuf.var_cnt) {
00122               return;
00123        }
00124 
00125        for (i=0; i < bbuf.var_cnt; i++) {
00126 
00127               /* free temporary bind buffer */
00128               if (type == FETCH_RESULT && bbuf.buf[i].val) {
00129                      efree(bbuf.buf[i].val);
00130               }
00131 
00132               if (bbuf.vars[i]) {
00133                      zval_ptr_dtor(&bbuf.vars[i]);
00134               }
00135        }
00136 
00137        if (bbuf.vars) {
00138               efree(bbuf.vars);
00139        }
00140 
00141        /*
00142          Don't free bbuf.is_null for FETCH_RESULT since we have allocated
00143          is_null and buf in one block so we free only buf, which is the beginning
00144          of the block. When FETCH_SIMPLE then buf wasn't allocated together with
00145          buf and we have to free it.
00146        */
00147        if (type == FETCH_RESULT) {
00148               efree(bbuf.buf);
00149        } else if (type == FETCH_SIMPLE){
00150               efree(bbuf.is_null);
00151        }
00152 
00153        bbuf.var_cnt = 0;
00154 }
00155 /* }}} */
00156 #endif
00157 
00158 /* {{{ php_clear_stmt_bind */
00159 void php_clear_stmt_bind(MY_STMT *stmt TSRMLS_DC)
00160 {
00161        if (stmt->stmt) {
00162               if (mysqli_stmt_close(stmt->stmt, TRUE)) {
00163                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error occured while closing statement");
00164                      return;
00165               }
00166        }
00167 
00168        /*
00169          mysqlnd keeps track of the binding and has freed its
00170          structures in stmt_close() above
00171        */
00172 #ifndef MYSQLI_USE_MYSQLND
00173        /* Clean param bind */
00174        php_free_stmt_bind_buffer(stmt->param, FETCH_SIMPLE);
00175        /* Clean output bind */
00176        php_free_stmt_bind_buffer(stmt->result, FETCH_RESULT);
00177 #endif
00178 
00179        if (stmt->query) {
00180               efree(stmt->query);
00181        }
00182        efree(stmt);
00183 }
00184 /* }}} */
00185 
00186 /* {{{ php_clear_mysql */
00187 void php_clear_mysql(MY_MYSQL *mysql) {
00188        if (mysql->hash_key) {
00189               efree(mysql->hash_key);
00190               mysql->hash_key = NULL;
00191        }
00192        if (mysql->li_read) {
00193               zval_ptr_dtor(&(mysql->li_read));
00194               mysql->li_read = NULL;
00195        }
00196 }
00197 /* }}} */
00198 
00199 /* {{{ mysqli_objects_free_storage
00200  */
00201 static void mysqli_objects_free_storage(void *object TSRMLS_DC)
00202 {
00203        zend_object *zo = (zend_object *)object;
00204        mysqli_object        *intern = (mysqli_object *)zo;
00205        MYSQLI_RESOURCE      *my_res = (MYSQLI_RESOURCE *)intern->ptr;
00206 
00207        my_efree(my_res);
00208        zend_object_std_dtor(&intern->zo TSRMLS_CC);
00209        efree(intern);
00210 }
00211 /* }}} */
00212 
00213 /* mysqli_link_free_storage partly doubles the work of PHP_FUNCTION(mysqli_close) */
00214 
00215 /* {{{ mysqli_link_free_storage
00216  */
00217 static void mysqli_link_free_storage(void *object TSRMLS_DC)
00218 {
00219        zend_object *zo = (zend_object *)object;
00220        mysqli_object        *intern = (mysqli_object *)zo;
00221        MYSQLI_RESOURCE      *my_res = (MYSQLI_RESOURCE *)intern->ptr;
00222 
00223        if (my_res && my_res->ptr) {
00224               MY_MYSQL *mysql = (MY_MYSQL *)my_res->ptr;
00225               if (mysql->mysql) {
00226                      php_mysqli_close(mysql, MYSQLI_CLOSE_EXPLICIT, my_res->status TSRMLS_CC);
00227               }
00228               php_clear_mysql(mysql);
00229               efree(mysql);
00230               my_res->status = MYSQLI_STATUS_UNKNOWN;
00231        }
00232        mysqli_objects_free_storage(object TSRMLS_CC);
00233 }
00234 /* }}} */
00235 
00236 /* {{{ mysql_driver_free_storage */
00237 static void mysqli_driver_free_storage(void *object TSRMLS_DC)
00238 {
00239        mysqli_objects_free_storage(object TSRMLS_CC);
00240 }
00241 /* }}} */
00242 
00243 /* {{{ mysqli_stmt_free_storage
00244  */
00245 static void mysqli_stmt_free_storage(void *object TSRMLS_DC)
00246 {
00247        zend_object *zo = (zend_object *)object;
00248        mysqli_object        *intern = (mysqli_object *)zo;
00249        MYSQLI_RESOURCE      *my_res = (MYSQLI_RESOURCE *)intern->ptr;
00250 
00251        if (my_res && my_res->ptr) {
00252               MY_STMT *stmt = (MY_STMT *)my_res->ptr;
00253               php_clear_stmt_bind(stmt TSRMLS_CC);
00254        }
00255        mysqli_objects_free_storage(object TSRMLS_CC);
00256 }
00257 /* }}} */
00258 
00259 /* {{{ mysqli_result_free_storage
00260  */
00261 static void mysqli_result_free_storage(void *object TSRMLS_DC)
00262 {
00263        zend_object *zo = (zend_object *)object;
00264        mysqli_object        *intern = (mysqli_object *)zo;
00265        MYSQLI_RESOURCE      *my_res = (MYSQLI_RESOURCE *)intern->ptr;
00266 
00267        if (my_res && my_res->ptr) {
00268               mysql_free_result(my_res->ptr);
00269        }
00270        mysqli_objects_free_storage(object TSRMLS_CC);
00271 }
00272 /* }}} */
00273 
00274 /* {{{ mysqli_warning_free_storage
00275  */
00276 static void mysqli_warning_free_storage(void *object TSRMLS_DC)
00277 {
00278        zend_object *zo = (zend_object *)object;
00279        mysqli_object        *intern = (mysqli_object *)zo;
00280        MYSQLI_RESOURCE      *my_res = (MYSQLI_RESOURCE *)intern->ptr;
00281 
00282        if (my_res && my_res->ptr) {
00283               php_clear_warnings((MYSQLI_WARNING *)my_res->info);
00284               my_res->ptr = NULL;
00285        }
00286        mysqli_objects_free_storage(object TSRMLS_CC);
00287 }
00288 /* }}} */
00289 
00290 /* {{{ mysqli_read_na */
00291 static int mysqli_read_na(mysqli_object *obj, zval **retval TSRMLS_DC)
00292 {
00293        *retval = NULL;
00294        php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot read property");
00295        return FAILURE;
00296 }
00297 /* }}} */
00298 
00299 /* {{{ mysqli_write_na */
00300 static int mysqli_write_na(mysqli_object *obj, zval *newval TSRMLS_DC)
00301 {
00302        php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot write property");
00303        return FAILURE;
00304 }
00305 /* }}} */
00306 
00307 #ifndef Z_ADDREF_P
00308 /* PHP 5.2, old GC */
00309 #define Z_ADDREF_P(pz)                           (++(pz)->refcount)
00310 #define Z_REFCOUNT_P(pz)                  ((pz)->refcount)
00311 #define Z_SET_REFCOUNT_P(pz, rc)   ((pz)->refcount = rc)
00312 #endif
00313 
00314 
00315 /* {{{ mysqli_read_property */
00316 zval *mysqli_read_property(zval *object, zval *member, int type TSRMLS_DC)
00317 {
00318        zval tmp_member;
00319        zval *retval;
00320        mysqli_object *obj;
00321        mysqli_prop_handler *hnd;
00322        int ret;
00323 
00324        ret = FAILURE;
00325        obj = (mysqli_object *)zend_objects_get_address(object TSRMLS_CC);
00326 
00327        if (member->type != IS_STRING) {
00328               tmp_member = *member;
00329               zval_copy_ctor(&tmp_member);
00330               convert_to_string(&tmp_member);
00331               member = &tmp_member;
00332        }
00333 
00334        if (obj->prop_handler != NULL) {
00335               ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
00336        }
00337 
00338        if (ret == SUCCESS) {
00339               ret = hnd->read_func(obj, &retval TSRMLS_CC);
00340               if (ret == SUCCESS) {
00341                      /* ensure we're creating a temporary variable */
00342                      Z_SET_REFCOUNT_P(retval, 0);
00343               } else {
00344                      retval = EG(uninitialized_zval_ptr);
00345               }
00346        } else {
00347               zend_object_handlers * std_hnd = zend_get_std_object_handlers();
00348               retval = std_hnd->read_property(object, member, type TSRMLS_CC);
00349        }
00350 
00351        if (member == &tmp_member) {
00352               zval_dtor(member);
00353        }
00354        return(retval);
00355 }
00356 /* }}} */
00357 
00358 /* {{{ mysqli_write_property */
00359 void mysqli_write_property(zval *object, zval *member, zval *value TSRMLS_DC)
00360 {
00361        zval tmp_member;
00362        mysqli_object *obj;
00363        mysqli_prop_handler *hnd;
00364        int ret;
00365 
00366        if (member->type != IS_STRING) {
00367               tmp_member = *member;
00368               zval_copy_ctor(&tmp_member);
00369               convert_to_string(&tmp_member);
00370               member = &tmp_member;
00371        }
00372 
00373        ret = FAILURE;
00374        obj = (mysqli_object *)zend_objects_get_address(object TSRMLS_CC);
00375 
00376        if (obj->prop_handler != NULL) {
00377               ret = zend_hash_find((HashTable *)obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
00378        }
00379        if (ret == SUCCESS) {
00380               hnd->write_func(obj, value TSRMLS_CC);
00381               if (! PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) == 0) {
00382                      Z_ADDREF_P(value);
00383                      zval_ptr_dtor(&value);
00384               }
00385        } else {
00386               zend_object_handlers * std_hnd = zend_get_std_object_handlers();
00387               std_hnd->write_property(object, member, value TSRMLS_CC);
00388        }
00389 
00390        if (member == &tmp_member) {
00391               zval_dtor(member);
00392        }
00393 }
00394 /* }}} */
00395 
00396 /* {{{ void mysqli_add_property(HashTable *h, char *pname, mysqli_read_t r_func, mysqli_write_t w_func TSRMLS_DC) */
00397 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) {
00398        mysqli_prop_handler         p;
00399 
00400        p.name = (char*) pname;
00401        p.name_len = pname_len;
00402        p.read_func = (r_func) ? r_func : mysqli_read_na;
00403        p.write_func = (w_func) ? w_func : mysqli_write_na;
00404        zend_hash_add(h, pname, pname_len + 1, &p, sizeof(mysqli_prop_handler), NULL);
00405 }
00406 /* }}} */
00407 
00408 static int mysqli_object_has_property(zval *object, zval *member, int has_set_exists TSRMLS_DC) /* {{{ */
00409 {
00410        mysqli_object *obj = (mysqli_object *)zend_objects_get_address(object TSRMLS_CC);
00411        mysqli_prop_handler  p;
00412        int ret = 0;
00413 
00414        if (zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member) + 1, (void **)&p) == SUCCESS) {
00415               switch (has_set_exists) {
00416                      case 2:
00417                             ret = 1;
00418                             break;
00419                      case 1: {
00420                             zval *value = mysqli_read_property(object, member, BP_VAR_IS TSRMLS_CC);
00421                             if (value != EG(uninitialized_zval_ptr)) {
00422                                    convert_to_boolean(value);
00423                                    ret = Z_BVAL_P(value)? 1:0;
00424                                    /* refcount is 0 */
00425                                    Z_ADDREF_P(value);
00426                                    zval_ptr_dtor(&value);
00427                             }
00428                             break;
00429                      }
00430                      case 0:{
00431                             zval *value = mysqli_read_property(object, member, BP_VAR_IS TSRMLS_CC);
00432                             if (value != EG(uninitialized_zval_ptr)) {
00433                                    ret = Z_TYPE_P(value) != IS_NULL? 1:0;
00434                                    /* refcount is 0 */
00435                                    Z_ADDREF_P(value);
00436                                    zval_ptr_dtor(&value);
00437                             }
00438                             break;
00439                      }
00440                      default:
00441                             php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid value for has_set_exists");
00442               }
00443        } else {
00444               zend_object_handlers * std_hnd = zend_get_std_object_handlers();
00445               ret = std_hnd->has_property(object, member, has_set_exists TSRMLS_CC);
00446        }
00447        return ret;
00448 } /* }}} */
00449 
00450 
00451 #if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3
00452 HashTable * mysqli_object_get_debug_info(zval *object, int *is_temp TSRMLS_DC)
00453 {
00454        mysqli_object *obj = (mysqli_object *)zend_objects_get_address(object TSRMLS_CC);
00455        HashTable *retval, *props = obj->prop_handler;
00456        HashPosition pos;
00457        mysqli_prop_handler *entry;
00458 
00459        ALLOC_HASHTABLE(retval);
00460        ZEND_INIT_SYMTABLE_EX(retval, zend_hash_num_elements(props) + 1, 0);
00461 
00462        zend_hash_internal_pointer_reset_ex(props, &pos);
00463        while (zend_hash_get_current_data_ex(props, (void **)&entry, &pos) == SUCCESS) {
00464               zval member;
00465               zval *value;
00466               INIT_ZVAL(member);
00467               ZVAL_STRINGL(&member, entry->name, entry->name_len, 0);
00468               value = mysqli_read_property(object, &member, BP_VAR_IS TSRMLS_CC);
00469               if (value != EG(uninitialized_zval_ptr)) {
00470                      Z_ADDREF_P(value);
00471                      zend_hash_add(retval, entry->name, entry->name_len + 1, &value, sizeof(zval *), NULL);
00472               }
00473               zend_hash_move_forward_ex(props, &pos);
00474        }
00475 
00476        *is_temp = 1;
00477        return retval;
00478 }
00479 #endif
00480 
00481 /* {{{ mysqli_objects_new
00482  */
00483 PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry *class_type TSRMLS_DC)
00484 {
00485        zend_object_value retval;
00486        mysqli_object *intern;
00487        zval *tmp;
00488        zend_class_entry *mysqli_base_class;
00489        zend_objects_free_object_storage_t free_storage;
00490 
00491        intern = emalloc(sizeof(mysqli_object));
00492        memset(intern, 0, sizeof(mysqli_object));
00493        intern->ptr = NULL;
00494        intern->prop_handler = NULL;
00495 
00496        mysqli_base_class = class_type;
00497        while (mysqli_base_class->type != ZEND_INTERNAL_CLASS &&
00498                  mysqli_base_class->parent != NULL) {
00499               mysqli_base_class = mysqli_base_class->parent;
00500        }
00501        zend_hash_find(&classes, mysqli_base_class->name, mysqli_base_class->name_length + 1,
00502                                    (void **) &intern->prop_handler);
00503 
00504        zend_object_std_init(&intern->zo, class_type TSRMLS_CC);
00505        zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref,
00506                                    (void *) &tmp, sizeof(zval *));
00507 
00508        /* link object */
00509        if (instanceof_function(class_type, mysqli_link_class_entry TSRMLS_CC)) {
00510               free_storage = mysqli_link_free_storage;
00511        } else if (instanceof_function(class_type, mysqli_driver_class_entry TSRMLS_CC)) { /* driver object */
00512               free_storage = mysqli_driver_free_storage;
00513        } else if (instanceof_function(class_type, mysqli_stmt_class_entry TSRMLS_CC)) { /* stmt object */
00514               free_storage = mysqli_stmt_free_storage;
00515        } else if (instanceof_function(class_type, mysqli_result_class_entry TSRMLS_CC)) { /* result object */
00516               free_storage = mysqli_result_free_storage;
00517        } else if (instanceof_function(class_type, mysqli_warning_class_entry TSRMLS_CC)) { /* warning object */
00518               free_storage = mysqli_warning_free_storage;
00519        } else {
00520               free_storage = mysqli_objects_free_storage;
00521        }
00522 
00523        retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, free_storage, NULL TSRMLS_CC);
00524        retval.handlers = &mysqli_object_handlers;
00525 
00526        return retval;
00527 }
00528 /* }}} */
00529 
00530 
00531 /* {{{ PHP_INI_BEGIN
00532 */
00533 PHP_INI_BEGIN()
00534        STD_PHP_INI_ENTRY_EX("mysqli.max_links",                "-1",  PHP_INI_SYSTEM,             OnUpdateLong,        max_links,                  zend_mysqli_globals,        mysqli_globals, display_link_numbers)
00535        STD_PHP_INI_ENTRY_EX("mysqli.max_persistent",           "-1",  PHP_INI_SYSTEM,             OnUpdateLong,        max_persistent,             zend_mysqli_globals,        mysqli_globals,      display_link_numbers)
00536        STD_PHP_INI_BOOLEAN("mysqli.allow_persistent",          "1",   PHP_INI_SYSTEM,             OnUpdateLong,        allow_persistent,    zend_mysqli_globals,        mysqli_globals)
00537        STD_PHP_INI_ENTRY("mysqli.default_host",                NULL,  PHP_INI_ALL,         OnUpdateString,             default_host,        zend_mysqli_globals,        mysqli_globals)
00538        STD_PHP_INI_ENTRY("mysqli.default_user",                NULL,  PHP_INI_ALL,         OnUpdateString,             default_user,        zend_mysqli_globals,        mysqli_globals)
00539        STD_PHP_INI_ENTRY("mysqli.default_pw",                         NULL,  PHP_INI_ALL,         OnUpdateString,             default_pw,                 zend_mysqli_globals,        mysqli_globals)
00540        STD_PHP_INI_ENTRY("mysqli.default_port",                "3306",       PHP_INI_ALL,         OnUpdateLong,        default_port,        zend_mysqli_globals,        mysqli_globals)
00541 #ifdef PHP_MYSQL_UNIX_SOCK_ADDR
00542        STD_PHP_INI_ENTRY("mysqli.default_socket",                     MYSQL_UNIX_ADDR,PHP_INI_ALL,OnUpdateStringUnempty,      default_socket,      zend_mysqli_globals,        mysqli_globals)
00543 #else
00544        STD_PHP_INI_ENTRY("mysqli.default_socket",                     NULL,  PHP_INI_ALL,         OnUpdateStringUnempty,      default_socket,      zend_mysqli_globals,        mysqli_globals)
00545 #endif
00546        STD_PHP_INI_BOOLEAN("mysqli.reconnect",                        "0",   PHP_INI_SYSTEM,             OnUpdateLong,        reconnect,                  zend_mysqli_globals,        mysqli_globals)
00547        STD_PHP_INI_BOOLEAN("mysqli.allow_local_infile", "1",   PHP_INI_SYSTEM,             OnUpdateLong,        allow_local_infile,  zend_mysqli_globals,        mysqli_globals)
00548 PHP_INI_END()
00549 /* }}} */
00550 
00551 
00552 /* {{{ PHP_GINIT_FUNCTION
00553  */
00554 static PHP_GINIT_FUNCTION(mysqli)
00555 {
00556        mysqli_globals->num_links = 0;
00557        mysqli_globals->num_active_persistent = 0;
00558        mysqli_globals->num_inactive_persistent = 0;
00559        mysqli_globals->max_links = -1;
00560        mysqli_globals->max_persistent = -1;
00561        mysqli_globals->allow_persistent = 1;
00562        mysqli_globals->default_port = 0;
00563        mysqli_globals->default_host = NULL;
00564        mysqli_globals->default_user = NULL;
00565        mysqli_globals->default_pw = NULL;
00566        mysqli_globals->default_socket = NULL;
00567        mysqli_globals->reconnect = 0;
00568        mysqli_globals->report_mode = 0;
00569        mysqli_globals->report_ht = 0;
00570        mysqli_globals->allow_local_infile = 1;
00571 #ifdef HAVE_EMBEDDED_MYSQLI
00572        mysqli_globals->embedded = 1;
00573 #else
00574        mysqli_globals->embedded = 0;
00575 #endif
00576 }
00577 /* }}} */
00578 
00579 /* {{{ PHP_MINIT_FUNCTION
00580  */
00581 PHP_MINIT_FUNCTION(mysqli)
00582 {
00583        zend_class_entry *ce,cex;
00584        zend_object_handlers *std_hnd = zend_get_std_object_handlers();
00585 
00586        REGISTER_INI_ENTRIES();
00587 #ifndef MYSQLI_USE_MYSQLND
00588 #if MYSQL_VERSION_ID >= 40000
00589        if (mysql_server_init(0, NULL, NULL)) {
00590               return FAILURE;
00591        }
00592 #endif
00593 #endif
00594 
00595        memcpy(&mysqli_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
00596        mysqli_object_handlers.clone_obj = NULL;
00597        mysqli_object_handlers.read_property = mysqli_read_property;
00598        mysqli_object_handlers.write_property = mysqli_write_property;
00599        mysqli_object_handlers.get_property_ptr_ptr = std_hnd->get_property_ptr_ptr;
00600        mysqli_object_handlers.has_property = mysqli_object_has_property;
00601 #if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3
00602        mysqli_object_handlers.get_debug_info = mysqli_object_get_debug_info;
00603 #endif
00604 
00605        zend_hash_init(&classes, 0, NULL, NULL, 1);
00606 
00607        /* persistent connections */
00608        le_pmysqli = zend_register_list_destructors_ex(NULL, php_mysqli_dtor,
00609               "MySqli persistent connection", module_number);
00610 
00611        INIT_CLASS_ENTRY(cex, "mysqli_sql_exception", mysqli_exception_methods);
00612 #ifdef HAVE_SPL
00613        mysqli_exception_class_entry = zend_register_internal_class_ex(&cex, spl_ce_RuntimeException, NULL TSRMLS_CC);
00614 #else
00615        mysqli_exception_class_entry = zend_register_internal_class_ex(&cex, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
00616 #endif
00617        mysqli_exception_class_entry->ce_flags |= ZEND_ACC_FINAL;
00618        zend_declare_property_long(mysqli_exception_class_entry, "code", sizeof("code")-1, 0, ZEND_ACC_PROTECTED TSRMLS_CC);
00619        zend_declare_property_string(mysqli_exception_class_entry, "sqlstate", sizeof("sqlstate")-1, "00000", ZEND_ACC_PROTECTED TSRMLS_CC);
00620 
00621        REGISTER_MYSQLI_CLASS_ENTRY("mysqli_driver", mysqli_driver_class_entry, mysqli_driver_methods);
00622        ce = mysqli_driver_class_entry;
00623        zend_hash_init(&mysqli_driver_properties, 0, NULL, NULL, 1);
00624        MYSQLI_ADD_PROPERTIES(&mysqli_driver_properties, mysqli_driver_property_entries);
00625        MYSQLI_ADD_PROPERTIES_INFO(ce, mysqli_driver_property_info_entries);
00626        zend_hash_add(&classes, ce->name, ce->name_length+1, &mysqli_driver_properties, sizeof(mysqli_driver_properties), NULL);
00627        ce->ce_flags |= ZEND_ACC_FINAL_CLASS;
00628 
00629        REGISTER_MYSQLI_CLASS_ENTRY("mysqli", mysqli_link_class_entry, mysqli_link_methods);
00630        ce = mysqli_link_class_entry;
00631        zend_hash_init(&mysqli_link_properties, 0, NULL, NULL, 1);
00632        MYSQLI_ADD_PROPERTIES(&mysqli_link_properties, mysqli_link_property_entries);
00633        MYSQLI_ADD_PROPERTIES_INFO(ce, mysqli_link_property_info_entries);
00634        zend_hash_add(&classes, ce->name, ce->name_length+1, &mysqli_link_properties, sizeof(mysqli_link_properties), NULL);
00635 
00636        REGISTER_MYSQLI_CLASS_ENTRY("mysqli_warning", mysqli_warning_class_entry, mysqli_warning_methods);
00637        ce = mysqli_warning_class_entry;
00638        ce->ce_flags |= ZEND_ACC_FINAL_CLASS | ZEND_ACC_PROTECTED;
00639        zend_hash_init(&mysqli_warning_properties, 0, NULL, NULL, 1);
00640        MYSQLI_ADD_PROPERTIES(&mysqli_warning_properties, mysqli_warning_property_entries);
00641        MYSQLI_ADD_PROPERTIES_INFO(ce, mysqli_warning_property_info_entries);
00642        zend_hash_add(&classes, ce->name, ce->name_length+1, &mysqli_warning_properties, sizeof(mysqli_warning_properties), NULL);
00643 
00644        REGISTER_MYSQLI_CLASS_ENTRY("mysqli_result", mysqli_result_class_entry, mysqli_result_methods);
00645        ce = mysqli_result_class_entry;
00646        zend_hash_init(&mysqli_result_properties, 0, NULL, NULL, 1);
00647        MYSQLI_ADD_PROPERTIES(&mysqli_result_properties, mysqli_result_property_entries);
00648        MYSQLI_ADD_PROPERTIES_INFO(ce, mysqli_result_property_info_entries);
00649        zend_hash_add(&classes, ce->name, ce->name_length+1, &mysqli_result_properties, sizeof(mysqli_result_properties), NULL);
00650 
00651        REGISTER_MYSQLI_CLASS_ENTRY("mysqli_stmt", mysqli_stmt_class_entry, mysqli_stmt_methods);
00652        ce = mysqli_stmt_class_entry;
00653        zend_hash_init(&mysqli_stmt_properties, 0, NULL, NULL, 1);
00654        MYSQLI_ADD_PROPERTIES(&mysqli_stmt_properties, mysqli_stmt_property_entries);
00655        MYSQLI_ADD_PROPERTIES_INFO(ce, mysqli_stmt_property_info_entries);
00656        zend_hash_add(&classes, ce->name, ce->name_length+1, &mysqli_stmt_properties, sizeof(mysqli_stmt_properties), NULL);
00657 
00658        /* mysqli_options */
00659        REGISTER_LONG_CONSTANT("MYSQLI_READ_DEFAULT_GROUP", MYSQL_READ_DEFAULT_GROUP, CONST_CS | CONST_PERSISTENT);
00660        REGISTER_LONG_CONSTANT("MYSQLI_READ_DEFAULT_FILE", MYSQL_READ_DEFAULT_FILE, CONST_CS | CONST_PERSISTENT);
00661        REGISTER_LONG_CONSTANT("MYSQLI_OPT_CONNECT_TIMEOUT", MYSQL_OPT_CONNECT_TIMEOUT, CONST_CS | CONST_PERSISTENT);
00662        REGISTER_LONG_CONSTANT("MYSQLI_OPT_LOCAL_INFILE", MYSQL_OPT_LOCAL_INFILE, CONST_CS | CONST_PERSISTENT);
00663        REGISTER_LONG_CONSTANT("MYSQLI_INIT_COMMAND", MYSQL_INIT_COMMAND, CONST_CS | CONST_PERSISTENT);
00664 #if defined(MYSQLI_USE_MYSQLND)
00665        REGISTER_LONG_CONSTANT("MYSQLI_OPT_NET_CMD_BUFFER_SIZE", MYSQLND_OPT_NET_CMD_BUFFER_SIZE, CONST_CS | CONST_PERSISTENT);
00666        REGISTER_LONG_CONSTANT("MYSQLI_OPT_NET_READ_BUFFER_SIZE", MYSQLND_OPT_NET_READ_BUFFER_SIZE, CONST_CS | CONST_PERSISTENT);
00667 #endif
00668 #ifdef MYSQLND_STRING_TO_INT_CONVERSION
00669        REGISTER_LONG_CONSTANT("MYSQLI_OPT_INT_AND_FLOAT_NATIVE", MYSQLND_OPT_INT_AND_FLOAT_NATIVE, CONST_CS | CONST_PERSISTENT);
00670 #endif
00671 #if MYSQL_VERSION_ID > 50110 || defined(MYSQLI_USE_MYSQLND)
00672        REGISTER_LONG_CONSTANT("MYSQLI_OPT_SSL_VERIFY_SERVER_CERT", MYSQL_OPT_SSL_VERIFY_SERVER_CERT, CONST_CS | CONST_PERSISTENT);
00673 #endif
00674 
00675        /* mysqli_real_connect flags */
00676        REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_SSL", CLIENT_SSL, CONST_CS | CONST_PERSISTENT);
00677        REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_COMPRESS",CLIENT_COMPRESS, CONST_CS | CONST_PERSISTENT);
00678        REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_INTERACTIVE", CLIENT_INTERACTIVE, CONST_CS | CONST_PERSISTENT);
00679        REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_IGNORE_SPACE", CLIENT_IGNORE_SPACE, CONST_CS | CONST_PERSISTENT);
00680        REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_NO_SCHEMA", CLIENT_NO_SCHEMA, CONST_CS | CONST_PERSISTENT);
00681        REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_FOUND_ROWS", CLIENT_FOUND_ROWS, CONST_CS | CONST_PERSISTENT);
00682 
00683        /* for mysqli_query */
00684        REGISTER_LONG_CONSTANT("MYSQLI_STORE_RESULT", MYSQLI_STORE_RESULT, CONST_CS | CONST_PERSISTENT);
00685        REGISTER_LONG_CONSTANT("MYSQLI_USE_RESULT", MYSQLI_USE_RESULT, CONST_CS | CONST_PERSISTENT);
00686 #if defined (MYSQLI_USE_MYSQLND)
00687        REGISTER_LONG_CONSTANT("MYSQLI_ASYNC", MYSQLI_ASYNC, CONST_CS | CONST_PERSISTENT);
00688 #endif
00689 
00690        /* for mysqli_fetch_assoc */
00691        REGISTER_LONG_CONSTANT("MYSQLI_ASSOC", MYSQLI_ASSOC, CONST_CS | CONST_PERSISTENT);
00692        REGISTER_LONG_CONSTANT("MYSQLI_NUM", MYSQLI_NUM, CONST_CS | CONST_PERSISTENT);
00693        REGISTER_LONG_CONSTANT("MYSQLI_BOTH", MYSQLI_BOTH, CONST_CS | CONST_PERSISTENT);
00694 
00695        /* for mysqli_stmt_set_attr */
00696        REGISTER_LONG_CONSTANT("MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH", STMT_ATTR_UPDATE_MAX_LENGTH, CONST_CS | CONST_PERSISTENT);
00697 
00698 #if MYSQL_VERSION_ID > 50003 || defined(MYSQLI_USE_MYSQLND)
00699        REGISTER_LONG_CONSTANT("MYSQLI_STMT_ATTR_CURSOR_TYPE", STMT_ATTR_CURSOR_TYPE, CONST_CS | CONST_PERSISTENT);
00700        REGISTER_LONG_CONSTANT("MYSQLI_CURSOR_TYPE_NO_CURSOR", CURSOR_TYPE_NO_CURSOR, CONST_CS | CONST_PERSISTENT);
00701        REGISTER_LONG_CONSTANT("MYSQLI_CURSOR_TYPE_READ_ONLY", CURSOR_TYPE_READ_ONLY, CONST_CS | CONST_PERSISTENT);
00702        REGISTER_LONG_CONSTANT("MYSQLI_CURSOR_TYPE_FOR_UPDATE", CURSOR_TYPE_FOR_UPDATE, CONST_CS | CONST_PERSISTENT);
00703        REGISTER_LONG_CONSTANT("MYSQLI_CURSOR_TYPE_SCROLLABLE", CURSOR_TYPE_SCROLLABLE, CONST_CS | CONST_PERSISTENT);
00704 #endif
00705 
00706 #if MYSQL_VERSION_ID > 50007 || defined(MYSQLI_USE_MYSQLND)
00707        REGISTER_LONG_CONSTANT("MYSQLI_STMT_ATTR_PREFETCH_ROWS", STMT_ATTR_PREFETCH_ROWS, CONST_CS | CONST_PERSISTENT);
00708 #endif
00709 
00710        /* column information */
00711        REGISTER_LONG_CONSTANT("MYSQLI_NOT_NULL_FLAG", NOT_NULL_FLAG, CONST_CS | CONST_PERSISTENT);
00712        REGISTER_LONG_CONSTANT("MYSQLI_PRI_KEY_FLAG", PRI_KEY_FLAG, CONST_CS | CONST_PERSISTENT);
00713        REGISTER_LONG_CONSTANT("MYSQLI_UNIQUE_KEY_FLAG", UNIQUE_KEY_FLAG, CONST_CS | CONST_PERSISTENT);
00714        REGISTER_LONG_CONSTANT("MYSQLI_MULTIPLE_KEY_FLAG", MULTIPLE_KEY_FLAG, CONST_CS | CONST_PERSISTENT);
00715        REGISTER_LONG_CONSTANT("MYSQLI_BLOB_FLAG", BLOB_FLAG, CONST_CS | CONST_PERSISTENT);
00716        REGISTER_LONG_CONSTANT("MYSQLI_UNSIGNED_FLAG", UNSIGNED_FLAG, CONST_CS | CONST_PERSISTENT);
00717        REGISTER_LONG_CONSTANT("MYSQLI_ZEROFILL_FLAG", ZEROFILL_FLAG, CONST_CS | CONST_PERSISTENT);
00718        REGISTER_LONG_CONSTANT("MYSQLI_AUTO_INCREMENT_FLAG", AUTO_INCREMENT_FLAG, CONST_CS | CONST_PERSISTENT);
00719        REGISTER_LONG_CONSTANT("MYSQLI_TIMESTAMP_FLAG", TIMESTAMP_FLAG, CONST_CS | CONST_PERSISTENT);
00720        REGISTER_LONG_CONSTANT("MYSQLI_SET_FLAG", SET_FLAG, CONST_CS | CONST_PERSISTENT);
00721        REGISTER_LONG_CONSTANT("MYSQLI_NUM_FLAG", NUM_FLAG, CONST_CS | CONST_PERSISTENT);
00722        REGISTER_LONG_CONSTANT("MYSQLI_PART_KEY_FLAG", PART_KEY_FLAG, CONST_CS | CONST_PERSISTENT);
00723        REGISTER_LONG_CONSTANT("MYSQLI_GROUP_FLAG", GROUP_FLAG, CONST_CS | CONST_PERSISTENT);
00724        REGISTER_LONG_CONSTANT("MYSQLI_ENUM_FLAG", ENUM_FLAG, CONST_CS | CONST_PERSISTENT);
00725        REGISTER_LONG_CONSTANT("MYSQLI_BINARY_FLAG", BINARY_FLAG, CONST_CS | CONST_PERSISTENT);
00726 #if MYSQL_VERSION_ID > 50001 || defined(MYSQLI_USE_MYSQLND)
00727        REGISTER_LONG_CONSTANT("MYSQLI_NO_DEFAULT_VALUE_FLAG", NO_DEFAULT_VALUE_FLAG, CONST_CS | CONST_PERSISTENT);
00728 #endif
00729 
00730 #if (MYSQL_VERSION_ID > 51122 && MYSQL_VERSION_ID < 60000) || (MYSQL_VERSION_ID > 60003) || defined(MYSQLI_USE_MYSQLND)
00731        REGISTER_LONG_CONSTANT("MYSQLI_ON_UPDATE_NOW_FLAG", ON_UPDATE_NOW_FLAG, CONST_CS | CONST_PERSISTENT);
00732 #endif
00733 
00734        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_DECIMAL", FIELD_TYPE_DECIMAL, CONST_CS | CONST_PERSISTENT);
00735        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_TINY", FIELD_TYPE_TINY, CONST_CS | CONST_PERSISTENT);
00736        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_SHORT", FIELD_TYPE_SHORT, CONST_CS | CONST_PERSISTENT);
00737        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_LONG", FIELD_TYPE_LONG, CONST_CS | CONST_PERSISTENT);
00738        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_FLOAT", FIELD_TYPE_FLOAT, CONST_CS | CONST_PERSISTENT);
00739        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_DOUBLE", FIELD_TYPE_DOUBLE, CONST_CS | CONST_PERSISTENT);
00740        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_NULL", FIELD_TYPE_NULL, CONST_CS | CONST_PERSISTENT);
00741        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_TIMESTAMP", FIELD_TYPE_TIMESTAMP, CONST_CS | CONST_PERSISTENT);
00742        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_LONGLONG", FIELD_TYPE_LONGLONG, CONST_CS | CONST_PERSISTENT);
00743        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_INT24", FIELD_TYPE_INT24, CONST_CS | CONST_PERSISTENT);
00744        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_DATE", FIELD_TYPE_DATE, CONST_CS | CONST_PERSISTENT);
00745        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_TIME", FIELD_TYPE_TIME, CONST_CS | CONST_PERSISTENT);
00746        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_DATETIME", FIELD_TYPE_DATETIME    , CONST_CS | CONST_PERSISTENT);
00747        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_YEAR", FIELD_TYPE_YEAR, CONST_CS | CONST_PERSISTENT);
00748        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_NEWDATE", FIELD_TYPE_NEWDATE, CONST_CS | CONST_PERSISTENT);
00749        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_ENUM", FIELD_TYPE_ENUM, CONST_CS | CONST_PERSISTENT);
00750        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_SET", FIELD_TYPE_SET, CONST_CS | CONST_PERSISTENT);
00751        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_TINY_BLOB", FIELD_TYPE_TINY_BLOB, CONST_CS | CONST_PERSISTENT);
00752        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_MEDIUM_BLOB", FIELD_TYPE_MEDIUM_BLOB, CONST_CS | CONST_PERSISTENT);
00753        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_LONG_BLOB", FIELD_TYPE_LONG_BLOB, CONST_CS | CONST_PERSISTENT);
00754        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_BLOB", FIELD_TYPE_BLOB, CONST_CS | CONST_PERSISTENT);
00755        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_VAR_STRING", FIELD_TYPE_VAR_STRING, CONST_CS | CONST_PERSISTENT);
00756        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_STRING", FIELD_TYPE_STRING, CONST_CS | CONST_PERSISTENT);
00757        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_CHAR", FIELD_TYPE_CHAR, CONST_CS | CONST_PERSISTENT);
00758        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_INTERVAL", FIELD_TYPE_INTERVAL, CONST_CS | CONST_PERSISTENT);
00759        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_GEOMETRY", FIELD_TYPE_GEOMETRY, CONST_CS | CONST_PERSISTENT);
00760 
00761 #if MYSQL_VERSION_ID > 50002 || defined(MYSQLI_USE_MYSQLND)
00762        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_NEWDECIMAL", FIELD_TYPE_NEWDECIMAL, CONST_CS | CONST_PERSISTENT);
00763        REGISTER_LONG_CONSTANT("MYSQLI_TYPE_BIT", FIELD_TYPE_BIT, CONST_CS | CONST_PERSISTENT);
00764 #endif
00765 
00766        REGISTER_LONG_CONSTANT("MYSQLI_SET_CHARSET_NAME", MYSQL_SET_CHARSET_NAME, CONST_CS | CONST_PERSISTENT);
00767        REGISTER_LONG_CONSTANT("MYSQLI_SET_CHARSET_DIR", MYSQL_SET_CHARSET_DIR, CONST_CS | CONST_PERSISTENT);
00768 
00769        /* bind support */
00770        REGISTER_LONG_CONSTANT("MYSQLI_NO_DATA", MYSQL_NO_DATA, CONST_CS | CONST_PERSISTENT);
00771 #ifdef MYSQL_DATA_TRUNCATED
00772        REGISTER_LONG_CONSTANT("MYSQLI_DATA_TRUNCATED", MYSQL_DATA_TRUNCATED, CONST_CS | CONST_PERSISTENT);
00773 #endif
00774 
00775        /* reporting */
00776        REGISTER_LONG_CONSTANT("MYSQLI_REPORT_INDEX", MYSQLI_REPORT_INDEX, CONST_CS | CONST_PERSISTENT);
00777        REGISTER_LONG_CONSTANT("MYSQLI_REPORT_ERROR", MYSQLI_REPORT_ERROR, CONST_CS | CONST_PERSISTENT);
00778        REGISTER_LONG_CONSTANT("MYSQLI_REPORT_STRICT", MYSQLI_REPORT_STRICT, CONST_CS | CONST_PERSISTENT);
00779        REGISTER_LONG_CONSTANT("MYSQLI_REPORT_ALL", MYSQLI_REPORT_ALL, CONST_CS | CONST_PERSISTENT);
00780        REGISTER_LONG_CONSTANT("MYSQLI_REPORT_OFF", 0, CONST_CS | CONST_PERSISTENT);
00781 
00782        /* We use non-nested macros with expansion, as VC has problems */
00783 #ifdef MYSQLI_USE_MYSQLND
00784        REGISTER_LONG_CONSTANT("MYSQLI_DEBUG_TRACE_ENABLED", MYSQLND_DBG_ENABLED, CONST_CS | CONST_PERSISTENT);
00785 #else
00786 #ifndef DBUG_OFF
00787        REGISTER_LONG_CONSTANT("MYSQLI_DEBUG_TRACE_ENABLED", 0, CONST_CS | CONST_PERSISTENT);
00788 #else
00789        REGISTER_LONG_CONSTANT("MYSQLI_DEBUG_TRACE_ENABLED", 1, CONST_CS | CONST_PERSISTENT);
00790 #endif
00791 #endif
00792 
00793        REGISTER_LONG_CONSTANT("MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED", SERVER_QUERY_NO_GOOD_INDEX_USED, CONST_CS | CONST_PERSISTENT);
00794        REGISTER_LONG_CONSTANT("MYSQLI_SERVER_QUERY_NO_INDEX_USED", SERVER_QUERY_NO_INDEX_USED, CONST_CS | CONST_PERSISTENT);
00795 #ifdef SERVER_QUERY_WAS_SLOW
00796        REGISTER_LONG_CONSTANT("MYSQLI_SERVER_QUERY_WAS_SLOW", SERVER_QUERY_WAS_SLOW, CONST_CS | CONST_PERSISTENT);
00797 #endif
00798 #ifdef SERVER_PS_OUT_PARAMS
00799        REGISTER_LONG_CONSTANT("MYSQLI_SERVER_PS_OUT_PARAMS", SERVER_PS_OUT_PARAMS, CONST_CS | CONST_PERSISTENT);
00800 #endif
00801 
00802        REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_GRANT",      REFRESH_GRANT, CONST_CS | CONST_PERSISTENT);
00803        REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_LOG",        REFRESH_LOG, CONST_CS | CONST_PERSISTENT);
00804        REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_TABLES",     REFRESH_TABLES, CONST_CS | CONST_PERSISTENT);
00805        REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_HOSTS",      REFRESH_HOSTS, CONST_CS | CONST_PERSISTENT);
00806        REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_STATUS",     REFRESH_STATUS, CONST_CS | CONST_PERSISTENT);
00807        REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_THREADS",    REFRESH_THREADS, CONST_CS | CONST_PERSISTENT);
00808        REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_SLAVE",      REFRESH_SLAVE, CONST_CS | CONST_PERSISTENT);
00809        REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_MASTER",     REFRESH_MASTER, CONST_CS | CONST_PERSISTENT);
00810 #ifdef REFRESH_BACKUP_LOG
00811        REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_BACKUP_LOG", REFRESH_BACKUP_LOG, CONST_CS | CONST_PERSISTENT);
00812 #endif
00813 
00814        return SUCCESS;
00815 }
00816 /* }}} */
00817 
00818 /* {{{ PHP_MSHUTDOWN_FUNCTION
00819  */
00820 PHP_MSHUTDOWN_FUNCTION(mysqli)
00821 {
00822 #ifndef MYSQLI_USE_MYSQLND
00823 #if MYSQL_VERSION_ID >= 40000
00824 #ifdef PHP_WIN32
00825        unsigned long client_ver = mysql_get_client_version();
00826        /*
00827          Can't call mysql_server_end() multiple times prior to 5.0.46 on Windows.
00828          PHP bug#41350 MySQL bug#25621
00829        */
00830        if ((client_ver >= 50046 && client_ver < 50100) || client_ver > 50122) {
00831               mysql_server_end();
00832        }
00833 #else
00834        mysql_server_end();
00835 #endif
00836 #endif
00837 #endif
00838 
00839        zend_hash_destroy(&mysqli_driver_properties);
00840        zend_hash_destroy(&mysqli_result_properties);
00841        zend_hash_destroy(&mysqli_stmt_properties);
00842        zend_hash_destroy(&mysqli_warning_properties);
00843        zend_hash_destroy(&mysqli_link_properties);
00844        zend_hash_destroy(&classes);
00845 
00846        UNREGISTER_INI_ENTRIES();
00847        return SUCCESS;
00848 }
00849 /* }}} */
00850 
00851 /* {{{ PHP_RINIT_FUNCTION
00852  */
00853 PHP_RINIT_FUNCTION(mysqli)
00854 {
00855 #if !defined(MYSQLI_USE_MYSQLND) && defined(ZTS) && MYSQL_VERSION_ID >= 40000
00856        if (mysql_thread_init()) {
00857               return FAILURE;
00858        }
00859 #endif
00860        MyG(error_msg) = NULL;
00861        MyG(error_no) = 0;
00862        MyG(report_mode) = 0;
00863 
00864        return SUCCESS;
00865 }
00866 /* }}} */
00867 
00868 #if defined(A0) && defined(MYSQLI_USE_MYSQLND)
00869 static void php_mysqli_persistent_helper_for_every(void *p)
00870 {
00871        TSRMLS_FETCH();
00872        mysqlnd_end_psession((MYSQLND *) p);
00873 } /* }}} */
00874 
00875 
00876 static int php_mysqli_persistent_helper_once(zend_rsrc_list_entry *le TSRMLS_DC)
00877 {
00878        if (le->type == php_le_pmysqli()) {
00879               mysqli_plist_entry *plist = (mysqli_plist_entry *) le->ptr;
00880               zend_ptr_stack_apply(&plist->free_links, php_mysqli_persistent_helper_for_every);
00881        }
00882        return ZEND_HASH_APPLY_KEEP;
00883 } /* }}} */
00884 #endif
00885 
00886 
00887 /* {{{ PHP_RSHUTDOWN_FUNCTION
00888  */
00889 PHP_RSHUTDOWN_FUNCTION(mysqli)
00890 {
00891        /* check persistent connections, move used to free */
00892 
00893 #if !defined(MYSQLI_USE_MYSQLND) && defined(ZTS) && MYSQL_VERSION_ID >= 40000
00894        mysql_thread_end();
00895 #endif
00896        if (MyG(error_msg)) {
00897               efree(MyG(error_msg));
00898        }
00899 #if defined(A0) && defined(MYSQLI_USE_MYSQLND)
00900        /* psession is being called when the connection is freed - explicitly or implicitly */
00901        zend_hash_apply(&EG(persistent_list), (apply_func_t) php_mysqli_persistent_helper_once TSRMLS_CC);
00902 #endif
00903        return SUCCESS;
00904 }
00905 /* }}} */
00906 
00907 
00908 /* {{{ PHP_MINFO_FUNCTION
00909  */
00910 PHP_MINFO_FUNCTION(mysqli)
00911 {
00912        char buf[32];
00913 
00914        php_info_print_table_start();
00915        php_info_print_table_header(2, "MysqlI Support", "enabled");
00916        php_info_print_table_row(2, "Client API library version", mysql_get_client_info());
00917        snprintf(buf, sizeof(buf), "%ld", MyG(num_active_persistent));
00918        php_info_print_table_row(2, "Active Persistent Links", buf);
00919        snprintf(buf, sizeof(buf), "%ld", MyG(num_inactive_persistent));
00920        php_info_print_table_row(2, "Inactive Persistent Links", buf);
00921        snprintf(buf, sizeof(buf), "%ld", MyG(num_links));
00922        php_info_print_table_row(2, "Active Links", buf);
00923 #if !defined(MYSQLI_USE_MYSQLND)
00924        php_info_print_table_row(2, "Client API header version", MYSQL_SERVER_VERSION);
00925        php_info_print_table_row(2, "MYSQLI_SOCKET", MYSQL_UNIX_ADDR);
00926 #endif
00927        php_info_print_table_end();
00928 
00929        DISPLAY_INI_ENTRIES();
00930 }
00931 /* }}} */
00932 
00933 
00934 /* Dependancies */
00935 static const  zend_module_dep mysqli_deps[] = {
00936 #if defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1))
00937        ZEND_MOD_REQUIRED("spl")
00938 #endif
00939 #if defined(MYSQLI_USE_MYSQLND)
00940        ZEND_MOD_REQUIRED("mysqlnd")
00941 #endif
00942        ZEND_MOD_END
00943 };
00944 
00945 /* {{{ mysqli_module_entry
00946  */
00947 zend_module_entry mysqli_module_entry = {
00948 #if ZEND_MODULE_API_NO >= 20050922
00949        STANDARD_MODULE_HEADER_EX, NULL,
00950        mysqli_deps,
00951 #elif ZEND_MODULE_API_NO >= 20010901
00952        STANDARD_MODULE_HEADER,
00953 #endif
00954        "mysqli",
00955        mysqli_functions,
00956        PHP_MINIT(mysqli),
00957        PHP_MSHUTDOWN(mysqli),
00958        PHP_RINIT(mysqli),
00959        PHP_RSHUTDOWN(mysqli),
00960        PHP_MINFO(mysqli),
00961        "0.1", /* Replace with version number for your extension */
00962        PHP_MODULE_GLOBALS(mysqli),
00963        PHP_GINIT(mysqli),
00964        NULL,
00965        NULL,
00966        STANDARD_MODULE_PROPERTIES_EX
00967 };
00968 /* }}} */
00969 
00970 #ifdef COMPILE_DL_MYSQLI
00971 ZEND_GET_MODULE(mysqli)
00972 #endif
00973 
00974 
00975 /* {{{ mixed mysqli_stmt_construct()
00976 constructor for statement object.
00977 Parameters:
00978   object -> mysqli_stmt_init
00979   object, query -> mysqli_prepare
00980 */
00981 PHP_FUNCTION(mysqli_stmt_construct)
00982 {
00983        MY_MYSQL                    *mysql;
00984        zval                        *mysql_link;
00985        MY_STMT                            *stmt;
00986        MYSQLI_RESOURCE             *mysqli_resource;
00987        char                        *statement;
00988        int                                statement_len;
00989 
00990        switch (ZEND_NUM_ARGS())
00991        {
00992               case 1:  /* mysql_stmt_init */
00993                      if (zend_parse_parameters(1 TSRMLS_CC, "O", &mysql_link, mysqli_link_class_entry)==FAILURE) {
00994                             return;
00995                      }
00996                      MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
00997 
00998                      stmt = (MY_STMT *)ecalloc(1,sizeof(MY_STMT));
00999 
01000                      stmt->stmt = mysql_stmt_init(mysql->mysql);
01001               break;
01002               case 2:
01003                      if (zend_parse_parameters(2 TSRMLS_CC, "Os", &mysql_link, mysqli_link_class_entry, &statement, &statement_len)==FAILURE) {
01004                             return;
01005                      }
01006                      MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
01007 
01008                      stmt = (MY_STMT *)ecalloc(1,sizeof(MY_STMT));
01009 
01010                      if ((stmt->stmt = mysql_stmt_init(mysql->mysql))) {
01011                             mysql_stmt_prepare(stmt->stmt, (char *)statement, statement_len);
01012                      }
01013               break;
01014               default:
01015                      WRONG_PARAM_COUNT;
01016               break;
01017        }
01018 
01019        if (!stmt->stmt) {
01020               efree(stmt);
01021               RETURN_FALSE;
01022        }
01023 
01024        mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
01025        mysqli_resource->ptr = (void *)stmt;
01026        mysqli_resource->status = (ZEND_NUM_ARGS() == 1) ? MYSQLI_STATUS_INITIALIZED : MYSQLI_STATUS_VALID;
01027 
01028        ((mysqli_object *) zend_object_store_get_object(getThis() TSRMLS_CC))->ptr = mysqli_resource;
01029 }
01030 /* }}} */
01031 
01032 /* {{{ mixed mysqli_result_construct()
01033 constructor for result object.
01034 Parameters:
01035   object [, mode] -> mysqli_store/use_result
01036 */
01037 PHP_FUNCTION(mysqli_result_construct)
01038 {
01039        MY_MYSQL                    *mysql;
01040        MYSQL_RES                   *result = NULL;
01041        zval                        *mysql_link;
01042        MYSQLI_RESOURCE             *mysqli_resource;
01043        long                        resmode = MYSQLI_STORE_RESULT;
01044 
01045        switch (ZEND_NUM_ARGS()) {
01046               case 1:
01047                      if (zend_parse_parameters(1 TSRMLS_CC, "O", &mysql_link, mysqli_link_class_entry)==FAILURE) {
01048                             return;
01049                      }
01050                      break;
01051               case 2:
01052                      if (zend_parse_parameters(2 TSRMLS_CC, "Ol", &mysql_link, mysqli_link_class_entry, &resmode)==FAILURE) {
01053                             return;
01054                      }
01055                      break;
01056               default:
01057                      WRONG_PARAM_COUNT;
01058        }
01059 
01060        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
01061 
01062        switch (resmode) {
01063               case MYSQLI_STORE_RESULT:
01064                      result = mysql_store_result(mysql->mysql);
01065                      break;
01066               case MYSQLI_USE_RESULT:
01067                      result = mysql_use_result(mysql->mysql);
01068                      break;
01069               default:
01070                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid value for resultmode");
01071        }
01072 
01073        if (!result) {
01074               RETURN_FALSE;
01075        }
01076 
01077        mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
01078        mysqli_resource->ptr = (void *)result;
01079        mysqli_resource->status = MYSQLI_STATUS_VALID;
01080 
01081        ((mysqli_object *) zend_object_store_get_object(getThis() TSRMLS_CC))->ptr = mysqli_resource;
01082 
01083 }
01084 /* }}} */
01085 
01086 /* {{{ php_mysqli_fetch_into_hash
01087  */
01088 void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags, int into_object)
01089 {
01090        MYSQL_RES            *result;
01091        zval                 *mysql_result;
01092        long                 fetchtype;
01093        zval                 *ctor_params = NULL;
01094        zend_class_entry *ce = NULL;
01095 #if !defined(MYSQLI_USE_MYSQLND)
01096        unsigned int  i;
01097        MYSQL_FIELD          *fields;
01098        MYSQL_ROW            row;
01099        unsigned long *field_len;
01100        zend_bool magic_quotes_warning_sent = FALSE;
01101 #endif
01102 
01103        if (into_object) {
01104               char *class_name;
01105               int class_name_len;
01106 
01107               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) {
01108                      return;
01109               }
01110               if (ZEND_NUM_ARGS() < (getThis() ? 1 : 2)) {
01111                      ce = zend_standard_class_def;
01112               } else {
01113                      ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
01114               }
01115               if (!ce) {
01116                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not find class '%s'", class_name);
01117                      return;
01118               }
01119               fetchtype = MYSQLI_ASSOC;
01120        } else {
01121               if (override_flags) {
01122                      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
01123                             return;
01124                      }
01125                      fetchtype = override_flags;
01126               } else {
01127                      fetchtype = MYSQLI_BOTH;
01128                      if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &mysql_result, mysqli_result_class_entry, &fetchtype) == FAILURE) {
01129                             return;
01130                      }
01131               }
01132        }
01133        MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
01134 
01135        if (fetchtype < MYSQLI_ASSOC || fetchtype > MYSQLI_BOTH) {
01136               php_error_docref(NULL TSRMLS_CC, E_WARNING, "The result type should be either MYSQLI_NUM, MYSQLI_ASSOC or MYSQLI_BOTH");
01137               RETURN_FALSE;
01138        }
01139 
01140 #if !defined(MYSQLI_USE_MYSQLND)
01141        if (!(row = mysql_fetch_row(result))) {
01142               RETURN_NULL();
01143        }
01144 
01145        if (fetchtype & MYSQLI_ASSOC) {
01146               fields = mysql_fetch_fields(result);
01147        }
01148 
01149        array_init(return_value);
01150        field_len = mysql_fetch_lengths(result);
01151 
01152        for (i = 0; i < mysql_num_fields(result); i++) {
01153               if (row[i]) {
01154                      zval *res;
01155 
01156                      MAKE_STD_ZVAL(res);
01157 
01158 #if MYSQL_VERSION_ID > 50002
01159                      if (mysql_fetch_field_direct(result, i)->type == MYSQL_TYPE_BIT) {
01160                             my_ulonglong llval;
01161                             char tmp[22];
01162                             switch (field_len[i]) {
01163                                    case 8:llval = (my_ulonglong)  bit_uint8korr(row[i]);break;
01164                                    case 7:llval = (my_ulonglong)  bit_uint7korr(row[i]);break;
01165                                    case 6:llval = (my_ulonglong)  bit_uint6korr(row[i]);break;
01166                                    case 5:llval = (my_ulonglong)  bit_uint5korr(row[i]);break;
01167                                    case 4:llval = (my_ulonglong)  bit_uint4korr(row[i]);break;
01168                                    case 3:llval = (my_ulonglong)  bit_uint3korr(row[i]);break;
01169                                    case 2:llval = (my_ulonglong)  bit_uint2korr(row[i]);break;
01170                                    case 1:llval = (my_ulonglong)  uint1korr(row[i]);break;
01171                             }
01172                             /* even though lval is declared as unsigned, the value
01173                              * may be negative. Therefor we cannot use MYSQLI_LLU_SPEC and must
01174                              * use MYSQLI_LL_SPEC.
01175                              */
01176                             snprintf(tmp, sizeof(tmp), (mysql_fetch_field_direct(result, i)->flags & UNSIGNED_FLAG)? MYSQLI_LLU_SPEC : MYSQLI_LL_SPEC, llval);
01177                             ZVAL_STRING(res, tmp, 1);
01178                      } else
01179 #endif
01180                      {
01181 
01182                             /* check if we need magic quotes */
01183                             if (PG(magic_quotes_runtime)) {
01184                                    if (magic_quotes_warning_sent == FALSE) {
01185                                           magic_quotes_warning_sent = TRUE;
01186                                           php_error_docref(NULL TSRMLS_CC, E_WARNING, "magic_quotes_runtime are deprecated since PHP 5.3");
01187                                    }
01188                                    Z_TYPE_P(res) = IS_STRING;
01189                                    Z_STRVAL_P(res) = php_addslashes(row[i], field_len[i], &Z_STRLEN_P(res), 0 TSRMLS_CC);
01190                             } else {
01191                                    ZVAL_STRINGL(res, row[i], field_len[i], 1);
01192                             }
01193                      }
01194 
01195                      if (fetchtype & MYSQLI_NUM) {
01196                             add_index_zval(return_value, i, res);
01197                      }
01198                      if (fetchtype & MYSQLI_ASSOC) {
01199                             if (fetchtype & MYSQLI_NUM) {
01200                                    Z_ADDREF_P(res);
01201                             }
01202                             add_assoc_zval(return_value, fields[i].name, res);
01203                      }
01204               } else {
01205                      if (fetchtype & MYSQLI_NUM) {
01206                             add_index_null(return_value, i);
01207                      }
01208                      if (fetchtype & MYSQLI_ASSOC) {
01209                             add_assoc_null(return_value, fields[i].name);
01210                      }
01211               }
01212        }
01213 #else
01214        if (PG(magic_quotes_runtime)) {
01215               HashPosition pos_values;
01216               zval **entry_values;
01217               zval new_return_value;
01218               char * string_key;
01219               uint   string_key_len;
01220               ulong  num_key;
01221 
01222               mysqlnd_fetch_into(result, ((fetchtype & MYSQLI_NUM)? MYSQLND_FETCH_NUM:0) | ((fetchtype & MYSQLI_ASSOC)? MYSQLND_FETCH_ASSOC:0), &new_return_value, MYSQLND_MYSQLI);
01223               if (Z_TYPE(new_return_value) == IS_ARRAY) {
01224                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "magic_quotes_runtime are deprecated since PHP 5.3");
01225                      array_init(return_value);
01226                      zend_hash_internal_pointer_reset_ex(Z_ARRVAL(new_return_value), &pos_values);
01227                      while (zend_hash_get_current_data_ex(Z_ARRVAL(new_return_value), (void **)&entry_values, &pos_values) == SUCCESS) {
01228                             if (Z_TYPE_PP(entry_values) == IS_STRING) {
01229                                    int new_str_len;
01230                                    char * new_str = php_addslashes(Z_STRVAL_PP(entry_values), Z_STRLEN_PP(entry_values), &new_str_len, 0 TSRMLS_CC);
01231                                    switch (zend_hash_get_current_key_ex(Z_ARRVAL(new_return_value), &string_key, &string_key_len, &num_key, 0, &pos_values)) {
01232                                           case HASH_KEY_IS_LONG:
01233                                                  add_index_stringl(return_value, num_key, new_str, new_str_len, 0);
01234                                                  break;
01235                                           case HASH_KEY_IS_STRING:
01236                                                  add_assoc_stringl_ex(return_value, string_key, string_key_len, new_str, new_str_len, 0);
01237                                                  break;
01238                                    }
01239                             } else {
01240                                    zval_add_ref(entry_values);
01241                                    switch (zend_hash_get_current_key_ex(Z_ARRVAL(new_return_value), &string_key, &string_key_len, &num_key, 0, &pos_values)) {
01242                                           case HASH_KEY_IS_LONG:
01243                                                  add_index_zval(return_value, num_key, *entry_values);
01244                                                  break;
01245                                           case HASH_KEY_IS_STRING:
01246                                                  add_assoc_zval_ex(return_value, string_key, string_key_len, *entry_values);
01247                                                  break;
01248                                    }
01249                             }
01250                             zend_hash_move_forward_ex(Z_ARRVAL(new_return_value), &pos_values);
01251                      }
01252               } else {
01253                      RETVAL_NULL();
01254               }
01255               zval_dtor(&new_return_value);
01256        } else {
01257               mysqlnd_fetch_into(result, ((fetchtype & MYSQLI_NUM)? MYSQLND_FETCH_NUM:0) | ((fetchtype & MYSQLI_ASSOC)? MYSQLND_FETCH_ASSOC:0), return_value, MYSQLND_MYSQLI);
01258        }
01259 
01260 #endif
01261 
01262        if (into_object && Z_TYPE_P(return_value) != IS_NULL) {
01263               zval dataset = *return_value;
01264               zend_fcall_info fci;
01265               zend_fcall_info_cache fcc;
01266               zval *retval_ptr;
01267 
01268               object_and_properties_init(return_value, ce, NULL);
01269               zend_merge_properties(return_value, Z_ARRVAL(dataset), 1 TSRMLS_CC);
01270 
01271               if (ce->constructor) {
01272                      fci.size = sizeof(fci);
01273                      fci.function_table = &ce->function_table;
01274                      fci.function_name = NULL;
01275                      fci.symbol_table = NULL;
01276                      fci.object_ptr = return_value;
01277                      fci.retval_ptr_ptr = &retval_ptr;
01278                      if (ctor_params && Z_TYPE_P(ctor_params) != IS_NULL) {
01279                             if (Z_TYPE_P(ctor_params) == IS_ARRAY) {
01280                                    HashTable *params_ht = Z_ARRVAL_P(ctor_params);
01281                                    Bucket *p;
01282 
01283                                    fci.param_count = 0;
01284                                    fci.params = safe_emalloc(sizeof(zval*), params_ht->nNumOfElements, 0);
01285                                    p = params_ht->pListHead;
01286                                    while (p != NULL) {
01287                                           fci.params[fci.param_count++] = (zval**)p->pData;
01288                                           p = p->pListNext;
01289                                    }
01290                             } else {
01291                                    /* Two problems why we throw exceptions here: PHP is typeless
01292                                     * and hence passing one argument that's not an array could be
01293                                     * by mistake and the other way round is possible, too. The
01294                                     * single value is an array. Also we'd have to make that one
01295                                     * argument passed by reference.
01296                                     */
01297                                    zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Parameter ctor_params must be an array", 0 TSRMLS_CC);
01298                                    return;
01299                             }
01300                      } else {
01301                             fci.param_count = 0;
01302                             fci.params = NULL;
01303                      }
01304                      fci.no_separation = 1;
01305 
01306                      fcc.initialized = 1;
01307                      fcc.function_handler = ce->constructor;
01308                      fcc.calling_scope = EG(scope);
01309                      fcc.called_scope = Z_OBJCE_P(return_value);
01310                      fcc.object_ptr = return_value;
01311 
01312                      if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
01313                             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);
01314                      } else {
01315                             if (retval_ptr) {
01316                                    zval_ptr_dtor(&retval_ptr);
01317                             }
01318                      }
01319                      if (fci.params) {
01320                             efree(fci.params);
01321                      }
01322               } else if (ctor_params) {
01323                      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);
01324               }
01325        }
01326 }
01327 /* }}} */
01328 
01329 
01330 #if !defined(MYSQLI_USE_MYSQLND)
01331 
01332 #define ALLOC_CALLBACK_ARGS(a, b, c)\
01333 if (c) {\
01334        a = (zval ***)safe_emalloc(c, sizeof(zval **), 0);\
01335        for (i = b; i < c; i++) {\
01336               a[i] = emalloc(sizeof(zval *));\
01337               MAKE_STD_ZVAL(*a[i]);\
01338        }\
01339 }
01340 
01341 #define FREE_CALLBACK_ARGS(a, b, c)\
01342 if (a) {\
01343        for (i=b; i < c; i++) {\
01344               zval_ptr_dtor(a[i]);\
01345               efree(a[i]);\
01346        }\
01347        efree(a);\
01348 }
01349 
01350 #define LOCAL_INFILE_ERROR_MSG(source,dest)\
01351        memset(source, 0, LOCAL_INFILE_ERROR_LEN);\
01352        memcpy(source, dest, MIN(strlen(dest), LOCAL_INFILE_ERROR_LEN-1));\
01353        php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", dest);
01354 
01355 
01356 /* {{{ php_local_infile_init
01357  */
01358 static int php_local_infile_init(void **ptr, const char *filename, void *userdata)
01359 {
01360        mysqli_local_infile                *data;
01361        MY_MYSQL                                  *mysql;
01362        php_stream_context                 *context = NULL;
01363 
01364        TSRMLS_FETCH();
01365 
01366        /* save pointer to MY_MYSQL structure (userdata) */
01367        if (!(*ptr= data= ((mysqli_local_infile *)calloc(1, sizeof(mysqli_local_infile))))) {
01368               return 1;
01369        }
01370 
01371        if (!(mysql = (MY_MYSQL *)userdata)) {
01372               LOCAL_INFILE_ERROR_MSG(data->error_msg, ER(CR_UNKNOWN_ERROR));
01373               return 1;
01374        }
01375 
01376        /* check open_basedir */
01377        if (PG(open_basedir)) {
01378               if (php_check_open_basedir_ex(filename, 0 TSRMLS_CC) == -1) {
01379                      LOCAL_INFILE_ERROR_MSG(data->error_msg, "open_basedir restriction in effect. Unable to open file");
01380                      return 1;
01381               }
01382        }
01383 
01384        mysql->li_stream = php_stream_open_wrapper_ex((char *)filename, "r", 0, NULL, context);
01385 
01386        if (mysql->li_stream == NULL) {
01387               snprintf((char *)data->error_msg, sizeof(data->error_msg), "Can't find file '%-.64s'.", filename);
01388               return 1;
01389        }
01390 
01391        data->userdata = mysql;
01392 
01393        return 0;
01394 }
01395 /* }}} */
01396 
01397 /* {{{ int php_local_infile_read */
01398 static int php_local_infile_read(void *ptr, char *buf, uint buf_len)
01399 {
01400        mysqli_local_infile                *data;
01401        MY_MYSQL                                  *mysql;
01402        zval                                      ***callback_args;
01403        zval                                      *retval;
01404        zval                                      *fp;
01405        int                                              argc = 4;
01406        int                                              i;
01407        long                                      rc;
01408 
01409        TSRMLS_FETCH();
01410 
01411        data= (mysqli_local_infile *)ptr;
01412        mysql = data->userdata;
01413 
01414        /* default processing */
01415        if (!mysql->li_read) {
01416               int count = (int)php_stream_read(mysql->li_stream, buf, buf_len);
01417 
01418               if (count < 0) {
01419                      LOCAL_INFILE_ERROR_MSG(data->error_msg, ER(2));
01420               }
01421 
01422               return count;
01423        }
01424 
01425        ALLOC_CALLBACK_ARGS(callback_args, 1, argc);
01426 
01427        /* set parameters: filepointer, buffer, buffer_len, errormsg */
01428 
01429        MAKE_STD_ZVAL(fp);
01430        php_stream_to_zval(mysql->li_stream, fp);
01431        callback_args[0] = &fp;
01432        ZVAL_STRING(*callback_args[1], "", 1);
01433        ZVAL_LONG(*callback_args[2], buf_len);
01434        ZVAL_STRING(*callback_args[3], "", 1);
01435 
01436        if (call_user_function_ex(EG(function_table),
01437                                           NULL,
01438                                           mysql->li_read,
01439                                           &retval,
01440                                           argc,
01441                                           callback_args,
01442                                           0,
01443                                           NULL TSRMLS_CC) == SUCCESS) {
01444 
01445               rc = Z_LVAL_P(retval);
01446               zval_ptr_dtor(&retval);
01447 
01448               if (rc > 0) {
01449                      if (rc >= 0 && rc != Z_STRLEN_P(*callback_args[1])) {
01450                             LOCAL_INFILE_ERROR_MSG(data->error_msg,
01451                                                  "Mismatch between the return value of the callback and the content "
01452                                                  "length of the buffer.");
01453                             rc = -1;
01454                      } else if (rc > buf_len) {
01455                             /* check buffer overflow */
01456                             LOCAL_INFILE_ERROR_MSG(data->error_msg, "Too much data returned");
01457                             rc = -1;
01458                      } else {
01459                             memcpy(buf, Z_STRVAL_P(*callback_args[1]), MIN(rc, Z_STRLEN_P(*callback_args[1])));
01460                      }
01461               } else if (rc < 0) {
01462                      LOCAL_INFILE_ERROR_MSG(data->error_msg, Z_STRVAL_P(*callback_args[3]));
01463               }
01464        } else {
01465               LOCAL_INFILE_ERROR_MSG(data->error_msg, "Can't execute load data local init callback function");
01466               rc = -1;
01467        }
01468        /*
01469          If the (ab)user has closed the file handle we should
01470          not try to use it anymore or even close it
01471        */
01472        if (!zend_rsrc_list_get_rsrc_type(Z_LVAL_P(fp) TSRMLS_CC)) {
01473               LOCAL_INFILE_ERROR_MSG(data->error_msg, "File handle closed");
01474               rc = -1;
01475               /* Thus the end handler won't try to free already freed memory */
01476               mysql->li_stream = NULL;
01477        }
01478 
01479        FREE_CALLBACK_ARGS(callback_args, 1, argc);
01480        efree(fp);
01481        return rc;
01482 }
01483 /* }}} */
01484 
01485 /* {{{ php_local_infile_error
01486  */
01487 static int php_local_infile_error(void *ptr, char *error_msg, uint error_msg_len)
01488 {
01489        mysqli_local_infile *data = (mysqli_local_infile *) ptr;
01490 
01491        if (data) {
01492               strlcpy(error_msg, data->error_msg, error_msg_len);
01493               return 2000;
01494        }
01495        strlcpy(error_msg, ER(CR_OUT_OF_MEMORY), error_msg_len);
01496        return CR_OUT_OF_MEMORY;
01497 }
01498 /* }}} */
01499 
01500 /* {{{ php_local_infile_end
01501  */
01502 static void php_local_infile_end(void *ptr)
01503 {
01504        mysqli_local_infile         *data;
01505        MY_MYSQL                           *mysql;
01506 
01507        TSRMLS_FETCH();
01508 
01509        data= (mysqli_local_infile *)ptr;
01510 
01511        if (!data || !(mysql = data->userdata)) {
01512               if (data) {
01513                      free(data);
01514               }
01515               return;
01516        }
01517 
01518        if (mysql->li_stream) {
01519               php_stream_close(mysql->li_stream);
01520        }
01521        free(data);
01522        return;
01523 }
01524 /* }}} */
01525 
01526 
01527 /* {{{ void php_set_local_infile_handler_default
01528 */
01529 void php_set_local_infile_handler_default(MY_MYSQL *mysql) {
01530        /* register internal callback functions */
01531        mysql_set_local_infile_handler(mysql->mysql, &php_local_infile_init, &php_local_infile_read,
01532                             &php_local_infile_end, &php_local_infile_error, (void *)mysql);
01533        if (mysql->li_read) {
01534               zval_ptr_dtor(&mysql->li_read);
01535               mysql->li_read = NULL;
01536        }
01537 }
01538 /* }}} */
01539 #endif
01540 
01541 /*
01542  * Local variables:
01543  * tab-width: 4
01544  * c-basic-offset: 4
01545  * End:
01546  * vim600: noet sw=4 ts=4 fdm=marker
01547  * vim<600: noet sw=4 ts=4
01548  */