mirror of
https://github.com/php/php-src.git
synced 2024-09-22 18:37:25 +00:00
Major changes for 4.1.2-alpha/4.1.3-beta:
- added container for mysql structure - added load data infile callback functions (currently disabled under win) Bug fixes: - fixed property changes (4.1.1 -> 4.1.2) - fixed memleak in mysqli_connect - fixed bug #28100 - fixed bug #28205 - fixed bug #28430
This commit is contained in:
parent
120625548d
commit
93bf6517df
@ -88,7 +88,7 @@ void php_free_stmt_bind_buffer(BIND_BUFFER bbuf, int type)
|
||||
/* }}} */
|
||||
|
||||
/* {{{ php_clear_stmt_bind */
|
||||
void php_clear_stmt_bind(STMT *stmt)
|
||||
void php_clear_stmt_bind(MY_STMT *stmt)
|
||||
{
|
||||
if (stmt->stmt) {
|
||||
mysql_stmt_close(stmt->stmt);
|
||||
@ -105,6 +105,22 @@ void php_clear_stmt_bind(STMT *stmt)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ php_clear_mysql */
|
||||
void php_clear_mysql(MY_MYSQL *mysql) {
|
||||
int i;
|
||||
|
||||
for (i=0; i < 3; i++) {
|
||||
if (&mysql->callback_func[i]) {
|
||||
zval_dtor(&mysql->callback_func[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (mysql->local_infile) {
|
||||
zval_ptr_dtor(&mysql->local_infile);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mysqli_objects_free_storage
|
||||
*/
|
||||
static void mysqli_objects_free_storage(zend_object *object TSRMLS_DC)
|
||||
@ -118,11 +134,15 @@ static void mysqli_objects_free_storage(zend_object *object TSRMLS_DC)
|
||||
/* link object */
|
||||
if (intern->zo.ce == mysqli_link_class_entry) {
|
||||
if (my_res && my_res->ptr) {
|
||||
mysql_close(my_res->ptr);
|
||||
MY_MYSQL *mysql = (MY_MYSQL *)my_res->ptr;
|
||||
|
||||
mysql_close(mysql->mysql);
|
||||
|
||||
php_clear_mysql(mysql);
|
||||
}
|
||||
} else if (intern->zo.ce == mysqli_stmt_class_entry) { /* stmt object */
|
||||
if (my_res && my_res->ptr) {
|
||||
php_clear_stmt_bind((STMT *)my_res->ptr);
|
||||
php_clear_stmt_bind((MY_STMT *)my_res->ptr);
|
||||
}
|
||||
} else if (intern->zo.ce == mysqli_result_class_entry) { /* result object */
|
||||
if (my_res && my_res->ptr) {
|
||||
@ -134,14 +154,6 @@ static void mysqli_objects_free_storage(zend_object *object TSRMLS_DC)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mysqli_objects_clone
|
||||
*/
|
||||
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)
|
||||
{
|
||||
@ -264,15 +276,20 @@ PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry *class_
|
||||
zend_object_value retval;
|
||||
mysqli_object *intern;
|
||||
zval *tmp;
|
||||
zend_class_entry *parent;
|
||||
|
||||
intern = emalloc(sizeof(mysqli_object));
|
||||
memset(intern, 0, sizeof(mysqli_object));
|
||||
intern->zo.ce = class_type;
|
||||
intern->zo.in_get = 0;
|
||||
intern->zo.in_set = 0;
|
||||
intern->ptr = NULL;
|
||||
intern->valid = 0;
|
||||
intern->prop_handler = NULL;
|
||||
|
||||
if ((parent = class_type->parent))
|
||||
{
|
||||
zend_hash_find(&classes, parent->name, parent->name_length + 1, (void **) &intern->prop_handler);
|
||||
}
|
||||
zend_hash_find(&classes, class_type->name, class_type->name_length + 1, (void **) &intern->prop_handler);
|
||||
|
||||
ALLOC_HASHTABLE(intern->zo.properties);
|
||||
@ -280,7 +297,7 @@ PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry *class_
|
||||
zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref,
|
||||
(void *) &tmp, sizeof(zval *));
|
||||
|
||||
retval.handle = zend_objects_store_put(intern, NULL, mysqli_objects_free_storage, NULL /*mysqli_objects_clone*/ TSRMLS_CC);
|
||||
retval.handle = zend_objects_store_put(intern, NULL, mysqli_objects_free_storage, NULL TSRMLS_CC);
|
||||
retval.handlers = &mysqli_object_handlers;
|
||||
|
||||
return retval;
|
||||
@ -353,7 +370,7 @@ PHP_MINIT_FUNCTION(mysqli)
|
||||
REGISTER_INI_ENTRIES();
|
||||
|
||||
memcpy(&mysqli_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
|
||||
mysqli_object_handlers.clone_obj = NULL /*zend_objects_store_clone_obj*/;
|
||||
mysqli_object_handlers.clone_obj = NULL;
|
||||
mysqli_object_handlers.read_property = mysqli_read_property;
|
||||
mysqli_object_handlers.write_property = mysqli_write_property;
|
||||
mysqli_object_handlers.get_property_ptr_ptr = NULL;
|
||||
@ -684,6 +701,198 @@ PHP_MYSQLI_API void php_mysqli_set_error(long mysql_errno, char *mysql_err TSRML
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#define ALLOC_CALLBACK_ARGS(a, b, c)\
|
||||
if (c) {\
|
||||
a = (zval ***)safe_emalloc(c, sizeof(zval **), 0);\
|
||||
for (i = b; i < c; i++) {\
|
||||
a[i] = emalloc(sizeof(zval *));\
|
||||
MAKE_STD_ZVAL(*a[i]);\
|
||||
}\
|
||||
}
|
||||
|
||||
#define FREE_CALLBACK_ARGS(a, b, c)\
|
||||
if (a) {\
|
||||
for (i=b; i < c; i++) {\
|
||||
zval_ptr_dtor(a[i]);\
|
||||
efree(a[i]);\
|
||||
}\
|
||||
efree(a);\
|
||||
}
|
||||
|
||||
#define LOCAL_INFILE_ERROR_MSG(source,dest)\
|
||||
memset(source, 0, LOCAL_INFILE_ERROR_LEN);\
|
||||
memcpy(source, dest, LOCAL_INFILE_ERROR_LEN-1);
|
||||
|
||||
/* {{{ php_local_infile_init
|
||||
*/
|
||||
int php_local_infile_init(void **ptr, const char *filename, void *userdata)
|
||||
{
|
||||
mysqli_local_infile *data;
|
||||
MY_MYSQL *mysql;
|
||||
zval ***callback_args;
|
||||
int argc = 2;
|
||||
int i, rc = 0;
|
||||
|
||||
/* save pointer to MY_MYSQL structure (userdata) */
|
||||
if (!(*ptr= data= ((mysqli_local_infile *)calloc(1, sizeof(mysqli_local_infile))))) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!(mysql = data->userdata = userdata)) {
|
||||
LOCAL_INFILE_ERROR_MSG(data->error_msg, ER(CR_UNKNOWN_ERROR));
|
||||
return 1;
|
||||
}
|
||||
|
||||
ALLOC_CALLBACK_ARGS(callback_args, 0, argc);
|
||||
|
||||
ZVAL_STRING(*callback_args[0], (char *)filename, 1);
|
||||
ZVAL_STRING(*callback_args[1], "", 1);
|
||||
|
||||
if (call_user_function_ex(EG(function_table),
|
||||
NULL,
|
||||
&mysql->callback_func[0],
|
||||
&mysql->local_infile,
|
||||
argc,
|
||||
callback_args,
|
||||
0,
|
||||
NULL TSRMLS_CC) == SUCCESS) {
|
||||
|
||||
/* check if user callback function returned a valid filehandle */
|
||||
convert_to_string_ex(callback_args[1]);
|
||||
|
||||
if (Z_TYPE_P(mysql->local_infile) != IS_RESOURCE) {
|
||||
if (!strlen(Z_STRVAL_P(*callback_args[1]))) {
|
||||
LOCAL_INFILE_ERROR_MSG(data->error_msg, ER(CR_UNKNOWN_ERROR));
|
||||
} else {
|
||||
LOCAL_INFILE_ERROR_MSG(data->error_msg, Z_STRVAL_P(*callback_args[1]));
|
||||
}
|
||||
rc = 1;
|
||||
} else {
|
||||
}
|
||||
} else {
|
||||
LOCAL_INFILE_ERROR_MSG(data->error_msg, "Can't execute load data local init callback function");
|
||||
rc = 1;
|
||||
}
|
||||
|
||||
FREE_CALLBACK_ARGS(callback_args, 0, argc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
int php_local_infile_read(void *ptr, char *buf, uint buf_len)
|
||||
{
|
||||
mysqli_local_infile *data;
|
||||
MY_MYSQL *mysql;
|
||||
zval ***callback_args;
|
||||
zval *retval;
|
||||
int argc = 4;
|
||||
int i;
|
||||
long rc;
|
||||
|
||||
data= (mysqli_local_infile *)ptr;
|
||||
|
||||
mysql = data->userdata;
|
||||
|
||||
ALLOC_CALLBACK_ARGS(callback_args, 1, argc);
|
||||
|
||||
/* set parameters: filepointer, buffer, buffer_len, errormsg */
|
||||
|
||||
callback_args[0] = &mysql->local_infile;
|
||||
ZVAL_STRING(*callback_args[1], "", 1);
|
||||
ZVAL_LONG(*callback_args[2], buf_len);
|
||||
ZVAL_STRING(*callback_args[3], "", 1);
|
||||
|
||||
if (call_user_function_ex(EG(function_table),
|
||||
NULL,
|
||||
&mysql->callback_func[1],
|
||||
&retval,
|
||||
argc,
|
||||
callback_args,
|
||||
0,
|
||||
NULL TSRMLS_CC) == SUCCESS) {
|
||||
|
||||
rc = Z_LVAL_P(retval);
|
||||
zval_ptr_dtor(&retval);
|
||||
|
||||
if (rc > 0) {
|
||||
if (rc > buf_len) {
|
||||
/* check buffer overflow */
|
||||
LOCAL_INFILE_ERROR_MSG(data->error_msg, "Read buffer too large");
|
||||
rc = -1;
|
||||
} else {
|
||||
memcpy(buf, Z_STRVAL_P(*callback_args[1]), rc);
|
||||
}
|
||||
}
|
||||
if (rc < 0) {
|
||||
LOCAL_INFILE_ERROR_MSG(data->error_msg, Z_STRVAL_P(*callback_args[3]));
|
||||
}
|
||||
} else {
|
||||
LOCAL_INFILE_ERROR_MSG(data->error_msg, "Can't execute load data local init callback function");
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
FREE_CALLBACK_ARGS(callback_args, 1, argc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* {{{ php_local_infile_error
|
||||
*/
|
||||
int php_local_infile_error(void *ptr, char *error_msg, uint error_msg_len)
|
||||
{
|
||||
mysqli_local_infile *data = (mysqli_local_infile *) ptr;
|
||||
if (data) {
|
||||
strcpy(error_msg, data->error_msg);
|
||||
return 2000;
|
||||
}
|
||||
strcpy(error_msg, ER(CR_OUT_OF_MEMORY));
|
||||
return CR_OUT_OF_MEMORY;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ php_local_infile_end
|
||||
*/
|
||||
void php_local_infile_end(void *ptr)
|
||||
{
|
||||
mysqli_local_infile *data;
|
||||
MY_MYSQL *mysql;
|
||||
zval ***callback_args;
|
||||
zval *retval;
|
||||
int argc = 1;
|
||||
int i;
|
||||
|
||||
data= (mysqli_local_infile *)ptr;
|
||||
|
||||
mysql = data->userdata;
|
||||
|
||||
ALLOC_CALLBACK_ARGS(callback_args, 1, argc);
|
||||
|
||||
/* set parameters: filepointer, buffer, buffer_len, errormsg */
|
||||
|
||||
callback_args[0] = &mysql->local_infile;
|
||||
|
||||
call_user_function_ex(EG(function_table),
|
||||
NULL,
|
||||
&mysql->callback_func[2],
|
||||
&retval,
|
||||
argc,
|
||||
callback_args,
|
||||
0,
|
||||
NULL TSRMLS_CC);
|
||||
|
||||
if (retval) {
|
||||
zval_ptr_dtor(&retval);
|
||||
}
|
||||
|
||||
if (mysql->local_infile) {
|
||||
zval_ptr_dtor(&mysql->local_infile);
|
||||
}
|
||||
|
||||
FREE_CALLBACK_ARGS(callback_args, 1, argc);
|
||||
// efree(data);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -96,6 +96,10 @@ function_entry mysqli_functions[] = {
|
||||
PHP_FE(mysqli_info, NULL)
|
||||
PHP_FE(mysqli_insert_id, NULL)
|
||||
PHP_FE(mysqli_kill, NULL)
|
||||
#ifndef PHP_WIN32
|
||||
PHP_FE(mysqli_set_local_infile_default, NULL)
|
||||
PHP_FE(mysqli_set_local_infile_handler, NULL)
|
||||
#endif
|
||||
PHP_FE(mysqli_master_query, NULL)
|
||||
PHP_FE(mysqli_more_results, NULL)
|
||||
PHP_FE(mysqli_multi_query, NULL)
|
||||
@ -126,6 +130,7 @@ function_entry mysqli_functions[] = {
|
||||
PHP_FE(mysqli_stmt_fetch, NULL)
|
||||
#ifndef HAVE_MYSQLI_OLDAPI
|
||||
PHP_FE(mysqli_stmt_free_result, NULL)
|
||||
PHP_FE(mysqli_stmt_insert_id, NULL)
|
||||
PHP_FE(mysqli_stmt_reset, NULL)
|
||||
#endif
|
||||
PHP_FE(mysqli_stmt_param_count, NULL)
|
||||
@ -200,6 +205,10 @@ function_entry mysqli_link_methods[] = {
|
||||
PHP_FALIAS(get_server_info,mysqli_get_server_info,NULL)
|
||||
PHP_FALIAS(init,mysqli_init,NULL)
|
||||
PHP_FALIAS(kill,mysqli_kill,NULL)
|
||||
#ifndef PHP_WIN32
|
||||
PHP_FALIAS(set_local_infile_default,mysqli_set_local_infile_default,NULL)
|
||||
PHP_FALIAS(set_local_infile_handler,mysqli_set_local_infile_handler,NULL)
|
||||
#endif
|
||||
PHP_FALIAS(master_query,mysqli_master_query,NULL)
|
||||
PHP_FALIAS(mysqli, mysqli_connect, NULL)
|
||||
PHP_FALIAS(multi_query,mysqli_multi_query,NULL)
|
||||
|
@ -33,7 +33,7 @@
|
||||
Open a connection to a mysql server */
|
||||
PHP_FUNCTION(mysqli_connect)
|
||||
{
|
||||
MYSQL *mysql = NULL;
|
||||
MY_MYSQL *mysql;
|
||||
MYSQLI_RESOURCE *mysqli_resource;
|
||||
zval *object = getThis();
|
||||
char *hostname = NULL, *username=NULL, *passwd=NULL, *dbname=NULL, *socket=NULL;
|
||||
@ -64,26 +64,31 @@ PHP_FUNCTION(mysqli_connect)
|
||||
}
|
||||
}
|
||||
|
||||
mysql = mysql_init(NULL);
|
||||
mysql = (MY_MYSQL *)calloc(1, sizeof(MY_MYSQL));
|
||||
|
||||
if (mysql_real_connect(mysql,hostname,username,passwd,dbname,port,socket,0) == NULL) {
|
||||
if (!(mysql->mysql = mysql_init(NULL))) {
|
||||
efree(mysql);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (mysql_real_connect(mysql->mysql,hostname,username,passwd,dbname,port,socket,0) == NULL) {
|
||||
/* Save error messages */
|
||||
|
||||
MYSQLI_REPORT_MYSQL_ERROR(mysql);
|
||||
php_mysqli_set_error(mysql_errno(mysql), (char *) mysql_error(mysql) TSRMLS_CC);
|
||||
MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
|
||||
php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql) TSRMLS_CC);
|
||||
|
||||
if (!(MyG(report_mode) & MYSQLI_REPORT_ERROR)) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", mysql_error(mysql));
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", mysql_error(mysql->mysql));
|
||||
}
|
||||
/* free mysql structure */
|
||||
mysql_close(mysql);
|
||||
mysql_close(mysql->mysql);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
/* clear error */
|
||||
php_mysqli_set_error(mysql_errno(mysql), (char *) mysql_error(mysql) TSRMLS_CC);
|
||||
php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql) TSRMLS_CC);
|
||||
|
||||
mysql->reconnect = MyG(reconnect);
|
||||
mysql->mysql->reconnect = MyG(reconnect);
|
||||
|
||||
mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
|
||||
mysqli_resource->ptr = (void *)mysql;
|
||||
@ -102,7 +107,7 @@ PHP_FUNCTION(mysqli_connect)
|
||||
Open a connection to a embedded mysql server */
|
||||
PHP_FUNCTION(mysqli_embedded_connect)
|
||||
{
|
||||
MYSQL *mysql;
|
||||
MY_MYSQL *mysql;
|
||||
MYSQLI_RESOURCE *mysqli_resource;
|
||||
zval *object = getThis();
|
||||
char *dbname = NULL;
|
||||
@ -117,21 +122,27 @@ PHP_FUNCTION(mysqli_embedded_connect)
|
||||
return;
|
||||
}
|
||||
|
||||
mysql = mysql_init(NULL);
|
||||
mysql = (MY_MYSQL *) calloc(1, sizeof(MY_MYSQL));
|
||||
|
||||
if (mysql_real_connect(mysql, NULL, NULL, NULL, dbname, 0, NULL, 0) == NULL) {
|
||||
MYSQLI_REPORT_MYSQL_ERROR(mysql);
|
||||
php_mysqli_set_error(mysql_errno(mysql), (char *) mysql_error(mysql) TSRMLS_CC);
|
||||
|
||||
if (!(MyG(report_mode) & MYSQLI_REPORT_ERROR)) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", mysql_error(mysql));
|
||||
}
|
||||
/* free mysql structure */
|
||||
mysql_close(mysql);
|
||||
if (!(mysql = mysql_init(NULL))) {
|
||||
efree(mysql);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
php_mysqli_set_error(mysql_errno(mysql), (char *) mysql_error(mysql) TSRMLS_CC);
|
||||
if (mysql_real_connect(mysql, NULL, NULL, NULL, dbname, 0, NULL, 0) == NULL) {
|
||||
MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
|
||||
php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql) TSRMLS_CC);
|
||||
|
||||
if (!(MyG(report_mode) & MYSQLI_REPORT_ERROR)) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", mysql_error(mysql->mysql));
|
||||
}
|
||||
/* free mysql structure */
|
||||
mysql_close(mysql->mysql);
|
||||
efree(mysql);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql) TSRMLS_CC);
|
||||
|
||||
mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
|
||||
mysqli_resource->ptr = (void *)mysql;
|
||||
@ -193,7 +204,7 @@ PHP_FUNCTION(mysqli_fetch_object)
|
||||
Binary-safe version of mysql_query() */
|
||||
PHP_FUNCTION(mysqli_multi_query)
|
||||
{
|
||||
MYSQL *mysql;
|
||||
MY_MYSQL *mysql;
|
||||
zval *mysql_link;
|
||||
char *query = NULL;
|
||||
unsigned int query_len;
|
||||
@ -201,11 +212,12 @@ PHP_FUNCTION(mysqli_multi_query)
|
||||
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 *, &mysql_link, "mysqli_link");
|
||||
MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link");
|
||||
|
||||
MYSQLI_ENABLE_MQ;
|
||||
if (mysql_real_query(mysql, query, query_len)) {
|
||||
if (mysql_real_query(mysql->mysql, query, query_len)) {
|
||||
MYSQLI_DISABLE_MQ;
|
||||
MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
RETURN_TRUE;
|
||||
@ -215,7 +227,7 @@ PHP_FUNCTION(mysqli_multi_query)
|
||||
/* {{{ proto mixed mysqli_query(object link, string query [,int resultmode]) */
|
||||
PHP_FUNCTION(mysqli_query)
|
||||
{
|
||||
MYSQL *mysql;
|
||||
MY_MYSQL *mysql;
|
||||
zval *mysql_link;
|
||||
MYSQLI_RESOURCE *mysqli_resource;
|
||||
MYSQL_RES *result;
|
||||
@ -226,31 +238,31 @@ PHP_FUNCTION(mysqli_query)
|
||||
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|l", &mysql_link, mysqli_link_class_entry, &query, &query_len, &resultmode) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
MYSQLI_FETCH_RESOURCE(mysql, MYSQL*, &mysql_link, "mysqli_link");
|
||||
MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL*, &mysql_link, "mysqli_link");
|
||||
|
||||
MYSQLI_DISABLE_MQ;
|
||||
|
||||
if (mysql_real_query(mysql, query, query_len)) {
|
||||
MYSQLI_REPORT_MYSQL_ERROR(mysql);
|
||||
if (mysql_real_query(mysql->mysql, query, query_len)) {
|
||||
MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
|
||||
if (!mysql_field_count(mysql)) {
|
||||
if (!mysql_field_count(mysql->mysql)) {
|
||||
if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
|
||||
php_mysqli_report_index(query, mysql->server_status TSRMLS_CC);
|
||||
php_mysqli_report_index(query, mysql->mysql->server_status TSRMLS_CC);
|
||||
}
|
||||
RETURN_TRUE;
|
||||
}
|
||||
|
||||
result = (resultmode == MYSQLI_USE_RESULT) ? mysql_use_result(mysql) : mysql_store_result(mysql);
|
||||
result = (resultmode == MYSQLI_USE_RESULT) ? mysql_use_result(mysql->mysql) : mysql_store_result(mysql->mysql);
|
||||
|
||||
if (!result) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
|
||||
php_mysqli_report_index(query, mysql->server_status TSRMLS_CC);
|
||||
php_mysqli_report_index(query, mysql->mysql->server_status TSRMLS_CC);
|
||||
}
|
||||
|
||||
mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
|
||||
|
@ -29,50 +29,50 @@
|
||||
#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_GET_MYSQL() \
|
||||
MYSQL *p = (MYSQL *)((MY_MYSQL *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr)->mysql;
|
||||
|
||||
#define MYSQLI_MAP_PROPERTY_LONG_LONG( __func, __type, __val)\
|
||||
#define MYSQLI_GET_RESULT() \
|
||||
MYSQL_RES *p = (MYSQL_RES *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr
|
||||
|
||||
#define MYSQLI_GET_STMT() \
|
||||
MYSQL_STMT *p = (MYSQL_STMT *)((MY_STMT *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr)->stmt
|
||||
|
||||
#define MYSQLI_MAP_PROPERTY_FUNC_LONG( __func, __int_func, __get_type, __ret_type)\
|
||||
int __func(mysqli_object *obj, zval **retval TSRMLS_DC) \
|
||||
{\
|
||||
__type *p = (__type *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; \
|
||||
__ret_type l;\
|
||||
__get_type;\
|
||||
ALLOC_ZVAL(*retval);\
|
||||
if (!p) {\
|
||||
ZVAL_NULL(*retval);\
|
||||
} else {\
|
||||
if (p->__val < LONG_MAX) { \
|
||||
ZVAL_LONG(*retval, (long)p->__val); \
|
||||
l = (__ret_type)__int_func(p);\
|
||||
if (l < LONG_MAX) {\
|
||||
ZVAL_LONG(*retval, l);\
|
||||
} else { \
|
||||
char ret[40]; \
|
||||
sprintf(ret, "%llu", p->__val); \
|
||||
sprintf(ret, "%llu", (my_ulonglong)l); \
|
||||
ZVAL_STRING(*retval, ret, 1); \
|
||||
} \
|
||||
}\
|
||||
return SUCCESS;\
|
||||
}
|
||||
|
||||
#define MYSQLI_MAP_PROPERTY_STRING( __func, __type, __val)\
|
||||
#define MYSQLI_MAP_PROPERTY_FUNC_STRING(__func, __int_func, __get_type)\
|
||||
int __func(mysqli_object *obj, zval **retval TSRMLS_DC)\
|
||||
{\
|
||||
__type *p = (__type *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;\
|
||||
char *c;\
|
||||
__get_type;\
|
||||
ALLOC_ZVAL(*retval);\
|
||||
if (!p) {\
|
||||
ZVAL_NULL(*retval);\
|
||||
} else {\
|
||||
if (!p->__val) {\
|
||||
c = (char *)__int_func(p);\
|
||||
if (!c) {\
|
||||
ZVAL_NULL(*retval);\
|
||||
} else {\
|
||||
ZVAL_STRING(*retval, p->__val, 1);\
|
||||
ZVAL_STRING(*retval, c, 1);\
|
||||
}\
|
||||
}\
|
||||
return SUCCESS;\
|
||||
@ -96,16 +96,6 @@ int link_connect_errno_read(mysqli_object *obj, zval **retval TSRMLS_DC)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ property link_server_version_read */
|
||||
int link_server_version_read(mysqli_object *obj, zval **retval TSRMLS_DC)
|
||||
{
|
||||
MYSQL *mysql = (MYSQL *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;
|
||||
ALLOC_ZVAL(*retval);
|
||||
ZVAL_LONG(*retval, mysql_get_server_version(mysql));
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ property link_connect_error_read */
|
||||
int link_connect_error_read(mysqli_object *obj, zval **retval TSRMLS_DC)
|
||||
{
|
||||
@ -115,27 +105,21 @@ int link_connect_error_read(mysqli_object *obj, zval **retval TSRMLS_DC)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* link properties */
|
||||
MYSQLI_MAP_PROPERTY_LONG_LONG(link_affected_rows_read, MYSQL, last_used_con->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_LONG(link_insert_id_read, MYSQL, last_used_con->insert_id);
|
||||
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_LONG(link_server_status_read, MYSQL, server_status);
|
||||
MYSQLI_MAP_PROPERTY_STRING(link_server_info_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);
|
||||
|
||||
/* link properties */
|
||||
MYSQLI_MAP_PROPERTY_FUNC_LONG(link_affected_rows_read, mysql_affected_rows, MYSQLI_GET_MYSQL(), my_ulonglong);
|
||||
MYSQLI_MAP_PROPERTY_FUNC_LONG(link_errno_read, mysql_errno, MYSQLI_GET_MYSQL(), ulong);
|
||||
MYSQLI_MAP_PROPERTY_FUNC_STRING(link_error_read, mysql_error, MYSQLI_GET_MYSQL());
|
||||
MYSQLI_MAP_PROPERTY_FUNC_LONG(link_field_count_read, mysql_field_count, MYSQLI_GET_MYSQL(), ulong);
|
||||
MYSQLI_MAP_PROPERTY_FUNC_STRING(link_host_info_read, mysql_get_host_info, MYSQLI_GET_MYSQL());
|
||||
MYSQLI_MAP_PROPERTY_FUNC_STRING(link_info_read, mysql_info, MYSQLI_GET_MYSQL());
|
||||
MYSQLI_MAP_PROPERTY_FUNC_LONG(link_insert_id_read, mysql_insert_id, MYSQLI_GET_MYSQL(), my_ulonglong);
|
||||
MYSQLI_MAP_PROPERTY_FUNC_LONG(link_protocol_version_read, mysql_get_proto_info, MYSQLI_GET_MYSQL(), ulong);
|
||||
MYSQLI_MAP_PROPERTY_FUNC_STRING(link_server_info_read, mysql_get_server_info, MYSQLI_GET_MYSQL());
|
||||
MYSQLI_MAP_PROPERTY_FUNC_LONG(link_server_version_read, mysql_get_server_version, MYSQLI_GET_MYSQL(), ulong);
|
||||
MYSQLI_MAP_PROPERTY_FUNC_STRING(link_sqlstate_read, mysql_sqlstate, MYSQLI_GET_MYSQL());
|
||||
MYSQLI_MAP_PROPERTY_FUNC_LONG(link_thread_id_read, mysql_thread_id, MYSQLI_GET_MYSQL(), ulong);
|
||||
MYSQLI_MAP_PROPERTY_FUNC_LONG(link_warning_count_read, mysql_warning_count, MYSQLI_GET_MYSQL(), ulong);
|
||||
/* result properties */
|
||||
|
||||
/* {{{ property result_type_read */
|
||||
@ -177,48 +161,37 @@ int result_lengths_read(mysqli_object *obj, zval **retval TSRMLS_DC)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
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_LONG(result_num_rows_read, MYSQL_RES, row_count);
|
||||
|
||||
MYSQLI_MAP_PROPERTY_FUNC_LONG(result_current_field_read, mysql_field_tell, MYSQLI_GET_RESULT(), ulong);
|
||||
MYSQLI_MAP_PROPERTY_FUNC_LONG(result_field_count_read, mysql_num_fields, MYSQLI_GET_RESULT(), ulong);
|
||||
MYSQLI_MAP_PROPERTY_FUNC_LONG(result_num_rows_read, mysql_num_rows, MYSQLI_GET_RESULT(), my_ulonglong);
|
||||
|
||||
/* statement properties */
|
||||
|
||||
#if MYSQL_VERSION_ID < 40102
|
||||
MYSQLI_MAP_PROPERTY_LONG_LONG(stmt_affected_rows_read, STMT, stmt->mysql->last_used_con->affected_rows);
|
||||
#else
|
||||
MYSQLI_MAP_PROPERTY_LONG_LONG(stmt_affected_rows_read, STMT, stmt->affected_rows);
|
||||
#endif
|
||||
MYSQLI_MAP_PROPERTY_LONG_LONG(stmt_num_rows_read, STMT, stmt->result->row_count);
|
||||
MYSQLI_MAP_PROPERTY_LONG(stmt_param_count_read, STMT, stmt->param_count);
|
||||
MYSQLI_MAP_PROPERTY_LONG(stmt_field_count_read, STMT, stmt->field_count);
|
||||
MYSQLI_MAP_PROPERTY_LONG(stmt_id_read, STMT, stmt->stmt_id);
|
||||
MYSQLI_MAP_PROPERTY_LONG(stmt_errno_read, STMT, stmt->last_errno);
|
||||
MYSQLI_MAP_PROPERTY_STRING(stmt_error_read, STMT, stmt->last_error);
|
||||
MYSQLI_MAP_PROPERTY_STRING(stmt_sqlstate_read, STMT, stmt->sqlstate);
|
||||
MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_affected_rows_read, mysql_stmt_affected_rows, MYSQLI_GET_STMT(), my_ulonglong);
|
||||
MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_insert_id_read, mysql_stmt_insert_id, MYSQLI_GET_STMT(), my_ulonglong);
|
||||
MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_num_rows_read, mysql_stmt_num_rows, MYSQLI_GET_STMT(), my_ulonglong);
|
||||
MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_param_count_read, mysql_stmt_param_count, MYSQLI_GET_STMT(), ulong);
|
||||
//MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_field_count_read, mysql_stmt_field_count, MYSQLI_GET_STMT(), ulong);
|
||||
MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_errno_read, mysql_stmt_errno, MYSQLI_GET_STMT(), ulong);
|
||||
MYSQLI_MAP_PROPERTY_FUNC_STRING(stmt_error_read, mysql_stmt_error, MYSQLI_GET_STMT());
|
||||
MYSQLI_MAP_PROPERTY_FUNC_STRING(stmt_sqlstate_read, mysql_stmt_sqlstate, MYSQLI_GET_STMT());
|
||||
|
||||
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},
|
||||
{"connect_errno", link_connect_errno_read, NULL},
|
||||
{"connect_error", link_connect_error_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},
|
||||
{"insert_id", link_insert_id_read, NULL},
|
||||
{"server_capabilities", link_server_capabilities_read, NULL},
|
||||
{"server_status", link_server_status_read, NULL},
|
||||
{"server_info", link_server_info_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}
|
||||
};
|
||||
@ -234,10 +207,15 @@ mysqli_property_entry mysqli_result_property_entries[] = {
|
||||
|
||||
mysqli_property_entry mysqli_stmt_property_entries[] = {
|
||||
{"affected_rows", stmt_affected_rows_read, NULL},
|
||||
{"insert_id", stmt_insert_id_read, NULL},
|
||||
{"num_rows", stmt_num_rows_read, NULL},
|
||||
{"param_count", stmt_param_count_read, NULL},
|
||||
|
||||
/* TODO: stmt->field_count doesn't work currently, remove comments until mysqli_stmt_field_count
|
||||
is implemented in client library
|
||||
{"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},
|
||||
|
@ -26,6 +26,7 @@
|
||||
#endif
|
||||
|
||||
#include <mysql.h>
|
||||
#include <errmsg.h>
|
||||
|
||||
#ifndef PHP_MYSQLI_H
|
||||
#define PHP_MYSQLI_H
|
||||
@ -38,9 +39,9 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
unsigned int var_cnt;
|
||||
VAR_BUFFER *buf;
|
||||
zval **vars;
|
||||
char *is_null;
|
||||
VAR_BUFFER *buf;
|
||||
zval **vars;
|
||||
char *is_null;
|
||||
} BIND_BUFFER;
|
||||
|
||||
typedef struct {
|
||||
@ -48,7 +49,14 @@ typedef struct {
|
||||
BIND_BUFFER param;
|
||||
BIND_BUFFER result;
|
||||
char *query;
|
||||
} STMT;
|
||||
} MY_STMT;
|
||||
|
||||
typedef struct {
|
||||
MYSQL *mysql;
|
||||
/* callback functions for load data local infile support */
|
||||
zval callback_func[3];
|
||||
zval *local_infile;
|
||||
} MY_MYSQL;
|
||||
|
||||
typedef struct {
|
||||
int mode;
|
||||
@ -58,6 +66,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
void *ptr; /* resource: (mysql, result, stmt) */
|
||||
void *info; /* additional buffer */
|
||||
} MYSQLI_RESOURCE;
|
||||
|
||||
typedef struct _mysqli_object {
|
||||
@ -73,13 +82,10 @@ typedef struct _mysqli_property_entry {
|
||||
int (*w_func)(mysqli_object *obj, zval **retval TSRMLS_DC);
|
||||
} mysqli_property_entry;
|
||||
|
||||
#define MYSQLI_PR_CONNECT 1
|
||||
#define MYSQLI_PR_QUERY 2
|
||||
#define MYSQLI_PR_QUERY_RESULT 3
|
||||
#define MYSQLI_PR_STMT 4
|
||||
#define MYSQLI_PR_STMT_RESULT 5
|
||||
#define MYSQLI_PR_COMMAND 6
|
||||
|
||||
typedef struct {
|
||||
char error_msg[LOCAL_INFILE_ERROR_LEN];
|
||||
void *userdata;
|
||||
} mysqli_local_infile;
|
||||
|
||||
#define phpext_mysqli_ptr &mysqli_module_entry
|
||||
|
||||
@ -105,10 +111,14 @@ 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_clear_stmt_bind(MY_STMT *stmt);
|
||||
extern void php_free_stmt_bind_buffer(BIND_BUFFER bbuf, int type);
|
||||
extern void php_mysqli_report_error(char *sqlstate, int errorno, char *error TSRMLS_DC);
|
||||
extern void php_mysqli_report_index(char *query, unsigned int status TSRMLS_DC);
|
||||
extern int php_local_infile_init(void **, const char *, void *);
|
||||
extern int php_local_infile_read(void *, char *, uint);
|
||||
extern void php_local_infile_end(void *);
|
||||
extern int php_local_infile_error(void *, char *, uint);
|
||||
|
||||
zend_class_entry *mysqli_link_class_entry;
|
||||
zend_class_entry *mysqli_stmt_class_entry;
|
||||
@ -121,12 +131,12 @@ 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); \
|
||||
mysql_set_server_option(mysql->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); \
|
||||
mysql_set_server_option(mysql->mysql, MYSQL_OPTION_MULTI_STATEMENTS_ON); \
|
||||
MyG(multi_query) = 1; \
|
||||
}
|
||||
|
||||
@ -170,7 +180,7 @@ PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry * TSRML
|
||||
} \
|
||||
__ptr = (__type)my_res->ptr; \
|
||||
if (!strcmp((char *)__name, "mysqli_stmt")) {\
|
||||
if (!((STMT *)__ptr)->stmt->mysql) {\
|
||||
if (!((MYSQL_STMT *)__ptr)->mysql) {\
|
||||
php_error(E_WARNING, "Statement isn't valid anymore");\
|
||||
RETURN_NULL();\
|
||||
}\
|
||||
@ -300,6 +310,10 @@ PHP_FUNCTION(mysqli_info);
|
||||
PHP_FUNCTION(mysqli_insert_id);
|
||||
PHP_FUNCTION(mysqli_init);
|
||||
PHP_FUNCTION(mysqli_kill);
|
||||
#ifndef PHP_WIN32
|
||||
PHP_FUNCTION(mysqli_set_local_infile_default);
|
||||
PHP_FUNCTION(mysqli_set_local_infile_handler);
|
||||
#endif
|
||||
PHP_FUNCTION(mysqli_master_query);
|
||||
PHP_FUNCTION(mysqli_more_results);
|
||||
PHP_FUNCTION(mysqli_multi_query);
|
||||
@ -352,6 +366,7 @@ PHP_FUNCTION(mysqli_stmt_error);
|
||||
PHP_FUNCTION(mysqli_stmt_free_result);
|
||||
PHP_FUNCTION(mysqli_stmt_reset);
|
||||
#endif
|
||||
PHP_FUNCTION(mysqli_stmt_insert_id);
|
||||
PHP_FUNCTION(mysqli_stmt_num_rows);
|
||||
#if MYSQL_VERSION_ID >= 40101
|
||||
PHP_FUNCTION(mysqli_stmt_sqlstate);
|
||||
|
Loading…
Reference in New Issue
Block a user