diff options
| author | Andrey Hristov <andrey@php.net> | 2007-10-05 21:23:56 +0000 | 
|---|---|---|
| committer | Andrey Hristov <andrey@php.net> | 2007-10-05 21:23:56 +0000 | 
| commit | 8b9b553aa264d3c0afe611f49499e787004983c7 (patch) | |
| tree | 840ea2b1127ec97a63f36ffda689a1a1fe5fb975 /ext/mysqli/mysqli_api.c | |
| parent | 9f9495a48483aac9f6bc92ceea5841a8d243e2aa (diff) | |
| download | php-git-8b9b553aa264d3c0afe611f49499e787004983c7.tar.gz | |
Import mysqlnd
Patch ext/mysql and ext/mysqli to support mysqlnd
Diffstat (limited to 'ext/mysqli/mysqli_api.c')
| -rw-r--r-- | ext/mysqli/mysqli_api.c | 1043 | 
1 files changed, 629 insertions, 414 deletions
diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index fd01ba9ffa..5e55be7d51 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -12,7 +12,9 @@    | obtain it through the world-wide-web, please send a note to          |    | license@php.net so we can mail you a copy immediately.               |    +----------------------------------------------------------------------+ -  | Author: Georg Richter <georg@php.net>                                | +  | Authors: Georg Richter <georg@php.net>                               | +  |          Andrey Hristov <andrey@php.net>                             | +  |          Ulf Wendel <uw@php.net>                                     |    +----------------------------------------------------------------------+    $Id$  @@ -26,8 +28,9 @@  #include "php.h"  #include "php_ini.h" +#include "php_globals.h"  #include "ext/standard/info.h" -#include "php_mysqli.h" +#include "php_mysqli_structs.h"  /* {{{ proto mixed mysqli_affected_rows(object link)     Get number of affected rows in previous MySQL operation */ @@ -51,16 +54,17 @@ PHP_FUNCTION(mysqli_affected_rows)  }  /* }}} */ +  /* {{{ proto bool mysqli_autocommit(object link, bool mode)     Turn auto commit on or of */  PHP_FUNCTION(mysqli_autocommit)  { -	MY_MYSQL 		*mysql; -	zval  			*mysql_link; -	zend_bool		automode; +	MY_MYSQL	*mysql; +	zval		*mysql_link; +	zend_bool	automode;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ob", &mysql_link, mysqli_link_class_entry, &automode) == FAILURE) { -		return;	 +		return;  	}  	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); @@ -71,83 +75,38 @@ PHP_FUNCTION(mysqli_autocommit)  }  /* }}} */ -/* {{{ proto bool mysqli_stmt_bind_param(object stmt, string types, mixed variable [,mixed,....]) -   Bind variables to a prepared statement as parameters */ -PHP_FUNCTION(mysqli_stmt_bind_param) +/* {{{ mysqli_stmt_bind_param_do_bind */ +#ifndef HAVE_MYSQLND +static +int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int argc, unsigned int num_vars, +								   zval ***args, unsigned int start, const char * const types TSRMLS_DC)  { -	zval 			***args; -	int     		argc = ZEND_NUM_ARGS(); -	int 	    	i; -	int				num_vars; -	int				start = 2; -	int				ofs; -	MY_STMT			*stmt; -	zval 			*mysql_stmt; +	int				i, ofs;  	MYSQL_BIND		*bind; -	char			*types; -	int				typelen;  	unsigned long	rc; -	/* calculate and check number of parameters */ -	if (argc < 2) { -		/* there has to be at least one pair */ -		WRONG_PARAM_COUNT; -	} - -	if (zend_parse_method_parameters((getThis()) ? 1:2 TSRMLS_CC, getThis(), "Os", &mysql_stmt, mysqli_stmt_class_entry, &types, &typelen) == FAILURE) { -		return;	 -	} - -	MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt", MYSQLI_STATUS_VALID);  - -	num_vars = argc - 1; -	if (getThis()) { -		start = 1; -	} else { -		/* ignore handle parameter in procedural interface*/ -		--num_vars; -	} - -	if (typelen != argc - start) { -		/* number of bind variables doesn't match number of elements in type definition string */ -		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of elements in type definition string doesn't match number of bind variables"); -		RETURN_FALSE; -	} - -	if (typelen != stmt->stmt->param_count) { -		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of variables doesn't match number of parameters in prepared statement"); -		RETURN_FALSE; -	} -  	/* prevent leak if variables are already bound */  	if (stmt->param.var_cnt) {  		php_free_stmt_bind_buffer(stmt->param, FETCH_SIMPLE);  	} -	args = (zval ***)safe_emalloc(argc, sizeof(zval **), 0); - -	if (zend_get_parameters_array_ex(argc, args) == FAILURE) { -		efree(args); -		WRONG_PARAM_COUNT; -	} -  	stmt->param.is_null = ecalloc(num_vars, sizeof(char)); -	bind = (MYSQL_BIND *)ecalloc(num_vars, sizeof(MYSQL_BIND)); +	bind = (MYSQL_BIND *) ecalloc(num_vars, sizeof(MYSQL_BIND));  	ofs = 0; -	for (i=start; i < argc; i++) { +	for (i = start; i < argc; i++) {  		/* set specified type */  		switch (types[ofs]) {  			case 'd': /* Double */  				bind[ofs].buffer_type = MYSQL_TYPE_DOUBLE; -				bind[ofs].buffer = (char*)&Z_DVAL_PP(args[i]); +				bind[ofs].buffer = &Z_DVAL_PP(args[i]);  				bind[ofs].is_null = &stmt->param.is_null[ofs];  				break;  			case 'i': /* Integer */ -				bind[ofs].buffer_type = MYSQL_TYPE_LONG; -				bind[ofs].buffer = (char*)&Z_LVAL_PP(args[i]); +				bind[ofs].buffer_type = (sizeof(long) > 4) ? MYSQL_TYPE_LONGLONG : MYSQL_TYPE_LONG; +				bind[ofs].buffer = &Z_LVAL_PP(args[i]);  				bind[ofs].is_null = &stmt->param.is_null[ofs];  				break; @@ -164,85 +123,162 @@ PHP_FUNCTION(mysqli_stmt_bind_param)  			default:  				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Undefined fieldtype %c (parameter %d)", types[ofs], i+1); -				RETVAL_FALSE; -				goto end; +				rc = 1; +				goto end_1;  		}  		ofs++;  	}  	rc = mysql_stmt_bind_param(stmt->stmt, bind); -	MYSQLI_REPORT_STMT_ERROR(stmt->stmt); +end_1:  	if (rc) { -		RETVAL_FALSE; -		goto end; +		efree(stmt->param.is_null); +	} else { +		stmt->param.var_cnt = num_vars; +		stmt->param.vars = (zval **)safe_emalloc(num_vars, sizeof(zval), 0); +		for (i = 0; i < num_vars; i++) { +			if (bind[i].buffer_type  != MYSQL_TYPE_LONG_BLOB) { +				ZVAL_ADDREF(*args[i+start]); +				stmt->param.vars[i] = *args[i+start]; +			} else { +				stmt->param.vars[i] = NULL; +			} +		}  	} +	efree(bind); -	stmt->param.var_cnt = num_vars; -	stmt->param.vars = (zval **)safe_emalloc(num_vars, sizeof(zval), 0); -	for (i = 0; i < num_vars; i++) { -		if (bind[i].buffer_type  != MYSQL_TYPE_LONG_BLOB) { -			ZVAL_ADDREF(*args[i+start]); -			stmt->param.vars[i] = *args[i+start]; -		} else { -			stmt->param.vars[i] = NULL; +	return rc; +} +#else +static +int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int argc, unsigned int num_vars, +								   zval ***args, unsigned int start, const char * const types TSRMLS_DC) +{ +	int					i; +	MYSQLND_PARAM_BIND	*params; +	enum_func_status	ret = FAIL; + +	/* If no params -> skip binding and return directly */ +	if (argc == start) { +		return PASS; +	} +	params = emalloc((argc - start) * sizeof(MYSQLND_PARAM_BIND)); +	for (i = 0; i < (argc - start); i++) { +		zend_uchar type; +		switch (types[i]) { +			case 'd': /* Double */ +				type = MYSQL_TYPE_DOUBLE; +				break; +			case 'i': /* Integer */ +#if SIZEOF_LONG==8 +				type = MYSQL_TYPE_LONGLONG; +#elif SIZEOF_LONG==4 +				type = MYSQL_TYPE_LONG; +#endif +				break; +			case 'b': /* Blob (send data) */ +				type = MYSQL_TYPE_LONG_BLOB; +				break; +			case 's': /* string */ +				type = MYSQL_TYPE_VAR_STRING; +				break; +			default: +				/* We count parameters from 1 */ +				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Undefined fieldtype %c (parameter %d)", types[i], i + start + 1); +				ret = FAIL; +				efree(params); +				goto end;  		} +		params[i].zv = *(args[i + start]); +		params[i].type = type;  	} -	RETVAL_TRUE; +	ret = mysqlnd_stmt_bind_param(stmt->stmt, params); +  end: -	efree(args); -	efree(bind); +	return ret;  } +#endif  /* }}} */ -/* {{{ proto bool mysqli_stmt_bind_result(object stmt, mixed var, [,mixed, ...]) -   Bind variables to a prepared statement for result storage */ - -/* TODO: -   do_alloca, free_alloca -*/ - -PHP_FUNCTION(mysqli_stmt_bind_result) +/* {{{ proto bool mysqli_stmt_bind_param(object stmt, string types, mixed variable [,mixed,....]) U +   Bind variables to a prepared statement as parameters */ +PHP_FUNCTION(mysqli_stmt_bind_param)  { -	zval 		***args; -	int     	argc = ZEND_NUM_ARGS(); -	int     	i; -	int			start = 1; -	int			var_cnt; -	int			ofs; -	long		col_type; -	ulong		rc; -	MY_STMT 	*stmt; -	zval 		*mysql_stmt; -	MYSQL_BIND 	*bind; +	zval			***args; +	int				argc = ZEND_NUM_ARGS(); +	int				num_vars; +	int				start = 2; +	MY_STMT			*stmt; +	zval			*mysql_stmt; +	char			*types; +	int				types_len; +	unsigned long	rc; -	if (getThis()) { -		start = 0; +	/* calculate and check number of parameters */ +	if (argc < 2) { +		/* there has to be at least one pair */ +		WRONG_PARAM_COUNT;  	} -	if (zend_parse_method_parameters((getThis()) ? 0:1 TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { +	if (zend_parse_method_parameters((getThis()) ? 1:2 TSRMLS_CC, getThis(), "Os", &mysql_stmt, mysqli_stmt_class_entry, +									&types, &types_len) == FAILURE) {  		return;	  	} -	MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt", MYSQLI_STATUS_VALID);  +	MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt", MYSQLI_STATUS_VALID); -	if (argc < (getThis() ? 1 : 2))  { -		WRONG_PARAM_COUNT; +	num_vars = argc - 1; +	if (getThis()) { +		start = 1; +	} else { +		/* ignore handle parameter in procedural interface*/ +		--num_vars; +	} +	if (!types_len) { +		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid type or no types specified"); +		RETURN_FALSE; +	} + +	if (types_len != argc - start) { +		/* number of bind variables doesn't match number of elements in type definition string */ +		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of elements in type definition string doesn't match number of bind variables"); +		RETURN_FALSE; +	} + +	if (types_len != mysql_stmt_param_count(stmt->stmt)) { +		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of variables doesn't match number of parameters in prepared statement"); +		RETURN_FALSE;  	}  	args = (zval ***)safe_emalloc(argc, sizeof(zval **), 0);  	if (zend_get_parameters_array_ex(argc, args) == FAILURE) { -		efree(args); -		WRONG_PARAM_COUNT; +		zend_wrong_param_count(TSRMLS_C);  +		rc = 1; +	} else { +		rc = mysqli_stmt_bind_param_do_bind(stmt, argc, num_vars, args, start, types TSRMLS_CC); +		MYSQLI_REPORT_STMT_ERROR(stmt->stmt);  	} -	var_cnt = argc - start; +	efree(args); -	if (var_cnt != mysql_stmt_field_count(stmt->stmt)) { -		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of bind variables doesn't match number of fields in prepared statement"); -		efree(args); -		RETURN_FALSE; -	} +	RETURN_BOOL(!rc); +} +/* }}} */ + +/* {{{ mysqli_stmt_bind_result_do_bind */ +#ifndef HAVE_MYSQLND +/* TODO: +   do_alloca, free_alloca +*/ +static int +mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval ***args, unsigned int argc, unsigned int start TSRMLS_DC) +{ +	MYSQL_BIND	*bind; +	int			i, ofs; +	int			var_cnt = argc - start; +	long		col_type; +	ulong		rc;  	/* prevent leak if variables are already bound */  	if (stmt->result.var_cnt) { @@ -268,7 +304,7 @@ PHP_FUNCTION(mysqli_stmt_bind_result)  				convert_to_double_ex(args[i]);  				stmt->result.buf[ofs].type = IS_DOUBLE;  				stmt->result.buf[ofs].buflen = sizeof(double); -				 +  				/* allocate buffer for double */  				stmt->result.buf[ofs].val = (char *)emalloc(sizeof(double));  				bind[ofs].buffer_type = MYSQL_TYPE_DOUBLE; @@ -305,7 +341,7 @@ PHP_FUNCTION(mysqli_stmt_bind_result)  				break;  			case MYSQL_TYPE_LONGLONG: -#if MYSQL_VERSION_ID > 50002 +#if MYSQL_VERSION_ID > 50002 || defined(HAVE_MYSQLND)  			case MYSQL_TYPE_BIT:  #endif  				stmt->result.buf[ofs].type = IS_STRING;  @@ -324,8 +360,8 @@ PHP_FUNCTION(mysqli_stmt_bind_result)  			case MYSQL_TYPE_NEWDATE:  			case MYSQL_TYPE_VAR_STRING:  			case MYSQL_TYPE_STRING: -			case MYSQL_TYPE_BLOB:  			case MYSQL_TYPE_TINY_BLOB: +			case MYSQL_TYPE_BLOB:  			case MYSQL_TYPE_MEDIUM_BLOB:  			case MYSQL_TYPE_LONG_BLOB:  			case MYSQL_TYPE_TIMESTAMP: @@ -385,7 +421,6 @@ PHP_FUNCTION(mysqli_stmt_bind_result)  		}  		/* Don't free stmt->result.is_null because is_null & buf are one block of memory  */  		efree(stmt->result.buf); -		RETVAL_FALSE;  	} else {  		stmt->result.var_cnt = var_cnt;  		stmt->result.vars = (zval **)safe_emalloc((var_cnt), sizeof(zval), 0); @@ -394,10 +429,69 @@ PHP_FUNCTION(mysqli_stmt_bind_result)  			ZVAL_ADDREF(*args[i]);  			stmt->result.vars[ofs] = *args[i];  		} -		RETVAL_TRUE;  	} -	efree(args);  	efree(bind); + +	return rc; +} +#else +static int +mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval ***args, unsigned int argc, unsigned int start TSRMLS_DC) +{ +	unsigned int i; +	MYSQLND_RESULT_BIND *params; + +	params = emalloc((argc - start) * sizeof(MYSQLND_RESULT_BIND)); +	for (i = 0; i < (argc - start); i++) { +		params[i].zv = *(args[i + start]); +	} +	return mysqlnd_stmt_bind_result(stmt->stmt, params); +} +#endif +/* }}} */ + +/* {{{ proto bool mysqli_stmt_bind_result(object stmt, mixed var, [,mixed, ...]) U +   Bind variables to a prepared statement for result storage */ +PHP_FUNCTION(mysqli_stmt_bind_result) +{ +	zval		***args; +	int			argc = ZEND_NUM_ARGS(); +	int			start = 1; +	ulong		rc; +	MY_STMT		*stmt; +	zval		*mysql_stmt; + +	if (getThis()) { +		start = 0; +	} + +	if (zend_parse_method_parameters((getThis()) ? 0:1 TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { +		return;	 +	} + +	MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt", MYSQLI_STATUS_VALID); + +	if (argc < (getThis() ? 1 : 2)) { +		WRONG_PARAM_COUNT; +	} + +	if ((argc - start) != mysql_stmt_field_count(stmt->stmt)) { +		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of bind variables doesn't match number of fields in prepared statement"); +		RETURN_FALSE; +	} + +	args = (zval ***)safe_emalloc(argc, sizeof(zval **), 0); + +	if (zend_get_parameters_array_ex(argc, args) == FAILURE) { +		efree(args); +		WRONG_PARAM_COUNT; +	} + +	rc = mysqli_stmt_bind_result_do_bind(stmt, args, argc, start TSRMLS_CC); + +	efree(args); + +	RETURN_BOOL(!rc);  }  /* }}} */ @@ -406,9 +500,9 @@ PHP_FUNCTION(mysqli_stmt_bind_result)  PHP_FUNCTION(mysqli_change_user)  {  	MY_MYSQL	*mysql; -	zval  		*mysql_link = NULL; -	char  		*user, *password, *dbname; -	int   		user_len, password_len, dbname_len; +	zval		*mysql_link = NULL; +	char		*user, *password, *dbname; +	int			user_len, password_len, dbname_len;  	ulong		rc;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Osss", &mysql_link, mysqli_link_class_entry, &user, &user_len, &password, &password_len, &dbname, &dbname_len) == FAILURE) { @@ -431,8 +525,8 @@ PHP_FUNCTION(mysqli_change_user)     Returns the name of the character set used for this connection */  PHP_FUNCTION(mysqli_character_set_name)  { -	MY_MYSQL 	*mysql; -	zval  		*mysql_link; +	MY_MYSQL	*mysql; +	zval		*mysql_link;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {  		return; @@ -440,7 +534,7 @@ PHP_FUNCTION(mysqli_character_set_name)  	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); -	RETURN_STRING((char *) mysql_character_set_name(mysql->mysql), 1); +	RETURN_STRING((char *)mysql_character_set_name(mysql->mysql), 1);  }  /* }}} */ @@ -448,8 +542,8 @@ PHP_FUNCTION(mysqli_character_set_name)     Close connection */  PHP_FUNCTION(mysqli_close)  { -	zval 		*mysql_link; -	MY_MYSQL 	*mysql; +	zval		*mysql_link; +	MY_MYSQL	*mysql;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {  		return; @@ -457,11 +551,32 @@ PHP_FUNCTION(mysqli_close)  	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_INITIALIZED); -	mysql_close(mysql->mysql); -	mysql->mysql = NULL; +	if (!mysql->persistent) { +		mysqli_close(mysql->mysql, MYSQLI_CLOSE_EXPLICIT); +		mysql->mysql = NULL; +	} else { +		zend_rsrc_list_entry *le; +		if (zend_hash_find(&EG(persistent_list), mysql->hash_key, strlen(mysql->hash_key) + 1, (void **)&le) == SUCCESS) { +			if (Z_TYPE_P(le) == php_le_pmysqli()) { +				mysqli_plist_entry *plist = (mysqli_plist_entry *) le->ptr; +				dtor_func_t pDestructor = plist->used_links.pDestructor; + +				plist->used_links.pDestructor = NULL; /* Don't call pDestructor now */ +				zend_hash_index_del(&plist->used_links, mysql->hash_index); +				plist->used_links.pDestructor = pDestructor; /* Restore the destructor */ + +				zend_hash_next_index_insert(&plist->free_links, &mysql->mysql, sizeof(MYSQL *), NULL); +				MyG(num_links)--; +				MyG(num_active_persistent)--; +				MyG(num_inactive_persistent)++; +			} +		} +	} +  	php_clear_mysql(mysql); + +	MYSQLI_CLEAR_RESOURCE(&mysql_link);  	efree(mysql); -	MYSQLI_CLEAR_RESOURCE(&mysql_link);	  	RETURN_TRUE;  }  /* }}} */ @@ -470,8 +585,8 @@ PHP_FUNCTION(mysqli_close)     Commit outstanding actions and close transaction */  PHP_FUNCTION(mysqli_commit)  { -	MY_MYSQL 	*mysql; -	zval 		*mysql_link; +	MY_MYSQL	*mysql; +	zval		*mysql_link;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {  		return; @@ -489,8 +604,8 @@ PHP_FUNCTION(mysqli_commit)  PHP_FUNCTION(mysqli_data_seek)  {  	MYSQL_RES	*result; -	zval  		*mysql_result; -	long  		offset; +	zval		*mysql_result; +	long		offset;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_result, mysqli_result_class_entry, &offset) == FAILURE) {  		return; @@ -498,13 +613,13 @@ PHP_FUNCTION(mysqli_data_seek)  	MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); -	if (result->handle && result->handle->status == MYSQL_STATUS_USE_RESULT) { +	if (mysqli_result_is_unbuffered(result)) {  		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function cannot be used with MYSQL_USE_RESULT");  		RETURN_FALSE;  	} -	if (offset < 0 || offset >= result->row_count) { -	   RETURN_FALSE; +	if (offset < 0 || offset >= mysql_num_rows(result)) { +		RETURN_FALSE;  	}  	mysql_data_seek(result, offset); @@ -512,12 +627,12 @@ PHP_FUNCTION(mysqli_data_seek)  }  /* }}} */ -/* {{{ proto void mysqli_debug(string debug) +/* {{{ proto void mysqli_debug(string debug) U  */  PHP_FUNCTION(mysqli_debug)  { -	char		*debug; -	int			debug_len; +	char	*debug; +	int		debug_len;  	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &debug, &debug_len) == FAILURE) {  		return; @@ -528,25 +643,20 @@ PHP_FUNCTION(mysqli_debug)  }  /* }}} */ +  /* {{{ proto bool mysqli_dump_debug_info(object link)  */  PHP_FUNCTION(mysqli_dump_debug_info)  { -	MY_MYSQL 	*mysql; -	zval  		*mysql_link; -	ulong		rc; +	MY_MYSQL	*mysql; +	zval		*mysql_link;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {  		return;  	}  	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); -	rc = mysql_dump_debug_info(mysql->mysql); - -	if (rc) { -		RETURN_FALSE; -	} -	RETURN_TRUE;	 +	RETURN_BOOL(!mysql_dump_debug_info(mysql->mysql))  }  /* }}} */ @@ -554,8 +664,8 @@ PHP_FUNCTION(mysqli_dump_debug_info)     Returns the numerical value of the error message from previous MySQL operation */  PHP_FUNCTION(mysqli_errno)  { -	MY_MYSQL 	*mysql; -	zval  		*mysql_link; +	MY_MYSQL	*mysql; +	zval		*mysql_link;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {  		return; @@ -569,8 +679,8 @@ PHP_FUNCTION(mysqli_errno)     Returns the text of the error message from previous MySQL operation */  PHP_FUNCTION(mysqli_error)   { -	MY_MYSQL 	*mysql; -	zval  		*mysql_link; +	MY_MYSQL	*mysql; +	zval		*mysql_link;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {  		return; @@ -584,16 +694,19 @@ PHP_FUNCTION(mysqli_error)     Execute a prepared statement */  PHP_FUNCTION(mysqli_stmt_execute)  { -	MY_STMT 		*stmt; -	zval 			*mysql_stmt; -	unsigned int 	i; +	MY_STMT		*stmt; +	zval		*mysql_stmt; +#ifndef HAVE_MYSQLND +	unsigned int	i; +#endif  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {  		return;  	}  	MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt", MYSQLI_STATUS_VALID); -	 -	for (i = 0; i < stmt->param.var_cnt; i++) {		 + +#ifndef HAVE_MYSQLND +	for (i = 0; i < stmt->param.var_cnt; i++) {  		if (stmt->param.vars[i]) {  			if ( !(stmt->param.is_null[i] = (stmt->param.vars[i]->type == IS_NULL)) ) {  				switch (stmt->stmt->params[i].buffer_type) { @@ -604,40 +717,43 @@ PHP_FUNCTION(mysqli_stmt_execute)  						break;  					case MYSQL_TYPE_DOUBLE:  						convert_to_double_ex(&stmt->param.vars[i]); -						stmt->stmt->params[i].buffer = (char*)&Z_LVAL_PP(&stmt->param.vars[i]); +						stmt->stmt->params[i].buffer = &Z_LVAL_PP(&stmt->param.vars[i]);  						break;  					case MYSQL_TYPE_LONG:  						convert_to_long_ex(&stmt->param.vars[i]); -						stmt->stmt->params[i].buffer = (char*)&Z_LVAL_PP(&stmt->param.vars[i]); +						stmt->stmt->params[i].buffer = &Z_LVAL_PP(&stmt->param.vars[i]);  						break;  					default:  						break;  				} -			}	 +			}  		}  	} +#endif +  	if (mysql_stmt_execute(stmt->stmt)) {  		MYSQLI_REPORT_STMT_ERROR(stmt->stmt); -		RETURN_FALSE; +		RETVAL_FALSE; +	} else { +		RETVAL_TRUE;  	}  	if (MyG(report_mode) & MYSQLI_REPORT_INDEX) { -		php_mysqli_report_index(stmt->query, stmt->stmt->mysql->server_status TSRMLS_CC); +		php_mysqli_report_index(stmt->query, mysqli_stmt_server_status(stmt->stmt) TSRMLS_CC);  	} -	 -	RETURN_TRUE;  }  /* }}} */ -/* {{{ proto mixed mysqli_stmt_fetch(object stmt) +#ifndef HAVE_MYSQLND +/* {{{ void mysqli_stmt_fetch_libmysql     Fetch results from a prepared statement into the bound variables */ -PHP_FUNCTION(mysqli_stmt_fetch) +void mysqli_stmt_fetch_libmysql(INTERNAL_FUNCTION_PARAMETERS)  { -	MY_STMT 		*stmt; -	zval 			*mysql_stmt; -	unsigned int 	i; -	ulong 			ret; -	unsigned int    uval; +	MY_STMT		*stmt; +	zval			*mysql_stmt; +	unsigned int	i; +	ulong			ret; +	unsigned int	uval;  	my_ulonglong	llval; @@ -647,8 +763,6 @@ PHP_FUNCTION(mysqli_stmt_fetch)  	MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt", MYSQLI_STATUS_VALID);  	/* reset buffers */ - -  	for (i = 0; i < stmt->result.var_cnt; i++) {  		if (stmt->result.buf[i].type == IS_STRING) {  			memset(stmt->result.buf[i].val, 0, stmt->result.buf[i].buflen); @@ -661,6 +775,11 @@ PHP_FUNCTION(mysqli_stmt_fetch)  	if (!ret) {  #endif  		for (i = 0; i < stmt->result.var_cnt; i++) { +			/* +			  QQ: Isn't it quite better to call zval_dtor(). What if the user has +			  assigned a resource, or an array to the bound variable? We are going +			  to leak probably. zval_dtor() will handle also Unicode/Non-unicode mode. +			*/  			/* Even if the string is of length zero there is one byte alloced so efree() in all cases */  			if (Z_TYPE_P(stmt->result.vars[i]) == IS_STRING) {  				efree(stmt->result.vars[i]->value.str.val); @@ -669,11 +788,11 @@ PHP_FUNCTION(mysqli_stmt_fetch)  				switch (stmt->result.buf[i].type) {  					case IS_LONG:  						if ((stmt->stmt->fields[i].type == MYSQL_TYPE_LONG)  -						    && (stmt->stmt->fields[i].flags & UNSIGNED_FLAG))  +						    && (stmt->stmt->fields[i].flags & UNSIGNED_FLAG))  						{  							/* unsigned int (11) */  							uval= *(unsigned int *) stmt->result.buf[i].val; - +#if SIZEOF_LONG==4  							if (uval > INT_MAX) {  								char *tmp, *p;  								int j=10; @@ -681,13 +800,14 @@ PHP_FUNCTION(mysqli_stmt_fetch)  								p= &tmp[9];  								do {   									*p-- = (uval % 10) + 48; -									uval = uval / 10;							 +									uval = uval / 10;  								} while (--j > 0);  								tmp[10]= '\0'; -								/* unsigned int > INT_MAX is 10 digis - ALWAYS */ +								/* unsigned int > INT_MAX is 10 digits - ALWAYS */  								ZVAL_STRINGL(stmt->result.vars[i], tmp, 10, 0);  								break;  							} +#endif  						}  						if (stmt->stmt->fields[i].flags & UNSIGNED_FLAG) {   							ZVAL_LONG(stmt->result.vars[i], *(unsigned int *)stmt->result.buf[i].val); @@ -702,11 +822,12 @@ PHP_FUNCTION(mysqli_stmt_fetch)  						if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_LONGLONG) {  							my_bool uns= (stmt->stmt->fields[i].flags & UNSIGNED_FLAG)? 1:0;  							llval= *(my_ulonglong *) stmt->result.buf[i].val; -#if SIZEOF_LONG==8   +#if SIZEOF_LONG==8  							if (uns && llval > 9223372036854775807L) {  #elif SIZEOF_LONG==4  							if ((uns && llval > L64(2147483647)) ||  -							    (!uns && (( L64(2147483647) < (my_longlong) llval) || (L64(-2147483648) > (my_longlong) llval)))) +								(!uns && (( L64(2147483647) < (my_longlong) llval) || +								(L64(-2147483648) > (my_longlong) llval))))  							{  #endif  								char tmp[22]; @@ -719,7 +840,7 @@ PHP_FUNCTION(mysqli_stmt_fetch)  							} else {  								ZVAL_LONG(stmt->result.vars[i], llval);  							} -						}  +						}  #if MYSQL_VERSION_ID > 50002  						else if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_BIT) {  							llval = *(my_ulonglong *)stmt->result.buf[i].val; @@ -728,19 +849,21 @@ PHP_FUNCTION(mysqli_stmt_fetch)  #endif  						else {  #if defined(MYSQL_DATA_TRUNCATED) && MYSQL_VERSION_ID > 50002 -							if(ret == MYSQL_DATA_TRUNCATED && *(stmt->stmt->bind[i].error) != 0) { +							if (ret == MYSQL_DATA_TRUNCATED && *(stmt->stmt->bind[i].error) != 0) {  								/* result was truncated */ -								ZVAL_STRINGL(stmt->result.vars[i], stmt->result.buf[i].val, stmt->stmt->bind[i].buffer_length, 1); +								ZVAL_STRINGL(stmt->result.vars[i], stmt->result.buf[i].val, +											 stmt->stmt->bind[i].buffer_length, 1);  							} else {  #else  							{  #endif -								ZVAL_STRINGL(stmt->result.vars[i], stmt->result.buf[i].val, stmt->result.buf[i].buflen, 1); +								ZVAL_STRINGL(stmt->result.vars[i], stmt->result.buf[i].val, +											 stmt->result.buf[i].buflen, 1);  							}  						}  						break;  					default: -						break;	 +						break;  				}  			} else {  				ZVAL_NULL(stmt->result.vars[i]); @@ -770,14 +893,68 @@ PHP_FUNCTION(mysqli_stmt_fetch)  	}  }  /* }}} */ +#else +/* {{{ mixed mysqli_stmt_fetch_mysqlnd */ +void mysqli_stmt_fetch_mysqlnd(INTERNAL_FUNCTION_PARAMETERS) +{ +	MY_STMT		*stmt; +	zval		*mysql_stmt; +	zend_bool	fetched_anything; + +	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { +		return; +	} +	MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt", MYSQLI_STATUS_VALID); + +	if (FAIL  == mysqlnd_stmt_fetch(stmt->stmt, &fetched_anything)) { +		RETURN_BOOL(FALSE); +	} else if (fetched_anything == TRUE) { +		RETURN_BOOL(TRUE); +	} else { +		RETURN_NULL(); +	} +} +#endif +/* }}} */ + + +/* {{{ proto mixed mysqli_stmt_fetch(object stmt) U +   Fetch results from a prepared statement into the bound variables */ +PHP_FUNCTION(mysqli_stmt_fetch) +{ +#if !defined(HAVE_MYSQLND) +	mysqli_stmt_fetch_libmysql(INTERNAL_FUNCTION_PARAM_PASSTHRU); +#else +	mysqli_stmt_fetch_mysqlnd(INTERNAL_FUNCTION_PARAM_PASSTHRU); +#endif +} +/* }}} */ + +/* {{{  php_add_field_properties */ +static void php_add_field_properties(zval *value, MYSQL_FIELD *field TSRMLS_DC) +{ +	add_property_string(value, "name",(field->name ? field->name : ""), 1); +	add_property_string(value, "orgname",(field->org_name ? field->org_name : ""), 1); +	add_property_string(value, "table",(field->table ? field->table : ""), 1); +	add_property_string(value, "orgtable",(field->org_table ? field->org_table : ""), 1); +	add_property_string(value, "def",(field->def ? field->def : ""), 1); + +	add_property_long(value, "max_length", field->max_length); +	add_property_long(value, "length", field->length); +	add_property_long(value, "charsetnr", field->charsetnr); +	add_property_long(value, "flags", field->flags); +	add_property_long(value, "type", field->type); +	add_property_long(value, "decimals", field->decimals); +} +/* }}} */  /* {{{ proto mixed mysqli_fetch_field (object result)     Get column information from a result and return as an object */  PHP_FUNCTION(mysqli_fetch_field)   { -	MYSQL_RES 	*result; -	zval  		*mysql_result; -	MYSQL_FIELD *field; +	MYSQL_RES	*result; +	zval		*mysql_result; +	MYSQL_FIELD	*field;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {  		return; @@ -790,18 +967,7 @@ PHP_FUNCTION(mysqli_fetch_field)  	}  	object_init(return_value); - -	add_property_string(return_value, "name",(field->name ? field->name : ""), 1); -	add_property_string(return_value, "orgname",(field->org_name ? field->org_name : ""), 1); -	add_property_string(return_value, "table",(field->table ? field->table : ""), 1); -	add_property_string(return_value, "orgtable",(field->org_table ? field->org_table : ""), 1); -	add_property_string(return_value, "def",(field->def ? field->def : ""), 1); -	add_property_long(return_value, "max_length", field->max_length); -	add_property_long(return_value, "length", field->length); -	add_property_long(return_value, "charsetnr", field->charsetnr); -	add_property_long(return_value, "flags", field->flags); -	add_property_long(return_value, "type", field->type); -	add_property_long(return_value, "decimals", field->decimals); +	php_add_field_properties(return_value, field TSRMLS_CC);  }  /* }}} */ @@ -810,9 +976,9 @@ PHP_FUNCTION(mysqli_fetch_field)  PHP_FUNCTION(mysqli_fetch_fields)   {  	MYSQL_RES	*result; -	zval  		*mysql_result; +	zval		*mysql_result;  	MYSQL_FIELD	*field; -	zval 		*obj; +	zval		*obj;  	unsigned int i; @@ -827,22 +993,10 @@ PHP_FUNCTION(mysqli_fetch_fields)  	for (i = 0; i < mysql_num_fields(result); i++) {  		field = mysql_fetch_field_direct(result, i); -  		MAKE_STD_ZVAL(obj);  		object_init(obj); -		add_property_string(obj, "name",(field->name ? field->name : ""), 1); -		add_property_string(obj, "orgname",(field->org_name ? field->org_name : ""), 1); -		add_property_string(obj, "table",(field->table ? field->table : ""), 1); -		add_property_string(obj, "orgtable",(field->org_table ? field->org_table : ""), 1); -		add_property_string(obj, "def",(field->def ? field->def : ""), 1); -		add_property_long(obj, "max_length", field->max_length); -		add_property_long(obj, "length", field->length); -		add_property_long(obj, "charsetnr", field->charsetnr); -		add_property_long(obj, "flags", field->flags); -		add_property_long(obj, "type", field->type); -		add_property_long(obj, "decimals", field->decimals); - +		php_add_field_properties(obj, field TSRMLS_CC);  		add_index_zval(return_value, i, obj);  	}  } @@ -854,8 +1008,8 @@ PHP_FUNCTION(mysqli_fetch_field_direct)  {  	MYSQL_RES	*result;  	zval		*mysql_result; -	MYSQL_FIELD *field; -	long 		offset; +	MYSQL_FIELD	*field; +	long		offset;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_result, mysqli_result_class_entry, &offset) == FAILURE) {  		return; @@ -873,18 +1027,7 @@ PHP_FUNCTION(mysqli_fetch_field_direct)  	}  	object_init(return_value); - -	add_property_string(return_value, "name",(field->name ? field->name : ""), 1); -	add_property_string(return_value, "orgname",(field->org_name ? field->org_name : ""), 1); -	add_property_string(return_value, "table",(field->table ? field->table : ""), 1); -	add_property_string(return_value, "orgtable",(field->org_table ? field->org_table : ""), 1); -	add_property_string(return_value, "def",(field->def ? field->def : ""), 1); -	add_property_long(return_value, "max_length", field->max_length); -	add_property_long(return_value, "length", field->length); -	add_property_long(return_value, "charsetnr", field->charsetnr); -	add_property_long(return_value, "flags", field->flags); -	add_property_long(return_value, "type", field->type); -	add_property_long(return_value, "decimals", field->decimals); +	php_add_field_properties(return_value, field TSRMLS_CC);  }  /* }}} */ @@ -896,7 +1039,7 @@ PHP_FUNCTION(mysqli_fetch_lengths)  	zval			*mysql_result;  	unsigned int	i;  	unsigned long	*ret; -	 +  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {  		return;  	} @@ -910,7 +1053,7 @@ PHP_FUNCTION(mysqli_fetch_lengths)  	array_init(return_value);  	for (i = 0; i < mysql_num_fields(result); i++) { -		add_index_long(return_value, i, ret[i]);	 +		add_index_long(return_value, i, ret[i]);  	}  }  /* }}} */ @@ -919,17 +1062,28 @@ PHP_FUNCTION(mysqli_fetch_lengths)     Get a result row as an enumerated array */  PHP_FUNCTION(mysqli_fetch_row)   { +#if !defined(HAVE_MYSQLND)  	php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_NUM, 0); +#else +	MYSQL_RES	*result; +	zval		*mysql_result; + +	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) { +		return; +	} +	MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); +	mysqlnd_fetch_into(result, MYSQLND_FETCH_NUM, return_value, MYSQLND_MYSQLI);  +#endif  }  /* }}} */  /* {{{ proto int mysqli_field_count(object link)     Fetch the number of fields returned by the last query for the given link  */ -PHP_FUNCTION(mysqli_field_count)  +PHP_FUNCTION(mysqli_field_count)  { -	MY_MYSQL 	*mysql; -	zval  		*mysql_link; +	MY_MYSQL	*mysql; +	zval		*mysql_link;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {  		return; @@ -958,7 +1112,7 @@ PHP_FUNCTION(mysqli_field_seek)  		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid field offset");  		RETURN_FALSE;   	} -	 +  	mysql_field_seek(result, fieldnr);  	RETURN_TRUE;  } @@ -975,7 +1129,7 @@ PHP_FUNCTION(mysqli_field_tell)  		return;  	}  	MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); -	 +  	RETURN_LONG(mysql_field_tell(result));  }  /* }}} */ @@ -992,12 +1146,12 @@ PHP_FUNCTION(mysqli_free_result)  	}  	MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); -	mysql_free_result(result); -	MYSQLI_CLEAR_RESOURCE(&mysql_result);	 +	mysqli_free_result(result, FALSE); +	MYSQLI_CLEAR_RESOURCE(&mysql_result);  }  /* }}} */ -/* {{{ proto string mysqli_get_client_info(void)  +/* {{{ proto string mysqli_get_client_info(void)     Get MySQL client info */  PHP_FUNCTION(mysqli_get_client_info)  { @@ -1005,7 +1159,7 @@ PHP_FUNCTION(mysqli_get_client_info)  }  /* }}} */ -/* {{{ proto int mysqli_get_client_version(void)  +/* {{{ proto int mysqli_get_client_version(void)     Get MySQL client info */  PHP_FUNCTION(mysqli_get_client_version)  { @@ -1018,7 +1172,7 @@ PHP_FUNCTION(mysqli_get_client_version)  PHP_FUNCTION(mysqli_get_host_info)  {  	MY_MYSQL	*mysql; -	zval  		*mysql_link = NULL; +	zval		*mysql_link = NULL;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {  		return; @@ -1033,24 +1187,23 @@ PHP_FUNCTION(mysqli_get_host_info)     Get MySQL protocol information */  PHP_FUNCTION(mysqli_get_proto_info)  { -	MY_MYSQL 	*mysql; -	zval  		*mysql_link = NULL; +	MY_MYSQL	*mysql; +	zval		*mysql_link = NULL;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {  		return;  	}  	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); -  	RETURN_LONG(mysql_get_proto_info(mysql->mysql));  }  /* }}} */ -/* {{{ proto string mysqli_get_server_info(object link)  +/* {{{ proto string mysqli_get_server_info(object link)     Get MySQL server info */  PHP_FUNCTION(mysqli_get_server_info)  {  	MY_MYSQL	*mysql; -	zval	  	*mysql_link = NULL; +	zval		*mysql_link = NULL;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {  		return; @@ -1083,14 +1236,16 @@ PHP_FUNCTION(mysqli_get_server_version)  PHP_FUNCTION(mysqli_info)  {  	MY_MYSQL	*mysql; -	zval  		*mysql_link = NULL; +	zval		*mysql_link = NULL; +	const char	*info;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {  		return;  	}  	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); -	RETURN_STRING((mysql->mysql->info) ? mysql->mysql->info : "", 1); +	info = mysql_info(mysql->mysql); +	RETURN_STRING((info) ? (char *)info : "", 1);  }  /* }}} */ @@ -1101,7 +1256,12 @@ PHP_FUNCTION(mysqli_init)  	MYSQLI_RESOURCE *mysqli_resource;  	MY_MYSQL *mysql = (MY_MYSQL *)ecalloc(1, sizeof(MY_MYSQL)); -	if (!(mysql->mysql = mysql_init(NULL))) { +#if !defined(HAVE_MYSQLND) +	if (!(mysql->mysql = mysql_init(NULL))) +#else +	if (!(mysql->mysql = mysql_init(FALSE))) +#endif +	{  		efree(mysql);  		RETURN_FALSE;  	} @@ -1123,8 +1283,8 @@ PHP_FUNCTION(mysqli_init)  PHP_FUNCTION(mysqli_insert_id)  {  	MY_MYSQL		*mysql; -	my_ulonglong 	rc; -	zval  			*mysql_link; +	my_ulonglong	rc; +	zval			*mysql_link;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {  		return; @@ -1139,15 +1299,20 @@ PHP_FUNCTION(mysqli_insert_id)     Kill a mysql process on the server */  PHP_FUNCTION(mysqli_kill)  { -	MY_MYSQL 	*mysql; -	zval  		*mysql_link; -	long   		processid; +	MY_MYSQL	*mysql; +	zval		*mysql_link; +	long		processid;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_link, mysqli_link_class_entry, &processid) == FAILURE) {  		return;  	}  	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); -	 + +	if (processid <= 0) { +		php_error_docref(NULL TSRMLS_CC, E_WARNING, "processid should have positive value"); +		RETURN_FALSE; +	} +  	if (mysql_kill(mysql->mysql, processid)) {  		MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);  		RETURN_FALSE; @@ -1158,6 +1323,7 @@ PHP_FUNCTION(mysqli_kill)  /* {{{ proto void mysqli_set_local_infile_default(object link)     unsets user defined handler for load local infile command */ +#if !defined(HAVE_MYSQLND)  PHP_FUNCTION(mysqli_set_local_infile_default)  {  	MY_MYSQL	*mysql; @@ -1182,7 +1348,7 @@ PHP_FUNCTION(mysqli_set_local_infile_default)  PHP_FUNCTION(mysqli_set_local_infile_handler)  {  	MY_MYSQL	*mysql; -	zval  		*mysql_link; +	zval		*mysql_link;  	char		*callback_name;  	zval		*callback_func; @@ -1197,24 +1363,29 @@ PHP_FUNCTION(mysqli_set_local_infile_handler)  	if (!zend_is_callable(callback_func, 0, &callback_name)) {  		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not a valid callback function %s", callback_name);  		efree(callback_name); -		RETURN_FALSE;		 +		RETURN_FALSE;  	}  	efree(callback_name);  	/* save callback function */ -	ALLOC_ZVAL(mysql->li_read);	 -	ZVAL_STRING(mysql->li_read, callback_func->value.str.val, 1); +	if (!mysql->li_read) { +		MAKE_STD_ZVAL(mysql->li_read); +	} else { +		zval_dtor(mysql->li_read); +	} +	ZVAL_STRINGL(mysql->li_read, Z_STRVAL_P(callback_func), Z_STRLEN_P(callback_func), 1);  	RETURN_TRUE;  } +#endif  /* }}} */  /* {{{ proto bool mysqli_more_results(object link)     check if there any more query results from a multi query */  PHP_FUNCTION(mysqli_more_results)  { -	MY_MYSQL		*mysql; -	zval			*mysql_link; +	MY_MYSQL	*mysql; +	zval		*mysql_link;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {  		return; @@ -1228,14 +1399,20 @@ PHP_FUNCTION(mysqli_more_results)  /* {{{ proto bool mysqli_next_result(object link)     read next result from multi_query */  PHP_FUNCTION(mysqli_next_result) { -	MY_MYSQL		*mysql; -	zval			*mysql_link; +	MY_MYSQL	*mysql; +	zval		*mysql_link;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {  		return;  	}  	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); +	if (!mysql_more_results(mysql->mysql)) { +		php_error_docref(NULL TSRMLS_CC, E_STRICT, "There is no next result set. " +						"Please, call mysqli_more_results()/mysqli::more_results() to check " +						"whether to call this function/method"); +	} +  	RETURN_BOOL(!mysql_next_result(mysql->mysql));  }  /* }}} */ @@ -1268,7 +1445,7 @@ PHP_FUNCTION(mysqli_num_rows)  	}  	MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); -	if (result->handle && result->handle->status == MYSQL_STATUS_USE_RESULT) { +	if (mysqli_result_is_unbuffered(result)) {  		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function cannot be used with MYSQL_USE_RESULT");  		RETURN_LONG(0);  	} @@ -1281,12 +1458,12 @@ PHP_FUNCTION(mysqli_num_rows)     Set options */  PHP_FUNCTION(mysqli_options)  { -	MY_MYSQL 		*mysql; -	zval  			*mysql_link = NULL; -	zval  			*mysql_value; -	long  			mysql_option; -	unsigned int 	l_value; -	long  			ret; +	MY_MYSQL		*mysql; +	zval			*mysql_link = NULL; +	zval			*mysql_value; +	long			mysql_option; +	unsigned int	l_value; +	long			ret;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Olz", &mysql_link, mysqli_link_class_entry, &mysql_option, &mysql_value) == FAILURE) {  		return; @@ -1311,7 +1488,7 @@ PHP_FUNCTION(mysqli_options)  	}  	RETURN_BOOL(!ret); -}    +}  /* }}} */ @@ -1319,8 +1496,8 @@ PHP_FUNCTION(mysqli_options)     Ping a server connection or reconnect if there is no connection */  PHP_FUNCTION(mysqli_ping)  { -	MY_MYSQL 	*mysql; -	zval  		*mysql_link; +	MY_MYSQL	*mysql; +	zval		*mysql_link;  	long		rc;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { @@ -1339,60 +1516,71 @@ PHP_FUNCTION(mysqli_ping)  PHP_FUNCTION(mysqli_prepare)  {  	MY_MYSQL		*mysql; -	MY_STMT 		*stmt; +	MY_STMT			*stmt;  	char			*query = NULL;  	unsigned int	query_len;  	zval			*mysql_link; -	MYSQLI_RESOURCE *mysqli_resource;  +	MYSQLI_RESOURCE	*mysqli_resource;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os",&mysql_link, mysqli_link_class_entry, &query, &query_len) == FAILURE) {  		return;  	}  	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); + +#if !defined(HAVE_MYSQLND)  	if (mysql->mysql->status == MYSQL_STATUS_GET_RESULT) {  		php_error_docref(NULL TSRMLS_CC, E_WARNING, "All data must be fetched before a new statement prepare takes place");  		RETURN_FALSE;  	} +#endif  	stmt = (MY_STMT *)ecalloc(1,sizeof(MY_STMT));  	if ((stmt->stmt = mysql_stmt_init(mysql->mysql))) {  		if (mysql_stmt_prepare(stmt->stmt, query, query_len)) { -  			char  last_error[MYSQL_ERRMSG_SIZE]; -  			char  sqlstate[SQLSTATE_LENGTH+1];	 +			/* mysql_stmt_close() clears errors, so we have to store them temporarily */ +#if !defined(HAVE_MYSQLND) +			char  last_error[MYSQL_ERRMSG_SIZE]; +			char  sqlstate[SQLSTATE_LENGTH+1];  			unsigned int last_errno; -			/* mysql_stmt_close clears errors, so we have to store them temporarily */  			last_errno = stmt->stmt->last_errno;  			memcpy(last_error, stmt->stmt->last_error, MYSQL_ERRMSG_SIZE);  			memcpy(sqlstate, mysql->mysql->net.sqlstate, SQLSTATE_LENGTH+1); - -			mysql_stmt_close(stmt->stmt); +#else +			mysqlnd_error_info error_info = mysql->mysql->error_info; +#endif +			mysqli_stmt_close(stmt->stmt, FALSE);  			stmt->stmt = NULL;  			/* restore error messages */ +#if !defined(HAVE_MYSQLND)  			mysql->mysql->net.last_errno = last_errno;  			memcpy(mysql->mysql->net.last_error, last_error, MYSQL_ERRMSG_SIZE);  			memcpy(mysql->mysql->net.sqlstate, sqlstate, SQLSTATE_LENGTH+1); +#else +			mysql->mysql->error_info = error_info; +#endif  		}  	} -	/* don't joing to the previous if because it won't work if mysql_stmt_prepare_fails */ + +	/* don't initialize stmt->query with NULL, we ecalloc()-ed the memory */ +	/* Get performance boost if reporting is switched off */ +	if (stmt->stmt && query_len && (MyG(report_mode) & MYSQLI_REPORT_INDEX)) { +		stmt->query = (char *)emalloc(query_len + 1); +		memcpy(stmt->query, query, query_len); +		stmt->query[query_len] = '\0'; +	} + +	/* don't join to the previous if because it won't work if mysql_stmt_prepare_fails */  	if (!stmt->stmt) {  		MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);  		efree(stmt);  		RETURN_FALSE;  	} -  	mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));  	mysqli_resource->ptr = (void *)stmt; -	/* don't initialize stmt->query with NULL, we ecalloc()-ed the memory */ -	/* Get performance boost if reporting is switched off */ -	if (query_len && (MyG(report_mode) & MYSQLI_REPORT_INDEX)) { -		stmt->query = (char *)emalloc(query_len + 1); -		memcpy(stmt->query, query, query_len); -		stmt->query[query_len] = '\0'; -	}  	/* change status */  	mysqli_resource->status = MYSQLI_STATUS_VALID; @@ -1404,10 +1592,10 @@ PHP_FUNCTION(mysqli_prepare)     Open a connection to a mysql server */   PHP_FUNCTION(mysqli_real_connect)  { -	MY_MYSQL 		*mysql; -	char 			*hostname = NULL, *username=NULL, *passwd=NULL, *dbname=NULL, *socket=NULL; -	unsigned int 	hostname_len = 0, username_len = 0, passwd_len = 0, dbname_len = 0, socket_len = 0; -	unsigned long 	port=0, flags=0; +	MY_MYSQL		*mysql; +	char			*hostname = NULL, *username=NULL, *passwd=NULL, *dbname=NULL, *socket=NULL; +	unsigned int	hostname_len = 0, username_len = 0, passwd_len = 0, dbname_len = 0, socket_len = 0; +	unsigned long	port=0, flags=0;  	zval			*mysql_link;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|sssslsl", &mysql_link, mysqli_link_class_entry, @@ -1419,37 +1607,38 @@ PHP_FUNCTION(mysqli_real_connect)  	if (!socket_len) {  		socket = NULL;  	} - -	/* TODO: safe mode handling */ -	if (PG(sql_safe_mode)) { -	} else { -		if (!passwd) { -			passwd = MyG(default_pw); -			if (!username){ -				username = MyG(default_user); -				if (!hostname) { -					hostname = MyG(default_host); -				} -			} -		} +	if (!socket) { +		socket = MyG(default_socket);  	}	 +	if (!passwd) { +		passwd = MyG(default_pw); +		passwd_len = strlen(passwd); +	} +	if (!username){ +		username = MyG(default_user); +	} +	if (!hostname) { +		hostname = MyG(default_host); +	}  	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_INITIALIZED);  	/* remove some insecure options */  	flags &= ~CLIENT_MULTI_STATEMENTS;   /* don't allow multi_queries via connect parameter */ -	if ((PG(open_basedir) && PG(open_basedir)[0] != '\0') || PG(safe_mode)) { -		flags &= ~CLIENT_LOCAL_FILES; -	} - -	if (!socket) { -		socket = MyG(default_socket); +	if (PG(open_basedir) && PG(open_basedir)[0] != '\0') { +		flags ^= CLIENT_LOCAL_FILES;  	} -	if (mysql_real_connect(mysql->mysql,hostname,username,passwd,dbname,port,socket,flags) == NULL) { +#if !defined(HAVE_MYSQLND) +	if (mysql_real_connect(mysql->mysql, hostname, username, passwd, dbname ,port, socket ,flags) == NULL)  +#else +	if (mysqlnd_connect(mysql->mysql, hostname, username, passwd, passwd_len, dbname, dbname_len, +						port, socket, flags, MyG(mysqlnd_thd_zval_cache) TSRMLS_CC) == NULL) +#endif +	{  		php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql) TSRMLS_CC); -		php_mysqli_throw_sql_exception( mysql->mysql->net.sqlstate, mysql->mysql->net.last_errno TSRMLS_CC, -										"%s", mysql->mysql->net.last_error); +		php_mysqli_throw_sql_exception((char *)mysql_sqlstate(mysql->mysql), mysql_errno(mysql->mysql) TSRMLS_CC, +										"%s", mysql_error(mysql->mysql));  		/* change status */  		MYSQLI_SET_STATUS(&mysql_link, MYSQLI_STATUS_INITIALIZED); @@ -1458,10 +1647,14 @@ PHP_FUNCTION(mysqli_real_connect)  	php_mysqli_set_error(mysql_errno(mysql->mysql), (char *)mysql_error(mysql->mysql) TSRMLS_CC); +#if !defined(HAVE_MYSQLND)  	mysql->mysql->reconnect = MyG(reconnect);  	/* set our own local_infile handler */  	php_set_local_infile_handler_default(mysql); +#endif + +	mysql_options(mysql->mysql, MYSQL_OPT_LOCAL_INFILE, (char *)&MyG(allow_local_infile));  	/* change status */  	MYSQLI_SET_STATUS(&mysql_link, MYSQLI_STATUS_VALID); @@ -1477,7 +1670,7 @@ PHP_FUNCTION(mysqli_real_query)  	MY_MYSQL		*mysql;  	zval			*mysql_link;  	char			*query = NULL; -	unsigned int 	query_len; +	unsigned int	query_len;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &query, &query_len) == FAILURE) {  		return; @@ -1493,7 +1686,7 @@ PHP_FUNCTION(mysqli_real_query)  	if (!mysql_field_count(mysql->mysql)) {  		if (MyG(report_mode) & MYSQLI_REPORT_INDEX) { -			php_mysqli_report_index(query, mysql->mysql->server_status TSRMLS_CC); +			php_mysqli_report_index(query, mysqli_server_status(mysql->mysql) TSRMLS_CC);  		}  	} @@ -1517,7 +1710,7 @@ PHP_FUNCTION(mysqli_real_escape_string) {  	newstr = safe_emalloc(2, escapestr_len, 1);  	newstr_len = mysql_real_escape_string(mysql->mysql, newstr, escapestr, escapestr_len);  	newstr = erealloc(newstr, newstr_len + 1); -		 +  	RETURN_STRINGL(newstr, newstr_len, 0);  }  /* }}} */ @@ -1527,7 +1720,7 @@ PHP_FUNCTION(mysqli_real_escape_string) {  PHP_FUNCTION(mysqli_rollback)  {  	MY_MYSQL	*mysql; -	zval  		*mysql_link; +	zval		*mysql_link;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {  		return; @@ -1546,12 +1739,11 @@ PHP_FUNCTION(mysqli_rollback)  PHP_FUNCTION(mysqli_stmt_send_long_data)  {  	MY_STMT *stmt; -	zval  	*mysql_stmt; +	zval	*mysql_stmt;  	char	*data;  	long	param_nr;  	int		data_len; -  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ols", &mysql_stmt, mysqli_stmt_class_entry, ¶m_nr, &data, &data_len) == FAILURE) {  		return;  	} @@ -1573,8 +1765,8 @@ PHP_FUNCTION(mysqli_stmt_send_long_data)     Return the number of rows affected in the last query for the given link */  PHP_FUNCTION(mysqli_stmt_affected_rows)  { -	MY_STMT 		*stmt; -	zval    		*mysql_stmt; +	MY_STMT			*stmt; +	zval			*mysql_stmt;  	my_ulonglong	rc;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { @@ -1590,21 +1782,21 @@ PHP_FUNCTION(mysqli_stmt_affected_rows)  }  /* }}} */ -/* {{{ proto bool mysqli_stmt_close(object stmt)  +/* {{{ proto bool mysqli_stmt_close(object stmt)     Close statement */  PHP_FUNCTION(mysqli_stmt_close)  { -	MY_STMT 	*stmt; -	zval    	*mysql_stmt; +	MY_STMT		*stmt; +	zval		*mysql_stmt;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {  		return;  	}  	MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt", MYSQLI_STATUS_VALID); -	mysql_stmt_close(stmt->stmt); +	mysqli_stmt_close(stmt->stmt, FALSE);  	stmt->stmt = NULL; -	php_clear_stmt_bind(stmt);  +	php_clear_stmt_bind(stmt TSRMLS_CC);  	MYSQLI_CLEAR_RESOURCE(&mysql_stmt);  	RETURN_TRUE;  } @@ -1614,9 +1806,9 @@ PHP_FUNCTION(mysqli_stmt_close)     Move internal result pointer */  PHP_FUNCTION(mysqli_stmt_data_seek)  { -	MY_STMT 	*stmt; -	zval  		*mysql_stmt; -	long  		offset; +	MY_STMT		*stmt; +	zval		*mysql_stmt; +	long		offset;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_stmt, mysqli_stmt_class_entry, &offset) == FAILURE) {  		return; @@ -1636,7 +1828,7 @@ PHP_FUNCTION(mysqli_stmt_data_seek)     Return the number of result columns for the given statement */  PHP_FUNCTION(mysqli_stmt_field_count)  { -	MY_STMT 	*stmt; +	MY_STMT		*stmt;  	zval		*mysql_stmt;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { @@ -1652,8 +1844,8 @@ PHP_FUNCTION(mysqli_stmt_field_count)     Free stored result memory for the given statement handle */  PHP_FUNCTION(mysqli_stmt_free_result)   { -	MY_STMT 		*stmt; -	zval    		*mysql_stmt; +	MY_STMT		*stmt; +	zval		*mysql_stmt;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {  		return; @@ -1669,9 +1861,9 @@ PHP_FUNCTION(mysqli_stmt_free_result)     Get the ID generated from the previous INSERT operation */  PHP_FUNCTION(mysqli_stmt_insert_id)  { -	MY_STMT		 	*stmt; -	my_ulonglong 	rc; -	zval  			*mysql_stmt; +	MY_STMT			*stmt; +	my_ulonglong	rc; +	zval			*mysql_stmt;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {  		return; @@ -1682,13 +1874,13 @@ PHP_FUNCTION(mysqli_stmt_insert_id)  }  /* }}} */ -/* {{{ proto int mysqli_stmt_param_count(object stmt) { +/* {{{ proto int mysqli_stmt_param_count(object stmt)     Return the number of parameter for the given statement */  PHP_FUNCTION(mysqli_stmt_param_count)  { -	MY_STMT 	*stmt; +	MY_STMT		*stmt;  	zval		*mysql_stmt; -	 +  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {  		return;  	} @@ -1700,10 +1892,10 @@ PHP_FUNCTION(mysqli_stmt_param_count)  /* {{{ proto bool mysqli_stmt_reset(object stmt)     reset a prepared statement */ -PHP_FUNCTION(mysqli_stmt_reset)  +PHP_FUNCTION(mysqli_stmt_reset)  { -	MY_STMT 		*stmt; -	zval    		*mysql_stmt; +	MY_STMT		*stmt; +	zval		*mysql_stmt;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {  		return; @@ -1722,8 +1914,8 @@ PHP_FUNCTION(mysqli_stmt_reset)     Return the number of rows in statements result set */  PHP_FUNCTION(mysqli_stmt_num_rows)  { -	MY_STMT 		*stmt; -	zval    		*mysql_stmt; +	MY_STMT			*stmt; +	zval			*mysql_stmt;  	my_ulonglong	rc;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { @@ -1737,27 +1929,25 @@ PHP_FUNCTION(mysqli_stmt_num_rows)  }  /* }}} */ -/* {{{ proto string mysqli_select_db(object link, string dbname) +/* {{{ proto bool mysqli_select_db(object link, string dbname)     Select a MySQL database */  PHP_FUNCTION(mysqli_select_db)   {  	MY_MYSQL	*mysql; -	zval  		*mysql_link; -	char  		*dbname; -	int   		dbname_len; - +	zval		*mysql_link; +	char		*dbname; +	int			dbname_len;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &dbname, &dbname_len) == FAILURE) {  		return;  	}   	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); -	 -	if (!mysql_select_db(mysql->mysql, dbname)) { -		RETURN_TRUE; + +	if (mysql_select_db(mysql->mysql, dbname)) { +		MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); +		RETURN_FALSE;  	} -	 -	MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); -	RETURN_FALSE; +	RETURN_TRUE;  }  /* }}} */ @@ -1765,8 +1955,8 @@ PHP_FUNCTION(mysqli_select_db)     Returns the SQLSTATE error from previous MySQL operation */  PHP_FUNCTION(mysqli_sqlstate)   { -	MY_MYSQL 	*mysql; -	zval  		*mysql_link; +	MY_MYSQL	*mysql; +	zval		*mysql_link;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {  		return; @@ -1776,21 +1966,22 @@ PHP_FUNCTION(mysqli_sqlstate)  }  /* }}} */ -/* {{{ proto bool mysqli_ssl_set(object link ,string key ,string cert ,string ca ,string capath ,string cipher]) +/* {{{ proto bool mysqli_ssl_set(object link ,string key ,string cert ,string ca ,string capath ,string cipher]) U  */ +#if !defined(HAVE_MYSQLND)  PHP_FUNCTION(mysqli_ssl_set)  {  	MY_MYSQL	*mysql; -	zval  		*mysql_link; -	char  		*ssl_parm[5]; +	zval		*mysql_link; +	char		*ssl_parm[5];  	int			ssl_parm_len[5], i;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Osssss", &mysql_link, mysqli_link_class_entry, &ssl_parm[0], &ssl_parm_len[0], &ssl_parm[1], &ssl_parm_len[1], &ssl_parm[2], &ssl_parm_len[2], &ssl_parm[3], &ssl_parm_len[3], &ssl_parm[4], &ssl_parm_len[4])   == FAILURE) {  		return;  	} -	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_INITIALIZED); +	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); -	for (i=0; i < 5; i++) { +	for (i = 0; i < 5; i++) {  		if (!ssl_parm_len[i]) {  			ssl_parm[i] = NULL;  		} @@ -1800,25 +1991,37 @@ PHP_FUNCTION(mysqli_ssl_set)  	RETURN_TRUE;  } +#endif  /* }}} */  /* {{{ proto mixed mysqli_stat(object link)      Get current system status */  PHP_FUNCTION(mysqli_stat)  { -	MY_MYSQL 	*mysql; -	zval  		*mysql_link; +	MY_MYSQL	*mysql; +	zval		*mysql_link;  	char		*stat; +#if defined(HAVE_MYSQLND) +	uint		stat_len; +#endif  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {  		return;  	}  	MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); -	if ((stat = (char *)mysql_stat(mysql->mysql))) { +#if !defined(HAVE_MYSQLND) +	if ((stat = (char *)mysql_stat(mysql->mysql))) +	{  		RETURN_STRING(stat, 1); +#else +	if (mysqlnd_stat(mysql->mysql, &stat, &stat_len) == PASS) +	{ +		RETURN_STRINGL(stat, stat_len, 0); +#endif +	} else { +		RETURN_FALSE;  	} -	RETURN_FALSE;  }  /* }}} */ @@ -1828,16 +2031,23 @@ PHP_FUNCTION(mysqli_stat)  PHP_FUNCTION(mysqli_stmt_attr_set)  {  	MY_STMT	*stmt; -	zval 	*mysql_stmt; -	ulong   mode; +	zval	*mysql_stmt; +	long	mode_in; +	ulong	mode;  	ulong	attr;  	int		rc; -	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll", &mysql_stmt, mysqli_stmt_class_entry, &attr, &mode) == FAILURE) { +	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll", &mysql_stmt, mysqli_stmt_class_entry, &attr, &mode_in) == FAILURE) {  		return;  	}  	MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt", MYSQLI_STATUS_VALID); +	if (mode_in < 0) { +		php_error_docref(NULL TSRMLS_CC, E_WARNING, "mode should be non-negative, %ld passed", mode_in); +		RETURN_FALSE; +	} + +	mode = mode_in;  	if ((rc = mysql_stmt_attr_set(stmt->stmt, attr, (void *)&mode))) {  		RETURN_FALSE;  	} @@ -1850,8 +2060,8 @@ PHP_FUNCTION(mysqli_stmt_attr_set)  PHP_FUNCTION(mysqli_stmt_attr_get)  {  	MY_STMT	*stmt; -	zval 	*mysql_stmt; -#if MYSQL_VERSION_ID > 50099 +	zval	*mysql_stmt; +#if !defined(HAVE_MYSQLND) && MYSQL_VERSION_ID > 50099  	my_bool value;  #else  	ulong	value = 0; @@ -1876,7 +2086,7 @@ PHP_FUNCTION(mysqli_stmt_attr_get)  PHP_FUNCTION(mysqli_stmt_errno)  {  	MY_STMT	*stmt; -	zval 	*mysql_stmt; +	zval	*mysql_stmt;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {  		return; @@ -1909,9 +2119,9 @@ PHP_FUNCTION(mysqli_stmt_error)  PHP_FUNCTION(mysqli_stmt_init)  {  	MY_MYSQL		*mysql; -	MY_STMT 		*stmt; +	MY_STMT			*stmt;  	zval			*mysql_link; -	MYSQLI_RESOURCE *mysqli_resource;  +	MYSQLI_RESOURCE	*mysqli_resource;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",&mysql_link, mysqli_link_class_entry) == FAILURE) {  		return; @@ -1961,9 +2171,9 @@ PHP_FUNCTION(mysqli_stmt_prepare)     return result set from statement */  PHP_FUNCTION(mysqli_stmt_result_metadata)  { -	MY_STMT		*stmt; +	MY_STMT			*stmt;  	MYSQL_RES		*result; -	zval 			*mysql_stmt; +	zval			*mysql_stmt;  	MYSQLI_RESOURCE	*mysqli_resource;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { @@ -1979,7 +2189,7 @@ PHP_FUNCTION(mysqli_stmt_result_metadata)  	mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));  	mysqli_resource->ptr = (void *)result;  	mysqli_resource->status = MYSQLI_STATUS_VALID; -	MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);	 +	MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);  }  /* }}} */ @@ -1987,32 +2197,37 @@ PHP_FUNCTION(mysqli_stmt_result_metadata)  */  PHP_FUNCTION(mysqli_stmt_store_result)  { -	MY_STMT *stmt; -	zval 	*mysql_stmt; -	int		i=0; +	MY_STMT	*stmt; +	zval	*mysql_stmt;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {  		return;  	}  	MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt", MYSQLI_STATUS_VALID); -	/* -	  If the user wants to store the data and we have BLOBs/TEXTs we try to allocate -	  not the maximal length of the type (which is 16MB even for LONGBLOB) but -	  the maximal length of the field in the result set. If he/she has quite big -	  BLOB/TEXT columns after calling store_result() the memory usage of PHP will -	  double - but this is a known problem of the simple MySQL API ;) -	*/ -	for (i = mysql_stmt_field_count(stmt->stmt) - 1; i >=0; --i) { -		if (stmt->stmt->fields && (stmt->stmt->fields[i].type == MYSQL_TYPE_BLOB || -			stmt->stmt->fields[i].type == MYSQL_TYPE_MEDIUM_BLOB || -			stmt->stmt->fields[i].type == MYSQL_TYPE_LONG_BLOB)) -		{ -			my_bool	tmp=1; -			mysql_stmt_attr_set(stmt->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &tmp); -			break; +#if !defined(HAVE_MYSQLND) +	{ +		/* +		  If the user wants to store the data and we have BLOBs/TEXTs we try to allocate +		  not the maximal length of the type (which is 16MB even for LONGBLOB) but +		  the maximal length of the field in the result set. If he/she has quite big +		  BLOB/TEXT columns after calling store_result() the memory usage of PHP will +		  double - but this is a known problem of the simple MySQL API ;) +		*/ +		int	i = 0; + +		for (i = mysql_stmt_field_count(stmt->stmt) - 1; i >=0; --i) { +			if (stmt->stmt->fields && (stmt->stmt->fields[i].type == MYSQL_TYPE_BLOB || +				stmt->stmt->fields[i].type == MYSQL_TYPE_MEDIUM_BLOB || +				stmt->stmt->fields[i].type == MYSQL_TYPE_LONG_BLOB)) +			{ +				my_bool	tmp=1; +				mysql_stmt_attr_set(stmt->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &tmp); +				break; +			}  		}  	} +#endif  	if (mysql_stmt_store_result(stmt->stmt)){  		MYSQLI_REPORT_STMT_ERROR(stmt->stmt); @@ -2024,16 +2239,16 @@ PHP_FUNCTION(mysqli_stmt_store_result)  /* {{{ proto string mysqli_stmt_sqlstate(object stmt)  */ -PHP_FUNCTION(mysqli_stmt_sqlstate)  +PHP_FUNCTION(mysqli_stmt_sqlstate)  { -	MY_STMT *stmt; -	zval 	*mysql_stmt; +	MY_STMT	*stmt; +	zval	*mysql_stmt;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {  		return;  	}  	MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt", MYSQLI_STATUS_VALID); -	 +  	RETURN_STRING((char *)mysql_stmt_sqlstate(stmt->stmt),1);  }  /* }}} */ @@ -2042,9 +2257,9 @@ PHP_FUNCTION(mysqli_stmt_sqlstate)     Buffer result set on client */  PHP_FUNCTION(mysqli_store_result)  { -	MY_MYSQL 		*mysql; -	MYSQL_RES 		*result; -	zval  			*mysql_link; +	MY_MYSQL		*mysql; +	MYSQL_RES		*result; +	zval			*mysql_link;  	MYSQLI_RESOURCE	*mysqli_resource;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { @@ -2057,22 +2272,23 @@ PHP_FUNCTION(mysqli_store_result)  		RETURN_FALSE;  	}  	if (MyG(report_mode) & MYSQLI_REPORT_INDEX) { -		php_mysqli_report_index("from previous query", mysql->mysql->server_status TSRMLS_CC); +		php_mysqli_report_index("from previous query", mysqli_server_status(mysql->mysql) TSRMLS_CC);  	}  	mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));  	mysqli_resource->ptr = (void *)result;  	mysqli_resource->status = MYSQLI_STATUS_VALID; -	MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);	 +	MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);  }  /* }}} */ +  /* {{{ proto int mysqli_thread_id(object link)     Return the current thread ID */  PHP_FUNCTION(mysqli_thread_id)  { -	MY_MYSQL 	*mysql; -	zval  		*mysql_link; +	MY_MYSQL	*mysql; +	zval		*mysql_link;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {  		return; @@ -2089,17 +2305,16 @@ PHP_FUNCTION(mysqli_thread_safe)  {  	RETURN_BOOL(mysql_thread_safe());  } -  /* }}} */  /* {{{ proto mixed mysqli_use_result(object link)     Directly retrieve query results - do not buffer results on client side */  PHP_FUNCTION(mysqli_use_result)  { -	MY_MYSQL 		*mysql; -	MYSQL_RES 		*result; -	zval  			*mysql_link; -	MYSQLI_RESOURCE *mysqli_resource; +	MY_MYSQL		*mysql; +	MYSQL_RES		*result; +	zval			*mysql_link; +	MYSQLI_RESOURCE	*mysqli_resource;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {  		return; @@ -2112,12 +2327,12 @@ PHP_FUNCTION(mysqli_use_result)  	}  	if (MyG(report_mode) & MYSQLI_REPORT_INDEX) { -		php_mysqli_report_index("from previous query", mysql->mysql->server_status TSRMLS_CC); +		php_mysqli_report_index("from previous query", mysqli_server_status(mysql->mysql) TSRMLS_CC);  	}  	mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));  	mysqli_resource->ptr = (void *)result;  	mysqli_resource->status = MYSQLI_STATUS_VALID; -	MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);	 +	MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);  }  /* }}} */ @@ -2125,8 +2340,8 @@ PHP_FUNCTION(mysqli_use_result)     Return number of warnings from the last query for the given link */  PHP_FUNCTION(mysqli_warning_count)  { -	MY_MYSQL 	*mysql; -	zval  		*mysql_link; +	MY_MYSQL	*mysql; +	zval		*mysql_link;  	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {  		return;  | 
