diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c index 612239527e3c7..8eaffadf29301 100644 --- a/ext/mysqli/mysqli.c +++ b/ext/mysqli/mysqli.c @@ -218,11 +218,13 @@ static void mysqli_link_free_storage(zend_object *object) if (my_res && my_res->ptr) { MY_MYSQL *mysql = (MY_MYSQL *)my_res->ptr; - if (mysql->mysql) { - php_mysqli_close(mysql, MYSQLI_CLOSE_EXPLICIT, my_res->status); + if(!mysql->disable_cleanup) { + if (mysql->mysql) { + php_mysqli_close(mysql, MYSQLI_CLOSE_EXPLICIT, my_res->status); + } + php_clear_mysql(mysql); + efree(mysql); } - php_clear_mysql(mysql); - efree(mysql); my_res->status = MYSQLI_STATUS_UNKNOWN; } mysqli_objects_free_storage(object); diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index 96cad0dc5ffcd..fb85e4e1c07e2 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -804,6 +804,25 @@ PHP_FUNCTION(mysqli_debug) } /* }}} */ +/* {{{ proto void mysqli_disable_cleanup(object link, bool value) + Turn link cleanup on or off when the object is destroyed +*/ +PHP_FUNCTION(mysqli_disable_cleanup) +{ + MY_MYSQL *mysql; + zval *mysql_link; + zend_bool value; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ob", &mysql_link, mysqli_link_class_entry, &value) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID); + mysql->disable_cleanup = value; + RETURN_TRUE; +} +/* }}} */ + + /* {{{ proto bool mysqli_dump_debug_info(object link) */ PHP_FUNCTION(mysqli_dump_debug_info) @@ -1510,6 +1529,7 @@ void php_mysqli_init(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_method) mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); mysqli_resource->ptr = (void *)mysql; mysqli_resource->status = MYSQLI_STATUS_INITIALIZED; + mysql->disable_cleanup = FALSE; if (!is_method) { MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_link_class_entry); diff --git a/ext/mysqli/mysqli_fe.c b/ext/mysqli/mysqli_fe.c index f17f009830f6a..13fe5ad50da0f 100644 --- a/ext/mysqli/mysqli_fe.c +++ b/ext/mysqli/mysqli_fe.c @@ -217,6 +217,11 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_debug, 0, 0, 1) ZEND_ARG_INFO(0, debug_options) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_disable_cleanup, 0, 0, 2) + MYSQLI_ZEND_ARG_OBJ_INFO_LINK() + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_result_and_fieldnr, 0, 0, 2) MYSQLI_ZEND_ARG_OBJ_INFO_RESULT() ZEND_ARG_INFO(0, field_nr) @@ -401,7 +406,6 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_no_options, 0, 0, 0) ZEND_END_ARG_INFO() - /* {{{ mysqli_functions[] * * Every user visible function must have an entry in mysqli_functions[]. @@ -420,6 +424,7 @@ const zend_function_entry mysqli_functions[] = { PHP_FE(mysqli_data_seek, arginfo_mysqli_data_seek) PHP_FE(mysqli_dump_debug_info, arginfo_mysqli_only_link) PHP_FE(mysqli_debug, arginfo_mysqli_debug) + PHP_FE(mysqli_disable_cleanup, arginfo_mysqli_disable_cleanup) PHP_FE(mysqli_errno, arginfo_mysqli_only_link) PHP_FE(mysqli_error, arginfo_mysqli_only_link) PHP_FE(mysqli_error_list, arginfo_mysqli_only_link) @@ -549,6 +554,7 @@ const zend_function_entry mysqli_link_methods[] = { PHP_FALIAS(connect, mysqli_connect, arginfo_mysqli_connect) PHP_FALIAS(dump_debug_info, mysqli_dump_debug_info, arginfo_mysqli_no_params) PHP_FALIAS(debug, mysqli_debug, arginfo_mysqli_debug) + PHP_FALIAS(disable_cleanup, mysqli_disable_cleanup, arginfo_mysqli_disable_cleanup) #ifdef HAVE_MYSQLI_GET_CHARSET PHP_FALIAS(get_charset, mysqli_get_charset, arginfo_mysqli_no_params) #endif diff --git a/ext/mysqli/mysqli_fe.h b/ext/mysqli/mysqli_fe.h index c6e8293d1af07..8c18050c30e89 100644 --- a/ext/mysqli/mysqli_fe.h +++ b/ext/mysqli/mysqli_fe.h @@ -34,6 +34,7 @@ PHP_FUNCTION(mysqli_connect_errno); PHP_FUNCTION(mysqli_connect_error); PHP_FUNCTION(mysqli_data_seek); PHP_FUNCTION(mysqli_debug); +PHP_FUNCTION(mysqli_disable_cleanup); PHP_FUNCTION(mysqli_dump_debug_info); PHP_FUNCTION(mysqli_errno); PHP_FUNCTION(mysqli_error); diff --git a/ext/mysqli/php_mysqli_structs.h b/ext/mysqli/php_mysqli_structs.h index 93fbc15e91b0f..e730aac077700 100644 --- a/ext/mysqli/php_mysqli_structs.h +++ b/ext/mysqli/php_mysqli_structs.h @@ -123,6 +123,7 @@ typedef struct { php_stream *li_stream; unsigned int multi_query; zend_bool persistent; + zend_bool disable_cleanup; /* Disable dtor cleanup */ #if defined(MYSQLI_USE_MYSQLND) int async_result_fetch_type; #endif diff --git a/ext/mysqli/tests/mysqli_class_mysqli_interface.phpt b/ext/mysqli/tests/mysqli_class_mysqli_interface.phpt index dfefb9098c175..9160f7e8f3d91 100644 --- a/ext/mysqli/tests/mysqli_class_mysqli_interface.phpt +++ b/ext/mysqli/tests/mysqli_class_mysqli_interface.phpt @@ -28,6 +28,7 @@ require_once('skipifconnectfailure.inc'); 'commit' => true, 'connect' => true, 'dump_debug_info' => true, + 'disable_cleanup' => true, 'escape_string' => true, 'get_charset' => true, 'get_client_info' => true, diff --git a/ext/mysqli/tests/mysqli_class_mysqli_reflection.phpt b/ext/mysqli/tests/mysqli_class_mysqli_reflection.phpt index 47beb1d79b3e5..4a2b6ae48fddf 100644 --- a/ext/mysqli/tests/mysqli_class_mysqli_reflection.phpt +++ b/ext/mysqli/tests/mysqli_class_mysqli_reflection.phpt @@ -384,6 +384,36 @@ isPassedByReference: no isOptional: no isDefaultValueAvailable: no +Inspecting method 'disable_cleanup' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 1 +Number of Parameters: 2 +Number of Required Parameters: 2 + +Inspecting parameter 'link' of method 'disable_cleanup' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: no +isDefaultValueAvailable: no + +Inspecting parameter 'value' of method 'disable_cleanup' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: no +isDefaultValueAvailable: no + Inspecting method 'dump_debug_info' isFinal: no isAbstract: no