diff options
| author | Georg Richter <georg@php.net> | 2003-11-22 21:20:07 +0000 | 
|---|---|---|
| committer | Georg Richter <georg@php.net> | 2003-11-22 21:20:07 +0000 | 
| commit | 230b207849e883a08e361b250eb4a0fd367b3e01 (patch) | |
| tree | 65651b4158f90b9c0b31e3703a09d089eae7336f | |
| parent | 28b6c35d80bcdaab0cce5652550f2233c4e9577b (diff) | |
| download | php-git-230b207849e883a08e361b250eb4a0fd367b3e01.tar.gz | |
- Added multiquery support:
	mysqli_multi_query
	mysqli_more_results
	mysqli_next_results
- added read-only properties (and removed methods)
	object mysql
		affected_rows
		client_flags
		client_version
		errno, error,
		host, host_info, info
		server_capabilities, server_version
		sqlstate, port, protocol_version,
		server_language
		thread_id, user, warning_count
	object result
		current_field, field_count,
		lengths, num_rows, type
	object stmt
		query, param_count, field_count,
		id, errno, error, sqlstate
- added constructor
- minor fixes, prototypes
| -rw-r--r-- | ext/mysqli/config.m4 | 2 | ||||
| -rw-r--r-- | ext/mysqli/mysqli.c | 131 | ||||
| -rw-r--r-- | ext/mysqli/mysqli_api.c | 46 | ||||
| -rw-r--r-- | ext/mysqli/mysqli_fe.c | 27 | ||||
| -rw-r--r-- | ext/mysqli/mysqli_nonapi.c | 35 | ||||
| -rw-r--r-- | ext/mysqli/mysqli_prop.c | 181 | ||||
| -rw-r--r-- | ext/mysqli/php_mysqli.h | 48 | 
7 files changed, 437 insertions, 33 deletions
diff --git a/ext/mysqli/config.m4 b/ext/mysqli/config.m4 index 6c1bee819b..ddb97bd9a9 100644 --- a/ext/mysqli/config.m4 +++ b/ext/mysqli/config.m4 @@ -57,5 +57,5 @@ if test "$PHP_MYSQLI" != "no" || test "$PHP_EMBEDDED_MYSQLI" != "no"; then    ])    PHP_SUBST(MYSQLI_SHARED_LIBADD) -  PHP_NEW_EXTENSION(mysqli, mysqli.c mysqli_api.c mysqli_nonapi.c mysqli_fe.c mysqli_profiler.c mysqli_profiler_com.c, $ext_shared) +  PHP_NEW_EXTENSION(mysqli, mysqli.c mysqli_api.c mysqli_prop.c mysqli_nonapi.c mysqli_fe.c mysqli_profiler.c mysqli_profiler_com.c, $ext_shared)  fi diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c index 8e0cfc2911..30a0c13eb8 100644 --- a/ext/mysqli/mysqli.c +++ b/ext/mysqli/mysqli.c @@ -36,7 +36,20 @@  ZEND_DECLARE_MODULE_GLOBALS(mysqli)  static zend_object_handlers mysqli_object_handlers; +static HashTable classes; +static HashTable mysqli_link_properties; +static HashTable mysqli_result_properties; +static HashTable mysqli_stmt_properties;  PR_MAIN *prmain; +extern void php_mysqli_connect(INTERNAL_FUNCTION_PARAMETERS); + +typedef int (*mysqli_read_t)(mysqli_object *obj, zval **retval TSRMLS_DC); +typedef int (*mysqli_write_t)(mysqli_object *obj, zval *member, zval *newval TSRMLS_DC); + +typedef struct _mysqli_prop_handler { +	mysqli_read_t read_func; +	mysqli_write_t write_func; +} mysqli_prop_handler;  /* {{{ php_free_stmt_bind_buffer */  void php_free_stmt_bind_buffer(BIND_BUFFER bbuf, int type) @@ -96,6 +109,9 @@ static void mysqli_objects_dtor(void *object, zend_object_handle handle TSRMLS_D  	mysqli_object 	*intern = (mysqli_object *)object;  	MYSQLI_RESOURCE	*my_res = (MYSQLI_RESOURCE *)intern->ptr; +	zend_hash_destroy(intern->zo.properties); +	FREE_HASHTABLE(intern->zo.properties); +  	/* link object */  	if (intern->zo.ce == mysqli_link_class_entry) {  		if (my_res && my_res->ptr) { @@ -111,7 +127,7 @@ static void mysqli_objects_dtor(void *object, zend_object_handle handle TSRMLS_D  		}  	}  	my_efree(my_res); -	zend_objects_destroy_object(object, handle TSRMLS_CC); +	efree(object);  }  /* }}} */ @@ -122,7 +138,85 @@ static void mysqli_objects_clone(void *object, void **object_clone TSRMLS_DC)  	/* TODO */  }  /* }}} */ -	 + +/* {{{ mysqli_read_na */ +static int mysqli_read_na(mysqli_object *obj, zval **retval TSRMLS_DC) +{ +	*retval = NULL; +	php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot read property"); +	return FAILURE; +} +/* }}} */ + +/* {{{ mysqli_write_na */ +static int mysqli_write_na(mysqli_object *obj, zval *member, zval *newval TSRMLS_DC) +{ +	php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot write property"); +	return FAILURE; +} +/* }}} */ + +/* {{{ mysqli_read_property */ +zval *mysqli_read_property(zval *object, zval *member, zend_bool silent TSRMLS_DC) +{ +	zval tmp_member; +	zval *retval; +	mysqli_object *obj; +	mysqli_prop_handler *hnd; +	zend_object_handlers *std_hnd; +	int ret; + + 	if (member->type != IS_STRING) { +		tmp_member = *member; +		zval_copy_ctor(&tmp_member); +		convert_to_string(&tmp_member); +		member = &tmp_member; +	} + +	ret = FAILURE; +	obj = (mysqli_object *)zend_objects_get_address(object TSRMLS_CC); + +	if (obj->prop_handler != NULL) { +		ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd); +	} +	if (ret == SUCCESS) { +		ret = hnd->read_func(obj, &retval TSRMLS_CC); +		if (ret == SUCCESS) { +			/* ensure we're creating a temporary variable */ +			retval->refcount = 0; +		} else { +			retval = EG(uninitialized_zval_ptr); +		} +	} else { +		std_hnd = zend_get_std_object_handlers(); +		retval = std_hnd->read_property(object, member, silent TSRMLS_CC); +	} + +	if (member == &tmp_member) { +		zval_dtor(member); +	} + + +	return(retval); +} +/* }}} */ + +/* {{{ mysqli_write_property */ +void mysqli_write_property(zval *object, zval *member, zval *value TSRMLS_DC) +{ +	return; +} +/* }}} */ + +void mysqli_add_property(HashTable *h, char *pname, mysqli_read_t r_func, mysqli_write_t w_func TSRMLS_DC) { +	mysqli_prop_handler		p; + +	p.read_func = (r_func) ? r_func : mysqli_read_na;  +	p.write_func = (w_func) ? w_func : mysqli_write_na; + +	zend_hash_add(h, pname, strlen(pname) + 1, &p, sizeof(mysqli_prop_handler), NULL); +} +  /* {{{ mysqli_objects_new   */  PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry *class_type TSRMLS_DC) @@ -136,6 +230,9 @@ PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry *class_  	intern->zo.in_get = 0;  	intern->zo.in_set = 0;  	intern->ptr = NULL; +	intern->prop_handler = NULL; + +	zend_hash_find(&classes, class_type->name, class_type->name_length + 1, (void **) &intern->prop_handler);  	ALLOC_HASHTABLE(intern->zo.properties);  	zend_hash_init(intern->zo.properties, 0, NULL, ZVAL_PTR_DTOR, 0); @@ -197,6 +294,7 @@ static void php_mysqli_init_globals(zend_mysqli_globals *mysqli_globals)  	mysqli_globals->default_pw = NULL;  	mysqli_globals->default_socket = NULL;  	mysqli_globals->profiler = 0; +	mysqli_globals->multi_query = 0;  }  /* }}} */ @@ -204,16 +302,40 @@ static void php_mysqli_init_globals(zend_mysqli_globals *mysqli_globals)   */  PHP_MINIT_FUNCTION(mysqli)  { +	zend_class_entry *ce;  	ZEND_INIT_MODULE_GLOBALS(mysqli, php_mysqli_init_globals, NULL);  	REGISTER_INI_ENTRIES();  	memcpy(&mysqli_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));  	mysqli_object_handlers.clone_obj = zend_objects_store_clone_obj; +	mysqli_object_handlers.read_property = mysqli_read_property; +	mysqli_object_handlers.write_property = mysqli_write_property; +	mysqli_object_handlers.get_property_ptr_ptr = NULL; +//	mysqli_object_handlers.call_method = php_mysqli_connect; + +/* todo: call method */ + +	zend_hash_init(&classes, 0, NULL, NULL, 1);  	REGISTER_MYSQLI_CLASS_ENTRY("mysqli", mysqli_link_class_entry, mysqli_link_methods); + +	ce = mysqli_link_class_entry; +	zend_hash_init(&mysqli_link_properties, 0, NULL, NULL, 1); +	MYSQLI_ADD_PROPERTIES(&mysqli_link_properties, mysqli_link_property_entries); +	zend_hash_add(&classes, ce->name, ce->name_length+1, &mysqli_link_properties, sizeof(mysqli_link_properties), NULL); +  	REGISTER_MYSQLI_CLASS_ENTRY("mysqli_result", mysqli_result_class_entry, mysqli_result_methods); +	ce = mysqli_result_class_entry; +	zend_hash_init(&mysqli_result_properties, 0, NULL, NULL, 1); +	MYSQLI_ADD_PROPERTIES(&mysqli_result_properties, mysqli_result_property_entries); +	zend_hash_add(&classes, ce->name, ce->name_length+1, &mysqli_result_properties, sizeof(mysqli_result_properties), NULL); +  	REGISTER_MYSQLI_CLASS_ENTRY("mysqli_stmt", mysqli_stmt_class_entry, mysqli_stmt_methods); +	ce = mysqli_stmt_class_entry; +	zend_hash_init(&mysqli_stmt_properties, 0, NULL, NULL, 1); +	MYSQLI_ADD_PROPERTIES(&mysqli_stmt_properties, mysqli_stmt_property_entries); +	zend_hash_add(&classes, ce->name, ce->name_length+1, &mysqli_stmt_properties, sizeof(mysqli_stmt_properties), NULL);  	/* mysqli_options */  	REGISTER_LONG_CONSTANT("MYSQLI_READ_DEFAULT_GROUP", MYSQL_READ_DEFAULT_GROUP, CONST_CS | CONST_PERSISTENT); @@ -310,6 +432,9 @@ PHP_MINIT_FUNCTION(mysqli)   */  PHP_MSHUTDOWN_FUNCTION(mysqli)  { +	zend_hash_destroy(&mysqli_link_properties); +	zend_hash_destroy(&classes); +  	UNREGISTER_INI_ENTRIES();  	return SUCCESS;  } @@ -421,7 +546,7 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags  	fields = mysql_fetch_fields(result);  	if (!(row = mysql_fetch_row(result))) { -		RETURN_FALSE; +		RETURN_NULL();  	}  	array_init(return_value); diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index 6c90bb63c0..f01ba5c79c 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -372,6 +372,7 @@ PHP_FUNCTION(mysqli_change_user)  	MYSQLI_PROFILER_COMMAND_START(prcommand, prmysql);  	rc = mysql_change_user(mysql, user, password, dbname);  	MYSQLI_PROFILER_COMMAND_RETURNLONG(prcommand, rc); +  	if (rc) {  		RETURN_FALSE;  	} @@ -1014,7 +1015,7 @@ PHP_FUNCTION(mysqli_get_host_info)  }  /* }}} */ -/* {{{ proto int mysqli_get_proto_info(object link)  +/* {{{ proto int mysqli_get_proto_info(object link)     Get MySQL protocol information */  PHP_FUNCTION(mysqli_get_proto_info)  { @@ -1160,6 +1161,44 @@ PHP_FUNCTION(mysqli_master_query) {  }  /* }}} */ +/* {{{ proto bool mysqli_more_results(object link) +   check if there any more query results from a multi query */ +PHP_FUNCTION(mysqli_more_results) { +	MYSQL			*mysql; +	zval			*mysql_link; +	PR_MYSQL		*prmysql; + +	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { +		return; +	} +	MYSQLI_FETCH_RESOURCE(mysql, MYSQL *, prmysql, PR_MYSQL *, &mysql_link, "mysqli_link"); + +	if (!mysql_more_results(mysql)) { +		RETURN_FALSE; +	}	 +	RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto bool mysqli_next_result(object link) +   read next result from multi_query */ +PHP_FUNCTION(mysqli_next_result) { +	MYSQL			*mysql; +	zval			*mysql_link; +	PR_MYSQL		*prmysql; + +	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { +		return; +	} +	MYSQLI_FETCH_RESOURCE(mysql, MYSQL *, prmysql, PR_MYSQL *, &mysql_link, "mysqli_link"); + +	if (mysql_next_result(mysql)) { +		RETURN_FALSE; +	}	 +	RETURN_TRUE; +} +/* }}} */ +  /* {{{ proto int mysqli_num_fields(object result)     Get number of fields in result */  PHP_FUNCTION(mysqli_num_fields) @@ -1413,7 +1452,7 @@ PHP_FUNCTION(mysqli_real_connect)  	MYSQLI_FETCH_RESOURCE(mysql, MYSQL *, prmysql, PR_MYSQL *, &mysql_link, "mysqli_link");  	/* remove some insecure options */ -	flags ^= CLIENT_MULTI_QUERIES;   /* don't allow multi_queries via connect parameter */ +	flags ^= CLIENT_MULTI_STATEMENTS;   /* don't allow multi_queries via connect parameter */  	if (PG(open_basedir) && strlen(PG(open_basedir))) {  		flags ^= CLIENT_LOCAL_FILES;  	} @@ -1446,6 +1485,7 @@ PHP_FUNCTION(mysqli_real_query)  	}  	MYSQLI_FETCH_RESOURCE(mysql, MYSQL *, prmysql, PR_MYSQL *, &mysql_link, "mysqli_link"); +	MYSQLI_DISABLE_MQ;  	if (mysql_real_query(mysql, query, query_len)) {  		RETURN_FALSE;  	}	 @@ -1925,8 +1965,10 @@ PHP_FUNCTION(mysqli_store_result)  	MYSQLI_FETCH_RESOURCE(mysql, MYSQL *, prmysql, PR_MYSQL *, &mysql_link, "mysqli_link");  	if (!(result = mysql_store_result(mysql))) { +		MYSQLI_DISABLE_MQ;  		RETURN_FALSE;  	} +//	MYSQLI_DISABLE_MQ;  	mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));  	mysqli_resource->ptr = (void *)result;  	MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);	 diff --git a/ext/mysqli/mysqli_fe.c b/ext/mysqli/mysqli_fe.c index 93b5aaaac4..7e8eb87595 100644 --- a/ext/mysqli/mysqli_fe.c +++ b/ext/mysqli/mysqli_fe.c @@ -87,6 +87,7 @@ function_entry mysqli_functions[] = {  	PHP_FE(mysqli_free_result,							NULL)  	PHP_FE(mysqli_get_client_info,						NULL)  	PHP_FE(mysqli_get_host_info,						NULL) +	PHP_FE(mysqli_get_metadata,							NULL)  	PHP_FE(mysqli_get_proto_info,						NULL)  	PHP_FE(mysqli_get_server_info,						NULL)  	PHP_FE(mysqli_get_server_version,					NULL) @@ -95,13 +96,14 @@ function_entry mysqli_functions[] = {  	PHP_FE(mysqli_insert_id,							NULL)  	PHP_FE(mysqli_kill,									NULL)  	PHP_FE(mysqli_master_query,							NULL) +	PHP_FE(mysqli_more_results,							NULL) +	PHP_FE(mysqli_next_result,							NULL)  	PHP_FE(mysqli_num_fields,							NULL)  	PHP_FE(mysqli_num_rows,								NULL)  	PHP_FE(mysqli_options, 								NULL)  	PHP_FE(mysqli_param_count,							NULL)  	PHP_FE(mysqli_ping,									NULL)  	PHP_FE(mysqli_prepare,								NULL) -	PHP_FE(mysqli_get_metadata,							NULL)  	PHP_FE(mysqli_profiler,								NULL)  	PHP_FE(mysqli_query,								NULL)  	PHP_FE(mysqli_read_query_result,					NULL) @@ -153,7 +155,6 @@ function_entry mysqli_functions[] = {   * Every user visible function must have an entry in mysqli_functions[].   */  function_entry mysqli_link_methods[] = { -	PHP_FALIAS(affected_rows,mysqli_affected_rows,NULL)  	PHP_FALIAS(autocommit,mysqli_autocommit,NULL)  	PHP_FALIAS(change_user,mysqli_change_user,NULL)  	PHP_FALIAS(character_set_name,mysqli_character_set_name,NULL) @@ -167,18 +168,18 @@ function_entry mysqli_link_methods[] = {  	PHP_FALIAS(dump_debug_info,mysqli_dump_debug_info,NULL)  	PHP_FALIAS(enable_reads_from_master,mysqli_enable_reads_from_master,NULL)  	PHP_FALIAS(enable_rpl_parse,mysqli_enable_rpl_parse,NULL) -	PHP_FALIAS(errno,mysqli_errno,NULL) -	PHP_FALIAS(error,mysqli_error,NULL)  	PHP_FALIAS(get_client_info,mysqli_get_client_info,NULL)  	PHP_FALIAS(get_host_info,mysqli_get_host_info,NULL) -	PHP_FALIAS(get_proto_info,mysqli_get_proto_info,NULL)  	PHP_FALIAS(get_server_info,mysqli_get_server_info,NULL) -	PHP_FALIAS(get_server_version,mysqli_get_server_version,NULL)  	PHP_FALIAS(init,mysqli_init,NULL)  	PHP_FALIAS(info,mysqli_info,NULL)  	PHP_FALIAS(insert_id,mysqli_insert_id,NULL)  	PHP_FALIAS(kill,mysqli_kill,NULL)  	PHP_FALIAS(master_query,mysqli_master_query,NULL) +	PHP_FALIAS(mysqli, mysqli_connect, NULL) +	PHP_FALIAS(multi_query,mysqli_multi_query,NULL) +	PHP_FALIAS(more_results,mysqli_more_results, NULL) +	PHP_FALIAS(next_result, mysqli_next_result, NULL)  	PHP_FALIAS(options,mysqli_options,NULL)  	PHP_FALIAS(ping,mysqli_ping,NULL)  	PHP_FALIAS(prepare,mysqli_prepare,NULL) @@ -196,16 +197,11 @@ function_entry mysqli_link_methods[] = {  	PHP_FALIAS(select_db,mysqli_select_db,NULL)  	PHP_FALIAS(set_opt, mysqli_options,NULL)  	PHP_FALIAS(slave_query,mysqli_slave_query,NULL) -#if MYSQL_VERSION_ID >= 40101 -	PHP_FALIAS(sqlstate, mysqli_sqlstate,NULL) -#endif  	PHP_FALIAS(ssl_set,mysqli_ssl_set,NULL)  	PHP_FALIAS(stat,mysqli_stat,NULL)  	PHP_FALIAS(store_result,mysqli_store_result,NULL) -	PHP_FALIAS(thread_id, mysqli_thread_id,NULL)  	PHP_FALIAS(thread_safe,mysqli_thread_safe,NULL)  	PHP_FALIAS(use_result,mysqli_use_result,NULL) -	PHP_FALIAS(warning_count,mysqli_warning_count,NULL)  	{NULL, NULL, NULL}  };  /* }}} */ @@ -221,7 +217,6 @@ function_entry mysqli_result_methods[] = {  	PHP_FALIAS(fetch_field,mysqli_fetch_field,NULL)  	PHP_FALIAS(fetch_fields,mysqli_fetch_fields,NULL)  	PHP_FALIAS(fetvh_field_direct,mysqli_fetch_field_direct,NULL) -	PHP_FALIAS(fetch_lengths,mysqli_fetch_lengths,NULL)  	PHP_FALIAS(fetch_array,mysqli_fetch_array,NULL)  	PHP_FALIAS(fetch_assoc,mysqli_fetch_assoc,NULL)   	PHP_FALIAS(fetch_object,mysqli_fetch_object,NULL)  @@ -230,8 +225,6 @@ function_entry mysqli_result_methods[] = {  	PHP_FALIAS(field_seek,mysqli_field_seek,NULL)  	PHP_FALIAS(field_tell,mysqli_field_tell,NULL)  	PHP_FALIAS(free_result,mysqli_free_result,NULL) -	PHP_FALIAS(num_fields,mysqli_num_fields,NULL) -	PHP_FALIAS(num_rows,mysqli_num_rows,NULL)  	{NULL, NULL, NULL}  };  /* }}} */ @@ -246,18 +239,12 @@ function_entry mysqli_stmt_methods[] = {  	PHP_FALIAS(bind_result,mysqli_bind_result, all_args_by_ref)  	PHP_FALIAS(close,mysqli_stmt_close,NULL)  	PHP_FALIAS(data_seek,mysqli_stmt_data_seek,NULL) -	PHP_FALIAS(errno,mysqli_stmt_errno,NULL) -	PHP_FALIAS(error,mysqli_stmt_error,NULL)  	PHP_FALIAS(execute,mysqli_execute,NULL)  	PHP_FALIAS(fetch,mysqli_fetch,NULL)  	PHP_FALIAS(get_metadata, mysqli_get_metadata,NULL)  	PHP_FALIAS(num_rows, mysqli_stmt_num_rows,NULL) -	PHP_FALIAS(param_count,mysqli_param_count,NULL)  	PHP_FALIAS(send_long_data,mysqli_send_long_data,NULL)  	PHP_FALIAS(store_result,mysqli_stmt_store_result,NULL) -#if MYSQL_VERSION_ID >= 40101 -	PHP_FALIAS(sqlstate, mysqli_stmt_sqlstate,NULL) -#endif  	{NULL, NULL, NULL}  };  /* }}} */ diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c index d5c8f22b3f..ed09af20e5 100644 --- a/ext/mysqli/mysqli_nonapi.c +++ b/ext/mysqli/mysqli_nonapi.c @@ -171,7 +171,11 @@ PHP_FUNCTION(mysqli_connect_errno)     Returns the text of the error message from previous MySQL operation */  PHP_FUNCTION(mysqli_connect_error)   { -	RETURN_STRING(MyG(error_msg),1); +	if (MyG(error_msg)) { +		RETURN_STRING(MyG(error_msg),1); +	} else { +		RETURN_NULL(); +	}  }  /* }}} */ @@ -199,8 +203,31 @@ PHP_FUNCTION(mysqli_fetch_object)  }  /* }}} */ -/* {{{ proto resource mysqli_query(object link, string query [,int resultmode]) -   Send a MySQL query */ +/* {{{ proto bool mysqli_multi_query(object link, string query) +   Binary-safe version of mysql_query() */ +PHP_FUNCTION(mysqli_multi_query) +{ +	MYSQL			*mysql; +	zval			*mysql_link; +	char			*query = NULL; +	unsigned int 	query_len; +	PR_MYSQL		*prmysql; + +	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, MYSQL *, prmysql, PR_MYSQL *, &mysql_link, "mysqli_link"); + +	MYSQLI_ENABLE_MQ;	 +	if (mysql_real_query(mysql, query, query_len)) { +		MYSQLI_DISABLE_MQ; +		RETURN_FALSE; +	}	 +	RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto resource mysqli_query(object link, string query [,int resultmode]) */  PHP_FUNCTION(mysqli_query)  {  	MYSQL				*mysql; @@ -231,6 +258,8 @@ PHP_FUNCTION(mysqli_query)  		}  	} +	MYSQLI_DISABLE_MQ; +  	if (mysql_real_query(mysql, query, query_len)) {  		RETURN_FALSE;  	} diff --git a/ext/mysqli/mysqli_prop.c b/ext/mysqli/mysqli_prop.c new file mode 100644 index 0000000000..cfb2fa2c91 --- /dev/null +++ b/ext/mysqli/mysqli_prop.c @@ -0,0 +1,181 @@ +/* +  +----------------------------------------------------------------------+ +  | PHP Version 5                                                        | +  +----------------------------------------------------------------------+ +  | Copyright (c) 1997-2002 The PHP Group                                | +  +----------------------------------------------------------------------+ +  | This source file is subject to version 3.0 of the PHP license,       | +  | that is bundled with this package in the file LICENSE, and is        | +  | available through the world-wide-web at the following url:           | +  | http://www.php.net/license/3_0.txt.                                  | +  | If you did not receive a copy of the PHP license and are unable to   | +  | 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>                                | +  +----------------------------------------------------------------------+ + +  $Id$  +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <signal.h> + +#include "php.h" +#include "php_ini.h" +#include "ext/standard/info.h" +#include "php_mysqli.h" + +#define MYSQLI_MAP_PROPERTY_LONG(__func, __type, __val)\ +int __func(mysqli_object *obj, zval **retval TSRMLS_DC) \ +{\ +	__type *p = (__type *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;\ +	ALLOC_ZVAL(*retval);\ +	if (!p) {\ +		ZVAL_NULL(*retval);\ +	} else {\ +		ZVAL_LONG(*retval, (long)p->__val);\ +	}\ +	return SUCCESS;\ +}\ + +#define MYSQLI_MAP_PROPERTY_STRING(__func, __type, __val)\ +int __func(mysqli_object *obj, zval **retval TSRMLS_DC) \ +{\ +	__type *p = (__type *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;\ +	ALLOC_ZVAL(*retval);\ +	if (!p) {\ +		ZVAL_NULL(*retval);\ +	} else {\ +		if (!p->__val) {\ +			ZVAL_NULL(*retval);\ +		} else {\ +			ZVAL_STRING(*retval, p->__val, 1);\ +		}\ +	}\ +	return SUCCESS;\ +}\ + +/* {{{ property link_client_version_read */ +int link_client_version_read(mysqli_object *obj, zval **retval TSRMLS_DC) { +	ALLOC_ZVAL(*retval); +	ZVAL_STRING(*retval, MYSQL_SERVER_VERSION, 1); +	return SUCCESS; +} +/* }}} */ + +/* link properties */ +MYSQLI_MAP_PROPERTY_LONG(link_affected_rows_read, MYSQL, affected_rows); +MYSQLI_MAP_PROPERTY_LONG(link_client_flags_read, MYSQL, client_flag); +MYSQLI_MAP_PROPERTY_LONG(link_errno_read, MYSQL, net.last_errno); +MYSQLI_MAP_PROPERTY_STRING(link_error_read, MYSQL, net.last_error); +MYSQLI_MAP_PROPERTY_LONG(link_field_count_read, MYSQL, field_count); +MYSQLI_MAP_PROPERTY_STRING(link_host_read, MYSQL, host); +MYSQLI_MAP_PROPERTY_STRING(link_host_info_read, MYSQL, host_info); +MYSQLI_MAP_PROPERTY_STRING(link_info_read, MYSQL, info); +MYSQLI_MAP_PROPERTY_LONG(link_port_read, MYSQL, port); +MYSQLI_MAP_PROPERTY_LONG(link_protocol_version_read, MYSQL, protocol_version); +MYSQLI_MAP_PROPERTY_LONG(link_server_capabilities_read, MYSQL, server_capabilities); +MYSQLI_MAP_PROPERTY_LONG(link_server_language_read, MYSQL, server_language); +MYSQLI_MAP_PROPERTY_STRING(link_server_version_read, MYSQL, server_version); +MYSQLI_MAP_PROPERTY_STRING(link_sqlstate_read, MYSQL, net.sqlstate); +MYSQLI_MAP_PROPERTY_LONG(link_thread_id_read, MYSQL, thread_id); +MYSQLI_MAP_PROPERTY_STRING(link_user_read, MYSQL, user); +MYSQLI_MAP_PROPERTY_LONG(link_warning_count_read, MYSQL, warning_count); + +/* result properties */ + +/* {{{ property result_type_read */ +int result_type_read(mysqli_object *obj, zval **retval TSRMLS_DC) { +	MYSQL_RES *p = (MYSQL_RES *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; + +	ALLOC_ZVAL(*retval); +	if (!p) { +		ZVAL_NULL(*retval); +	} else { +		ZVAL_LONG(*retval, (p->data) ? MYSQLI_STORE_RESULT : MYSQLI_USE_RESULT); +	} +	return SUCCESS; +} +/* }}} */ + +/* {{{ property result_lengths_read */ +int result_lengths_read(mysqli_object *obj, zval **retval TSRMLS_DC) { +	MYSQL_RES *p = (MYSQL_RES *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; + +	ALLOC_ZVAL(*retval); +	if (!p || !p->field_count) { +		ZVAL_NULL(*retval); +	} else { +		ulong i; +		zval *l; +	 +		array_init(*retval); + +		for (i=0; i < p->field_count; i++) { +			MAKE_STD_ZVAL(l); +			ZVAL_LONG(l, p->lengths[i]); +			add_index_zval(*retval, i, l); +		}	 +	} +	return SUCCESS; +} +/* }}} */ + +MYSQLI_MAP_PROPERTY_LONG(result_current_field_read, MYSQL_RES, current_field); +MYSQLI_MAP_PROPERTY_LONG(result_field_count_read, MYSQL_RES, field_count); +MYSQLI_MAP_PROPERTY_LONG(result_num_rows_read, MYSQL_RES, row_count); + +/* statement properties */ +MYSQLI_MAP_PROPERTY_STRING(stmt_query_read, MYSQL_STMT, query); +MYSQLI_MAP_PROPERTY_LONG(stmt_param_count_read, MYSQL_STMT, param_count); +MYSQLI_MAP_PROPERTY_LONG(stmt_field_count_read, MYSQL_STMT, field_count); +MYSQLI_MAP_PROPERTY_LONG(stmt_id_read, MYSQL_STMT, stmt_id); +MYSQLI_MAP_PROPERTY_LONG(stmt_errno_read, MYSQL_STMT, last_errno); +MYSQLI_MAP_PROPERTY_STRING(stmt_error_read, MYSQL_STMT, last_error); +MYSQLI_MAP_PROPERTY_STRING(stmt_sqlstate_read, MYSQL_STMT, sqlstate); + +mysqli_property_entry mysqli_link_property_entries[] = { +	{"affected_rows", link_affected_rows_read, NULL}, +	{"client_flags", link_client_flags_read, NULL}, +	{"client_version", link_client_version_read, NULL}, +	{"errno", link_errno_read, NULL}, +	{"error", link_error_read, NULL}, +	{"field_count", link_field_count_read, NULL}, +	{"host", link_host_read, NULL}, +	{"host_info", link_host_info_read, NULL}, +	{"info", link_info_read, NULL}, +	{"server_capabilities", link_server_capabilities_read, NULL}, +	{"server_version", link_server_version_read, NULL}, +	{"sqlstate", link_sqlstate_read, NULL}, +	{"port", link_port_read, NULL}, +	{"protocol_version", link_protocol_version_read, NULL}, +	{"server_language", link_protocol_version_read, NULL}, +	{"thread_id", link_thread_id_read, NULL}, +	{"user", link_user_read, NULL}, +	{"warning_count", link_warning_count_read, NULL}, +	{NULL, NULL, NULL}	 +}; + +mysqli_property_entry mysqli_result_property_entries[] = { +	{"current_field", result_current_field_read, NULL}, +	{"field_count", result_field_count_read, NULL}, +	{"lengths", result_lengths_read, NULL}, +	{"num_rows", result_num_rows_read, NULL}, +	{"type", result_type_read, NULL}, +	{NULL, NULL, NULL} +}; + +mysqli_property_entry mysqli_stmt_property_entries[] = { +	{"query", stmt_query_read, NULL}, +	{"param_count", stmt_param_count_read, NULL}, +	{"field_count", stmt_field_count_read, NULL}, +	{"id", stmt_id_read, NULL}, +	{"errno", stmt_errno_read, NULL}, +	{"error", stmt_error_read, NULL}, +	{"sqlstate", stmt_sqlstate_read, NULL}, +	{NULL, NULL, NULL} +}; diff --git a/ext/mysqli/php_mysqli.h b/ext/mysqli/php_mysqli.h index 0d0f15f1dd..2b35876723 100644 --- a/ext/mysqli/php_mysqli.h +++ b/ext/mysqli/php_mysqli.h @@ -57,10 +57,17 @@ typedef struct {  } MYSQLI_RESOURCE;  typedef struct _mysqli_object { -	zend_object zo; -	void *ptr; +	zend_object 	zo; +	void 			*ptr; +	HashTable 		*prop_handler;  } mysqli_object; /* extends zend_object */ +typedef struct _mysqli_property_entry { +	char *pname; +	int (*r_func)(mysqli_object *obj, zval **retval TSRMLS_DC); +	int (*w_func)(mysqli_object *obj, zval **retval TSRMLS_DC); +} mysqli_property_entry; +  #define MYSQLI_PR_MAIN		0  #define MYSQLI_PR_MYSQL		1  #define MYSQLI_PR_QUERY		2 @@ -90,6 +97,10 @@ extern function_entry mysqli_functions[];  extern function_entry mysqli_link_methods[];  extern function_entry mysqli_stmt_methods[];  extern function_entry mysqli_result_methods[]; +extern mysqli_property_entry mysqli_link_property_entries[]; +extern mysqli_property_entry mysqli_result_property_entries[]; +extern mysqli_property_entry mysqli_stmt_property_entries[]; +  extern void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flag, int into_object);  extern void php_clear_stmt_bind(STMT *stmt);  extern void php_free_stmt_bind_buffer(BIND_BUFFER bbuf, int type); @@ -104,6 +115,16 @@ zend_class_entry _mysqli_result_class_entry;  PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry * TSRMLS_DC); +#define MYSQLI_DISABLE_MQ if (MyG(multi_query)) { \ +	mysql_set_server_option(mysql, MYSQL_OPTION_MULTI_STATEMENTS_OFF); \ +	MyG(multi_query) = 0; \ +}  + +#define MYSQLI_ENABLE_MQ if (!MyG(multi_query)) { \ +	mysql_set_server_option(mysql, MYSQL_OPTION_MULTI_STATEMENTS_ON); \ +	MyG(multi_query) = 1; \ +}  +  #define REGISTER_MYSQLI_CLASS_ENTRY(name, mysqli_entry, class_functions) { \  	INIT_CLASS_ENTRY(_##mysqli_entry,name,class_functions); \  	_##mysqli_entry.create_object = mysqli_objects_new; \ @@ -165,11 +186,20 @@ PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry * TSRML  	}					\  } -#define MYSQLI_STORE_RESULT 	0 +#define MYSQLI_ADD_PROPERTIES(a,b) \ +{ \ +	int i = 0; \ +	while (b[i].pname != NULL) { \ +		mysqli_add_property(a, b[i].pname, (mysqli_read_t)b[i].r_func, NULL TSRMLS_CC); \ +		i++; \ +	}\ +} + +#define MYSQLI_STORE_RESULT 0  #define MYSQLI_USE_RESULT 	1  /* for mysqli_fetch_assoc */ -#define MYSQLI_ASSOC		1 +#define MYSQLI_ASSOC	1  #define MYSQLI_NUM		2  #define MYSQLI_BOTH		3 @@ -194,6 +224,7 @@ PHP_RINIT_FUNCTION(mysqli);  PHP_RSHUTDOWN_FUNCTION(mysqli);  PHP_MINFO_FUNCTION(mysqli); +PHP_FUNCTION(mysqli);  PHP_FUNCTION(mysqli_affected_rows);  PHP_FUNCTION(mysqli_autocommit);  PHP_FUNCTION(mysqli_bind_param); @@ -241,6 +272,9 @@ PHP_FUNCTION(mysqli_insert_id);  PHP_FUNCTION(mysqli_init);  PHP_FUNCTION(mysqli_kill);  PHP_FUNCTION(mysqli_master_query); +PHP_FUNCTION(mysqli_more_results); +PHP_FUNCTION(mysqli_multi_query); +PHP_FUNCTION(mysqli_next_result);  PHP_FUNCTION(mysqli_num_fields);  PHP_FUNCTION(mysqli_num_rows);  PHP_FUNCTION(mysqli_options); @@ -301,11 +335,17 @@ ZEND_BEGIN_MODULE_GLOBALS(mysqli)  	long			error_no;  	char			*error_msg;  	unsigned int	profiler; +	unsigned int	multi_query;  #ifdef HAVE_EMBEDDED_MYSQLI  	unsigned int	embedded;  #endif  ZEND_END_MODULE_GLOBALS(mysqli) + +#define MYSQLI_PROPERTY(a) extern int a(mysqli_object *obj, zval **retval TSRMLS_DC) + +MYSQLI_PROPERTY(my_prop_link_host); +  #ifdef ZTS  #define MyG(v) TSRMG(mysqli_globals_id, zend_mysqli_globals *, v)  #else  | 
