/* Destructor for mysqli entries in free_links/used_links */ void php_mysqli_dtor_p_elements(void *data) { MYSQL *mysql = (MYSQL *) data; TSRMLS_FETCH(); mysqli_close(mysql, MYSQLI_CLOSE_IMPLICIT); }
void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_real_connect, zend_bool in_ctor) /* {{{ */ { MY_MYSQL *mysql = NULL; MYSQLI_RESOURCE *mysqli_resource = NULL; zval *object = getThis(); char *hostname = NULL, *username=NULL, *passwd=NULL, *dbname=NULL, *socket=NULL; size_t hostname_len = 0, username_len = 0, passwd_len = 0, dbname_len = 0, socket_len = 0; zend_bool persistent = FALSE; zend_long port = 0, flags = 0; zend_string *hash_key = NULL; zend_bool new_connection = FALSE; zend_resource *le; mysqli_plist_entry *plist = NULL; zend_bool self_alloced = 0; #if !defined(MYSQL_USE_MYSQLND) if ((MYSQL_VERSION_ID / 100) != (mysql_get_client_version() / 100)) { php_error_docref(NULL, E_WARNING, "Headers and client library minor version mismatch. Headers:%d Library:%ld", MYSQL_VERSION_ID, mysql_get_client_version()); } #endif if (getThis() && !ZEND_NUM_ARGS() && in_ctor) { php_mysqli_init(INTERNAL_FUNCTION_PARAM_PASSTHRU, in_ctor); return; } hostname = username = dbname = passwd = socket = NULL; if (!is_real_connect) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "|ssssls", &hostname, &hostname_len, &username, &username_len, &passwd, &passwd_len, &dbname, &dbname_len, &port, &socket, &socket_len) == FAILURE) { return; } if (object && instanceof_function(Z_OBJCE_P(object), mysqli_link_class_entry)) { mysqli_resource = (Z_MYSQLI_P(object))->ptr; if (mysqli_resource && mysqli_resource->ptr) { mysql = (MY_MYSQL*) mysqli_resource->ptr; } } if (!mysql) { mysql = (MY_MYSQL *) ecalloc(1, sizeof(MY_MYSQL)); self_alloced = 1; } flags |= CLIENT_MULTI_RESULTS; /* needed for mysql_multi_query() */ } else { /* We have flags too */ if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|sssslsl", &object, mysqli_link_class_entry, &hostname, &hostname_len, &username, &username_len, &passwd, &passwd_len, &dbname, &dbname_len, &port, &socket, &socket_len, &flags) == FAILURE) { return; } mysqli_resource = (Z_MYSQLI_P(object))->ptr; MYSQLI_FETCH_RESOURCE_CONN(mysql, object, MYSQLI_STATUS_INITIALIZED); /* set some required options */ flags |= CLIENT_MULTI_RESULTS; /* needed for mysql_multi_query() */ /* remove some insecure options */ flags &= ~CLIENT_MULTI_STATEMENTS; /* don't allow multi_queries via connect parameter */ #if !defined(MYSQLI_USE_MYSQLND) if (PG(open_basedir) && PG(open_basedir)[0] != '\0') { flags &= ~CLIENT_LOCAL_FILES; } #endif } if (!socket_len || !socket) { socket = MyG(default_socket); } if (!port){ port = MyG(default_port); } if (!passwd) { passwd = MyG(default_pw); passwd_len = strlen(SAFE_STR(passwd)); } if (!username){ username = MyG(default_user); } if (!hostname || !hostname_len) { hostname = MyG(default_host); } if (mysql->mysql && mysqli_resource && (mysqli_resource->status > MYSQLI_STATUS_INITIALIZED)) { /* already connected, we should close the connection */ php_mysqli_close(mysql, MYSQLI_CLOSE_IMPLICIT, mysqli_resource->status); } if (strlen(SAFE_STR(hostname)) > 2 && !strncasecmp(hostname, "p:", 2)) { hostname += 2; if (!MyG(allow_persistent)) { php_error_docref(NULL, E_WARNING, "Persistent connections are disabled. Downgrading to normal"); } else { mysql->persistent = persistent = TRUE; hash_key = strpprintf(0, "mysqli_%s_%s" ZEND_LONG_FMT "%s%s%s", SAFE_STR(hostname), SAFE_STR(socket), port, SAFE_STR(username), SAFE_STR(dbname), SAFE_STR(passwd)); mysql->hash_key = hash_key; /* check if we can reuse existing connection ... */ if ((le = zend_hash_find_ptr(&EG(persistent_list), hash_key)) != NULL) { if (le->type == php_le_pmysqli()) { plist = (mysqli_plist_entry *) le->ptr; do { if (zend_ptr_stack_num_elements(&plist->free_links)) { mysql->mysql = zend_ptr_stack_pop(&plist->free_links); MyG(num_inactive_persistent)--; /* reset variables */ #ifndef MYSQLI_NO_CHANGE_USER_ON_PCONNECT if (!mysqli_change_user_silent(mysql->mysql, username, passwd, dbname, passwd_len)) { #else if (!mysql_ping(mysql->mysql)) { #endif #ifdef MYSQLI_USE_MYSQLND mysqlnd_restart_psession(mysql->mysql); #endif MyG(num_active_persistent)++; /* clear error */ php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql)); goto end; } else { mysqli_close(mysql->mysql, MYSQLI_CLOSE_IMPLICIT); mysql->mysql = NULL; } } } while (0); } } else { plist = calloc(1, sizeof(mysqli_plist_entry)); zend_ptr_stack_init_ex(&plist->free_links, 1); zend_register_persistent_resource(ZSTR_VAL(hash_key), ZSTR_LEN(hash_key), plist, php_le_pmysqli()); } }