diff options
Diffstat (limited to 'ext/mysqli')
36 files changed, 1117 insertions, 546 deletions
diff --git a/ext/mysqli/config.m4 b/ext/mysqli/config.m4 index 59efaaaff2..6ec9334639 100644 --- a/ext/mysqli/config.m4 +++ b/ext/mysqli/config.m4 @@ -4,24 +4,20 @@ dnl config.m4 for extension mysqli PHP_ARG_WITH(mysqli, for MySQLi support, [ --with-mysqli[=FILE] Include MySQLi support. FILE is the path - to mysql_config. If mysqlnd is passed as FILE, - the MySQL native driver will be used [mysql_config]]) + to mysql_config. If no value or mysqlnd is passed + as FILE, the MySQL native driver will be used]) PHP_ARG_ENABLE(embedded_mysqli, whether to enable embedded MySQLi support, [ --enable-embedded-mysqli MYSQLi: Enable embedded support Note: Does not work with MySQL native driver!], no, no) -if test "$PHP_MYSQLI" = "mysqlnd"; then +if test "$PHP_MYSQLI" = "yes" || test "$PHP_MYSQLI" = "mysqlnd"; then dnl This needs to be set in any extension which wishes to use mysqlnd PHP_MYSQLND_ENABLED=yes elif test "$PHP_MYSQLI" != "no"; then - if test "$PHP_MYSQLI" = "yes"; then - MYSQL_CONFIG=`$php_shtool path mysql_config` - else - MYSQL_CONFIG=$PHP_MYSQLI - fi + MYSQL_CONFIG=$PHP_MYSQLI MYSQL_LIB_NAME='mysqlclient' if test "$PHP_EMBEDDED_MYSQLI" = "yes"; then @@ -77,12 +73,12 @@ dnl Build extension if test "$PHP_MYSQLI" != "no"; then mysqli_sources="mysqli.c mysqli_api.c mysqli_prop.c mysqli_nonapi.c \ mysqli_fe.c mysqli_report.c mysqli_driver.c mysqli_warning.c \ - mysqli_exception.c $mysqli_extra_sources" + mysqli_exception.c mysqli_result_iterator.c $mysqli_extra_sources" PHP_NEW_EXTENSION(mysqli, $mysqli_sources, $ext_shared) PHP_SUBST(MYSQLI_SHARED_LIBADD) PHP_INSTALL_HEADERS([ext/mysqli/php_mysqli_structs.h]) - if test "$PHP_MYSQLI" = "mysqlnd"; then + if test "$PHP_MYSQLI" = "yes" || test "$PHP_MYSQLI" = "mysqlnd"; then PHP_ADD_EXTENSION_DEP(mysqli, mysqlnd) AC_DEFINE([MYSQLI_USE_MYSQLND], 1, [Whether mysqlnd is enabled]) fi diff --git a/ext/mysqli/config.w32 b/ext/mysqli/config.w32 index ab3321ae44..ab8bcd0087 100644 --- a/ext/mysqli/config.w32 +++ b/ext/mysqli/config.w32 @@ -18,6 +18,7 @@ if (PHP_MYSQLI != "no") { "mysqli_fe.c " + "mysqli_nonapi.c " + "mysqli_prop.c " + + "mysqli_result_iterator.c " + "mysqli_report.c " + "mysqli_warning.c"; diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c index 08fcf1e75b..f18a503b5e 100644 --- a/ext/mysqli/mysqli.c +++ b/ext/mysqli/mysqli.c @@ -30,9 +30,11 @@ #include "php_ini.h" #include "ext/standard/info.h" #include "ext/standard/php_string.h" +#include "php_mysqli.h" #include "php_mysqli_structs.h" #include "mysqli_priv.h" #include "zend_exceptions.h" +#include "zend_interfaces.h" ZEND_DECLARE_MODULE_GLOBALS(mysqli) static PHP_GINIT_FUNCTION(mysqli); @@ -313,7 +315,7 @@ static int mysqli_write_na(mysqli_object *obj, zval *newval TSRMLS_DC) /* {{{ mysqli_read_property */ -zval *mysqli_read_property(zval *object, zval *member, int type TSRMLS_DC) +zval *mysqli_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) { zval tmp_member; zval *retval; @@ -345,7 +347,7 @@ zval *mysqli_read_property(zval *object, zval *member, int type TSRMLS_DC) } } else { zend_object_handlers * std_hnd = zend_get_std_object_handlers(); - retval = std_hnd->read_property(object, member, type TSRMLS_CC); + retval = std_hnd->read_property(object, member, type, key TSRMLS_CC); } if (member == &tmp_member) { @@ -356,7 +358,7 @@ zval *mysqli_read_property(zval *object, zval *member, int type TSRMLS_DC) /* }}} */ /* {{{ mysqli_write_property */ -void mysqli_write_property(zval *object, zval *member, zval *value TSRMLS_DC) +void mysqli_write_property(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC) { zval tmp_member; mysqli_object *obj; @@ -384,7 +386,7 @@ void mysqli_write_property(zval *object, zval *member, zval *value TSRMLS_DC) } } else { zend_object_handlers * std_hnd = zend_get_std_object_handlers(); - std_hnd->write_property(object, member, value TSRMLS_CC); + std_hnd->write_property(object, member, value, key TSRMLS_CC); } if (member == &tmp_member) { @@ -405,7 +407,7 @@ void mysqli_add_property(HashTable *h, const char *pname, size_t pname_len, mysq } /* }}} */ -static int mysqli_object_has_property(zval *object, zval *member, int has_set_exists TSRMLS_DC) /* {{{ */ +static int mysqli_object_has_property(zval *object, zval *member, int has_set_exists, const zend_literal *key TSRMLS_DC) /* {{{ */ { mysqli_object *obj = (mysqli_object *)zend_objects_get_address(object TSRMLS_CC); mysqli_prop_handler p; @@ -417,7 +419,7 @@ static int mysqli_object_has_property(zval *object, zval *member, int has_set_ex ret = 1; break; case 1: { - zval *value = mysqli_read_property(object, member, BP_VAR_IS TSRMLS_CC); + zval *value = mysqli_read_property(object, member, BP_VAR_IS, key TSRMLS_CC); if (value != EG(uninitialized_zval_ptr)) { convert_to_boolean(value); ret = Z_BVAL_P(value)? 1:0; @@ -428,7 +430,7 @@ static int mysqli_object_has_property(zval *object, zval *member, int has_set_ex break; } case 0:{ - zval *value = mysqli_read_property(object, member, BP_VAR_IS TSRMLS_CC); + zval *value = mysqli_read_property(object, member, BP_VAR_IS, key TSRMLS_CC); if (value != EG(uninitialized_zval_ptr)) { ret = Z_TYPE_P(value) != IS_NULL? 1:0; /* refcount is 0 */ @@ -442,7 +444,7 @@ static int mysqli_object_has_property(zval *object, zval *member, int has_set_ex } } else { zend_object_handlers * std_hnd = zend_get_std_object_handlers(); - ret = std_hnd->has_property(object, member, has_set_exists TSRMLS_CC); + ret = std_hnd->has_property(object, member, has_set_exists, key TSRMLS_CC); } return ret; } /* }}} */ @@ -465,7 +467,7 @@ HashTable * mysqli_object_get_debug_info(zval *object, int *is_temp TSRMLS_DC) zval *value; INIT_ZVAL(member); ZVAL_STRINGL(&member, entry->name, entry->name_len, 0); - value = mysqli_read_property(object, &member, BP_VAR_IS TSRMLS_CC); + value = mysqli_read_property(object, &member, BP_VAR_IS, 0 TSRMLS_CC); if (value != EG(uninitialized_zval_ptr)) { Z_ADDREF_P(value); zend_hash_add(retval, entry->name, entry->name_len + 1, &value, sizeof(zval *), NULL); @@ -484,7 +486,6 @@ 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 *mysqli_base_class; zend_objects_free_object_storage_t free_storage; @@ -502,8 +503,7 @@ PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry *class_ (void **) &intern->prop_handler); zend_object_std_init(&intern->zo, class_type TSRMLS_CC); - zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_property_ctor, - (void *) &tmp, sizeof(zval *)); + object_properties_init(&intern->zo, class_type); /* link object */ if (instanceof_function(class_type, mysqli_link_class_entry TSRMLS_CC)) { @@ -527,6 +527,30 @@ PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry *class_ } /* }}} */ +#ifdef MYSQLI_USE_MYSQLND +#include "ext/mysqlnd/mysqlnd_reverse_api.h" +static MYSQLND *mysqli_convert_zv_to_mysqlnd(zval * zv TSRMLS_DC) +{ + if (Z_TYPE_P(zv) == IS_OBJECT && Z_OBJCE_P(zv) == mysqli_link_class_entry) { + MY_MYSQL * mysql; + MYSQLI_RESOURCE * my_res; + mysqli_object * intern = (mysqli_object *)zend_object_store_get_object(zv TSRMLS_CC); + if (!(my_res = (MYSQLI_RESOURCE *)intern->ptr)) { + /* We know that we have a mysqli object, so this failure should be emitted */ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %s", intern->zo.ce->name); + return NULL; + } + mysql = (MY_MYSQL *)(my_res->ptr); + return mysql ? mysql->mysql : NULL; + } + return NULL; +} + +static MYSQLND_REVERSE_API mysqli_reverse_api = { + &mysqli_module_entry, + mysqli_convert_zv_to_mysqlnd +}; +#endif /* {{{ PHP_INI_BEGIN */ @@ -646,6 +670,9 @@ PHP_MINIT_FUNCTION(mysqli) zend_hash_init(&mysqli_result_properties, 0, NULL, NULL, 1); MYSQLI_ADD_PROPERTIES(&mysqli_result_properties, mysqli_result_property_entries); MYSQLI_ADD_PROPERTIES_INFO(ce, mysqli_result_property_info_entries); + mysqli_result_class_entry->get_iterator = php_mysqli_result_get_iterator; + mysqli_result_class_entry->iterator_funcs.funcs = &php_mysqli_result_iterator_funcs; + zend_class_implements(mysqli_result_class_entry TSRMLS_CC, 1, zend_ce_traversable); 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); @@ -783,10 +810,10 @@ PHP_MINIT_FUNCTION(mysqli) #ifdef MYSQLI_USE_MYSQLND REGISTER_LONG_CONSTANT("MYSQLI_DEBUG_TRACE_ENABLED", MYSQLND_DBG_ENABLED, CONST_CS | CONST_PERSISTENT); #else -#ifndef DBUG_OFF - REGISTER_LONG_CONSTANT("MYSQLI_DEBUG_TRACE_ENABLED", 0, CONST_CS | CONST_PERSISTENT); -#else +#ifdef DBUG_ON REGISTER_LONG_CONSTANT("MYSQLI_DEBUG_TRACE_ENABLED", 1, CONST_CS | CONST_PERSISTENT); +#else + REGISTER_LONG_CONSTANT("MYSQLI_DEBUG_TRACE_ENABLED", 0, CONST_CS | CONST_PERSISTENT); #endif #endif @@ -811,6 +838,11 @@ PHP_MINIT_FUNCTION(mysqli) REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_BACKUP_LOG", REFRESH_BACKUP_LOG, CONST_CS | CONST_PERSISTENT); #endif + +#ifdef MYSQLI_USE_MYSQLND + mysqlnd_reverse_api_register_api(&mysqli_reverse_api TSRMLS_CC); +#endif + return SUCCESS; } /* }}} */ @@ -1083,61 +1115,17 @@ PHP_FUNCTION(mysqli_result_construct) } /* }}} */ -/* {{{ php_mysqli_fetch_into_hash + +/* {{{ php_mysqli_fetch_into_hash_aux */ -void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags, int into_object) +void php_mysqli_fetch_into_hash_aux(zval *return_value, MYSQL_RES * result, long fetchtype TSRMLS_DC) { - MYSQL_RES *result; - zval *mysql_result; - long fetchtype; - zval *ctor_params = NULL; - zend_class_entry *ce = NULL; #if !defined(MYSQLI_USE_MYSQLND) + MYSQL_ROW row; unsigned int i; MYSQL_FIELD *fields; - MYSQL_ROW row; unsigned long *field_len; - zend_bool magic_quotes_warning_sent = FALSE; -#endif - - if (into_object) { - char *class_name; - int class_name_len; - - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|sz", &mysql_result, mysqli_result_class_entry, &class_name, &class_name_len, &ctor_params) == FAILURE) { - return; - } - if (ZEND_NUM_ARGS() < (getThis() ? 1 : 2)) { - ce = zend_standard_class_def; - } else { - ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC); - } - if (!ce) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not find class '%s'", class_name); - return; - } - fetchtype = MYSQLI_ASSOC; - } else { - if (override_flags) { - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) { - return; - } - fetchtype = override_flags; - } else { - fetchtype = MYSQLI_BOTH; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &mysql_result, mysqli_result_class_entry, &fetchtype) == FAILURE) { - return; - } - } - } - MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); - - if (fetchtype < MYSQLI_ASSOC || fetchtype > MYSQLI_BOTH) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "The result type should be either MYSQLI_NUM, MYSQLI_ASSOC or MYSQLI_BOTH"); - RETURN_FALSE; - } - -#if !defined(MYSQLI_USE_MYSQLND) + if (!(row = mysql_fetch_row(result))) { RETURN_NULL(); } @@ -1179,17 +1167,17 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags #endif { +#if PHP_API_VERSION < 20100412 /* check if we need magic quotes */ if (PG(magic_quotes_runtime)) { - if (magic_quotes_warning_sent == FALSE) { - magic_quotes_warning_sent = TRUE; - php_error_docref(NULL TSRMLS_CC, E_WARNING, "magic_quotes_runtime are deprecated since PHP 5.3"); - } Z_TYPE_P(res) = IS_STRING; Z_STRVAL_P(res) = php_addslashes(row[i], field_len[i], &Z_STRLEN_P(res), 0 TSRMLS_CC); } else { +#endif ZVAL_STRINGL(res, row[i], field_len[i], 1); +#if PHP_API_VERSION < 20100412 } +#endif } if (fetchtype & MYSQLI_NUM) { @@ -1211,53 +1199,60 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags } } #else - if (PG(magic_quotes_runtime)) { - HashPosition pos_values; - zval **entry_values; - zval new_return_value; - char * string_key; - uint string_key_len; - ulong num_key; - - mysqlnd_fetch_into(result, ((fetchtype & MYSQLI_NUM)? MYSQLND_FETCH_NUM:0) | ((fetchtype & MYSQLI_ASSOC)? MYSQLND_FETCH_ASSOC:0), &new_return_value, MYSQLND_MYSQLI); - if (Z_TYPE(new_return_value) == IS_ARRAY) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "magic_quotes_runtime are deprecated since PHP 5.3"); - array_init(return_value); - zend_hash_internal_pointer_reset_ex(Z_ARRVAL(new_return_value), &pos_values); - while (zend_hash_get_current_data_ex(Z_ARRVAL(new_return_value), (void **)&entry_values, &pos_values) == SUCCESS) { - if (Z_TYPE_PP(entry_values) == IS_STRING) { - int new_str_len; - char * new_str = php_addslashes(Z_STRVAL_PP(entry_values), Z_STRLEN_PP(entry_values), &new_str_len, 0 TSRMLS_CC); - switch (zend_hash_get_current_key_ex(Z_ARRVAL(new_return_value), &string_key, &string_key_len, &num_key, 0, &pos_values)) { - case HASH_KEY_IS_LONG: - add_index_stringl(return_value, num_key, new_str, new_str_len, 0); - break; - case HASH_KEY_IS_STRING: - add_assoc_stringl_ex(return_value, string_key, string_key_len, new_str, new_str_len, 0); - break; - } - } else { - zval_add_ref(entry_values); - switch (zend_hash_get_current_key_ex(Z_ARRVAL(new_return_value), &string_key, &string_key_len, &num_key, 0, &pos_values)) { - case HASH_KEY_IS_LONG: - add_index_zval(return_value, num_key, *entry_values); - break; - case HASH_KEY_IS_STRING: - add_assoc_zval_ex(return_value, string_key, string_key_len, *entry_values); - break; - } - } - zend_hash_move_forward_ex(Z_ARRVAL(new_return_value), &pos_values); - } + mysqlnd_fetch_into(result, ((fetchtype & MYSQLI_NUM)? MYSQLND_FETCH_NUM:0) | ((fetchtype & MYSQLI_ASSOC)? MYSQLND_FETCH_ASSOC:0), return_value, MYSQLND_MYSQLI); +#endif +} +/* }}} */ + + +/* {{{ php_mysqli_fetch_into_hash + */ +void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags, int into_object) +{ + MYSQL_RES *result; + zval *mysql_result; + long fetchtype; + zval *ctor_params = NULL; + zend_class_entry *ce = NULL; + + if (into_object) { + char *class_name; + int class_name_len; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|sz", &mysql_result, mysqli_result_class_entry, &class_name, &class_name_len, &ctor_params) == FAILURE) { + return; + } + if (ZEND_NUM_ARGS() < (getThis() ? 1 : 2)) { + ce = zend_standard_class_def; } else { - RETVAL_NULL(); + ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC); } - zval_dtor(&new_return_value); + if (!ce) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not find class '%s'", class_name); + return; + } + fetchtype = MYSQLI_ASSOC; } else { - mysqlnd_fetch_into(result, ((fetchtype & MYSQLI_NUM)? MYSQLND_FETCH_NUM:0) | ((fetchtype & MYSQLI_ASSOC)? MYSQLND_FETCH_ASSOC:0), return_value, MYSQLND_MYSQLI); + if (override_flags) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) { + return; + } + fetchtype = override_flags; + } else { + fetchtype = MYSQLI_BOTH; + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &mysql_result, mysqli_result_class_entry, &fetchtype) == FAILURE) { + return; + } + } } + MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); -#endif + if (fetchtype < MYSQLI_ASSOC || fetchtype > MYSQLI_BOTH) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The result type should be either MYSQLI_NUM, MYSQLI_ASSOC or MYSQLI_BOTH"); + RETURN_FALSE; + } + + php_mysqli_fetch_into_hash_aux(return_value, result, fetchtype TSRMLS_CC); if (into_object && Z_TYPE_P(return_value) != IS_NULL) { zval dataset = *return_value; diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index aa6b6ab98e..ce7588ecbf 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -535,7 +535,11 @@ PHP_FUNCTION(mysqli_change_user) old_charset = mysql->mysql->charset; #endif +#if defined(MYSQLI_USE_MYSQLND) + rc = mysqlnd_change_user_ex(mysql->mysql, user, password, dbname, FALSE, (size_t) password_len); +#else rc = mysql_change_user(mysql->mysql, user, password, dbname); +#endif MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); if (rc) { @@ -883,7 +887,7 @@ void mysqli_stmt_fetch_libmysql(INTERNAL_FUNCTION_PARAMETERS) */ /* 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); + STR_FREE(stmt->result.vars[i]->value.str.val); } if (!stmt->result.is_null[i]) { switch (stmt->result.buf[i].type) { @@ -1047,12 +1051,12 @@ PHP_FUNCTION(mysqli_stmt_fetch) /* {{{ php_add_field_properties */ static void php_add_field_properties(zval *value, const MYSQL_FIELD *field TSRMLS_DC) { - add_property_string(value, "name", (char *) (field->name ? field->name : ""), 1); - add_property_string(value, "orgname", (char *) (field->org_name ? field->org_name : ""), 1); - add_property_string(value, "table", (char *) (field->table ? field->table : ""), 1); - add_property_string(value, "orgtable", (char *) (field->org_table ? field->org_table : ""), 1); - add_property_string(value, "def", (field->def ? field->def : ""), 1); - add_property_string(value, "db", (field->db ? field->db : ""), 1); + 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_string(value, "db",(field->db ? field->db : ""), 1); /* FIXME: manually set the catalog to "def" due to bug in * libmysqlclient which does not initialize field->catalog @@ -1287,8 +1291,11 @@ PHP_FUNCTION(mysqli_get_host_info) return; } MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); - +#if !defined(MYSQLI_USE_MYSQLND) RETURN_STRING((mysql->mysql->host_info) ? mysql->mysql->host_info : "", 1); +#else + RETURN_STRING((mysql->mysql->data->host_info) ? mysql->mysql->data->host_info : "", 1); +#endif } /* }}} */ @@ -1800,7 +1807,7 @@ PHP_FUNCTION(mysqli_prepare) memcpy(last_error, stmt->stmt->last_error, MYSQL_ERRMSG_SIZE); memcpy(sqlstate, mysql->mysql->net.sqlstate, SQLSTATE_LENGTH+1); #else - MYSQLND_ERROR_INFO error_info = mysql->mysql->error_info; + MYSQLND_ERROR_INFO error_info = *mysql->mysql->data->error_info; #endif mysqli_stmt_close(stmt->stmt, FALSE); stmt->stmt = NULL; @@ -1811,7 +1818,7 @@ PHP_FUNCTION(mysqli_prepare) 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; + *mysql->mysql->data->error_info = error_info; #endif } } diff --git a/ext/mysqli/mysqli_driver.c b/ext/mysqli/mysqli_driver.c index b7227bb3c2..67e2b43e76 100644 --- a/ext/mysqli/mysqli_driver.c +++ b/ext/mysqli/mysqli_driver.c @@ -151,14 +151,14 @@ const mysqli_property_entry mysqli_driver_property_entries[] = { }; /* {{{ mysqli_warning_property_info_entries */ -zend_property_info mysqli_driver_property_info_entries[] = { - {ZEND_ACC_PUBLIC, "client_info", sizeof("client_info") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "client_version", sizeof("client_version") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "driver_version", sizeof("driver_version") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "embedded", sizeof("embedded") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "reconnect", sizeof("reconnect") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "report_mode", sizeof("report_mode") - 1, 0, NULL, 0, NULL}, - {0, NULL, 0, 0, NULL, 0, NULL}, +const zend_property_info mysqli_driver_property_info_entries[] = { + {ZEND_ACC_PUBLIC, "client_info", sizeof("client_info") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "client_version", sizeof("client_version") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "driver_version", sizeof("driver_version") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "embedded", sizeof("embedded") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "reconnect", sizeof("reconnect") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "report_mode", sizeof("report_mode") - 1, -1, 0, NULL, 0, NULL}, + {0, NULL, 0, -1, 0, NULL, 0, NULL}, }; /* }}} */ diff --git a/ext/mysqli/mysqli_fe.c b/ext/mysqli/mysqli_fe.c index bb4e7cab8c..9ebb9352fe 100644 --- a/ext/mysqli/mysqli_fe.c +++ b/ext/mysqli/mysqli_fe.c @@ -33,7 +33,7 @@ #include "mysqli_fe.h" #include "mysqli_priv.h" -#if PHP_VERSION_ID >= 50399 +#ifdef MYSQLI_USE_FULL_TYPED_ARGINFO_0 #define MYSQLI_ZEND_ARG_OBJ_INFO_LINK() ZEND_ARG_OBJ_INFO(0, link, mysqli, 0) #define MYSQLI_ZEND_ARG_OBJ_INFO_RESULT() ZEND_ARG_OBJ_INFO(0, result, mysqli_result, 0) #define MYSQLI_ZEND_ARG_OBJ_INFO_STMT() ZEND_ARG_OBJ_INFO(0, stmt, mysqli_stmt, 0) @@ -352,6 +352,7 @@ const zend_function_entry mysqli_functions[] = { #endif PHP_FE(mysqli_errno, arginfo_mysqli_only_link) PHP_FE(mysqli_error, arginfo_mysqli_only_link) + PHP_FE(mysqli_error_list, arginfo_mysqli_only_link) PHP_FE(mysqli_stmt_execute, arginfo_mysqli_only_statement) PHP_FALIAS(mysqli_execute, mysqli_stmt_execute, arginfo_mysqli_only_statement) PHP_FE(mysqli_fetch_field, arginfo_mysqli_only_result) @@ -370,7 +371,6 @@ const zend_function_entry mysqli_functions[] = { PHP_FE(mysqli_field_tell, arginfo_mysqli_only_result) PHP_FE(mysqli_free_result, arginfo_mysqli_only_result) #if defined(MYSQLI_USE_MYSQLND) - PHP_FE(mysqli_get_cache_stats, arginfo_mysqli_no_params) PHP_FE(mysqli_get_connection_stats, arginfo_mysqli_only_link) PHP_FE(mysqli_get_client_stats, arginfo_mysqli_no_params) #endif @@ -425,6 +425,7 @@ const zend_function_entry mysqli_functions[] = { PHP_FE(mysqli_stmt_data_seek, arginfo_mysqli_stmt_data_seek) PHP_FE(mysqli_stmt_errno, arginfo_mysqli_only_statement) PHP_FE(mysqli_stmt_error, arginfo_mysqli_only_statement) + PHP_FE(mysqli_stmt_error_list, arginfo_mysqli_only_statement) PHP_FE(mysqli_stmt_fetch, arginfo_mysqli_only_statement) PHP_FE(mysqli_stmt_field_count, arginfo_mysqli_only_statement) PHP_FE(mysqli_stmt_free_result, arginfo_mysqli_only_statement) @@ -458,14 +459,7 @@ const zend_function_entry mysqli_functions[] = { PHP_FE(mysqli_refresh, arginfo_mysqli_refresh) /* Aliases */ - PHP_FALIAS(mysqli_bind_param, mysqli_stmt_bind_param, arginfo_mysqli_stmt_bind_param) - PHP_FALIAS(mysqli_bind_result, mysqli_stmt_bind_result, arginfo_mysqli_stmt_bind_result) - PHP_FALIAS(mysqli_client_encoding, mysqli_character_set_name, NULL) PHP_FALIAS(mysqli_escape_string, mysqli_real_escape_string, arginfo_mysqli_query) - PHP_FALIAS(mysqli_fetch, mysqli_stmt_fetch, NULL) - PHP_FALIAS(mysqli_param_count, mysqli_stmt_param_count, NULL) - PHP_FALIAS(mysqli_get_metadata, mysqli_stmt_result_metadata,NULL) - PHP_FALIAS(mysqli_send_long_data, mysqli_stmt_send_long_data, NULL) PHP_FALIAS(mysqli_set_opt, mysqli_options, NULL) PHP_FE_END @@ -480,7 +474,6 @@ const zend_function_entry mysqli_link_methods[] = { PHP_FALIAS(autocommit, mysqli_autocommit, arginfo_class_mysqli_autocommit) PHP_FALIAS(change_user,mysqli_change_user, arginfo_class_mysqli_change_user) PHP_FALIAS(character_set_name, mysqli_character_set_name, arginfo_mysqli_no_params) - PHP_FALIAS(client_encoding, mysqli_character_set_name, arginfo_mysqli_no_params) /* deprecated */ PHP_FALIAS(close, mysqli_close, arginfo_mysqli_no_params) PHP_FALIAS(commit, mysqli_commit, arginfo_mysqli_no_params) PHP_FALIAS(connect, mysqli_connect, arginfo_mysqli_connect) diff --git a/ext/mysqli/mysqli_fe.h b/ext/mysqli/mysqli_fe.h index ad73eb73e5..7b55ad1c12 100644 --- a/ext/mysqli/mysqli_fe.h +++ b/ext/mysqli/mysqli_fe.h @@ -38,6 +38,7 @@ PHP_FUNCTION(mysqli_debug); PHP_FUNCTION(mysqli_dump_debug_info); PHP_FUNCTION(mysqli_errno); PHP_FUNCTION(mysqli_error); +PHP_FUNCTION(mysqli_error_list); PHP_FUNCTION(mysqli_fetch_all); PHP_FUNCTION(mysqli_fetch_array); PHP_FUNCTION(mysqli_fetch_assoc); @@ -111,6 +112,7 @@ PHP_FUNCTION(mysqli_stmt_close); PHP_FUNCTION(mysqli_stmt_data_seek); PHP_FUNCTION(mysqli_stmt_errno); PHP_FUNCTION(mysqli_stmt_error); +PHP_FUNCTION(mysqli_stmt_error_list); PHP_FUNCTION(mysqli_stmt_free_result); PHP_FUNCTION(mysqli_stmt_get_result); PHP_FUNCTION(mysqli_stmt_get_warnings); @@ -133,3 +135,5 @@ PHP_FUNCTION(mysqli_driver_construct); PHP_METHOD(mysqli_warning,__construct); #endif /* MYSQLI_FE_H */ + + diff --git a/ext/mysqli/mysqli_libmysql.h b/ext/mysqli/mysqli_libmysql.h index 65c69bf282..a61f7e87b9 100644 --- a/ext/mysqli/mysqli_libmysql.h +++ b/ext/mysqli/mysqli_libmysql.h @@ -1,9 +1,9 @@ /* - ---------------------------------------------------------------------- - | PHP Version 6 | - ---------------------------------------------------------------------- - | Copyright (c) 2007 The PHP Group | - ---------------------------------------------------------------------- + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2012 The PHP Group | + +----------------------------------------------------------------------+ | This source file is subject to version 3.01 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: | @@ -11,12 +11,11 @@ | 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. | - ---------------------------------------------------------------------- - | Authors: Georg Richter <georg@mysql.com> | - | Andrey Hristov <andrey@mysql.com> | - | Ulf Wendel <uwendel@mysql.com> | - ---------------------------------------------------------------------- - + +----------------------------------------------------------------------+ + | Authors: Georg Richter <georg@php.net> | + | Andrey Hristov <andrey@php.net> | + | Ulf Wendel <uw@php.net> | + +----------------------------------------------------------------------+ */ #ifndef MYSQLI_LIBMYSQL_H @@ -29,8 +28,9 @@ #define MYSQLND_OPT_NUMERIC_AND_DATETIME_AS_UNICODE 200 #define MYSQLND_OPT_INT_AND_YEAR_AS_INT 201 +/* r->data should be always NULL, at least in recent libmysql versions, the status changes once data is read*/ #define mysqli_result_is_unbuffered(r) ((r)->handle && (r)->handle->status == MYSQL_STATUS_USE_RESULT && (r)->data == NULL) -#define mysqli_result_is_unbuffered_and_not_everything_is_fetched(r) mysqli_result_is_unbuffered(r) +#define mysqli_result_is_unbuffered_and_not_everything_is_fetched(r) mysqli_result_is_unbuffered(r) #define mysqli_server_status(c) (c)->server_status #define mysqli_stmt_get_id(s) ((s)->stmt_id) #define mysqli_stmt_warning_count(s) mysql_warning_count((s)->mysql) @@ -39,7 +39,7 @@ #define mysqli_close(c, is_forced) mysql_close((c)) #define mysqli_stmt_close(c, implicit) mysql_stmt_close((c)) #define mysqli_free_result(r, is_forced) mysql_free_result((r)) -#define mysqli_change_user_silent(c, u, p, d) mysql_change_user((c), (u), (p), (d)) +#define mysqli_change_user_silent(c, u, p, d, p_len) mysql_change_user((c), (u), (p), (d)) /* diff --git a/ext/mysqli/mysqli_mysqlnd.h b/ext/mysqli/mysqli_mysqlnd.h index ce0be63e5b..b6d23d9ef1 100644 --- a/ext/mysqli/mysqli_mysqlnd.h +++ b/ext/mysqli/mysqli_mysqlnd.h @@ -32,7 +32,7 @@ #define mysqli_result_is_unbuffered(r) ((r)->unbuf) #define mysqli_result_is_unbuffered_and_not_everything_is_fetched(r) ((r)->unbuf && !(r)->unbuf->eof_reached) -#define mysqli_server_status(c) (c)->upsert_status.server_status +#define mysqli_server_status(c) mysqlnd_get_server_status((c)) #define mysqli_stmt_get_id(s) ((s)->data->stmt_id) #define mysqli_stmt_warning_count(s) mysqlnd_stmt_warning_count((s)) #define mysqli_stmt_server_status(s) mysqlnd_stmt_server_status((s)) @@ -41,7 +41,7 @@ #define mysqli_stmt_close(c, implicit) mysqlnd_stmt_close((c), (implicit)) #define mysqli_free_result(r, implicit) mysqlnd_free_result((r), (implicit)) #define mysqli_async_query(c, q, l) mysqlnd_async_query((c), (q), (l)) -#define mysqli_change_user_silent(c, u, p, d) mysqlnd_change_user((c), (u), (p), (d), TRUE) +#define mysqli_change_user_silent(c, u, p, d, p_len) mysqlnd_change_user_ex((c), (u), (p), (d), TRUE, (size_t)(p_len)) #define HAVE_STMT_NEXT_RESULT diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c index fbfc02e2fc..0cc1240208 100644 --- a/ext/mysqli/mysqli_nonapi.c +++ b/ext/mysqli/mysqli_nonapi.c @@ -174,7 +174,7 @@ void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_real_conne /* reset variables */ #ifndef MYSQLI_NO_CHANGE_USER_ON_PCONNECT - if (!mysqli_change_user_silent(mysql->mysql, username, passwd, dbname)) { + if (!mysqli_change_user_silent(mysql->mysql, username, passwd, dbname, passwd_len)) { #else if (!mysql_ping(mysql->mysql)) { #endif @@ -387,17 +387,6 @@ PHP_FUNCTION(mysqli_fetch_all) /* }}} */ -/* {{{ proto array mysqli_cache_stats(void) U - Returns statistics about the zval cache */ -PHP_FUNCTION(mysqli_get_cache_stats) -{ - if (zend_parse_parameters_none() == FAILURE) { - return; - } - array_init(return_value); -} -/* }}} */ - /* {{{ proto array mysqli_get_client_stats(void) Returns statistics about the zval cache */ @@ -429,6 +418,93 @@ PHP_FUNCTION(mysqli_get_connection_stats) #endif /* }}} */ +/* {{{ proto mixed mysqli_error_list (object connection) + Fetches all client errors */ +PHP_FUNCTION(mysqli_error_list) +{ + 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_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + array_init(return_value); +#if defined(MYSQLI_USE_MYSQLND) + if (mysql->mysql->data->error_info->error_list) { + MYSQLND_ERROR_LIST_ELEMENT * message; + zend_llist_position pos; + for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(mysql->mysql->data->error_info->error_list, &pos); + message; + message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(mysql->mysql->data->error_info->error_list, &pos)) + { + zval * single_error; + MAKE_STD_ZVAL(single_error); + array_init(single_error); + add_assoc_long_ex(single_error, "errno", sizeof("errno"), message->error_no); + add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), message->sqlstate, 1); + add_assoc_string_ex(single_error, "error", sizeof("error"), message->error, 1); + add_next_index_zval(return_value, single_error); + } + } +#else + if (mysql_errno(mysql->mysql)) { + zval * single_error; + MAKE_STD_ZVAL(single_error); + array_init(single_error); + add_assoc_long_ex(single_error, "errno", sizeof("errno"), mysql_errno(mysql->mysql)); + add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), mysql_sqlstate(mysql->mysql), 1); + add_assoc_string_ex(single_error, "error", sizeof("error"), mysql_error(mysql->mysql), 1); + add_next_index_zval(return_value, single_error); + } +#endif +} +/* }}} */ + + +/* {{{ proto string mysqli_stmt_error_list(object stmt) +*/ +PHP_FUNCTION(mysqli_stmt_error_list) +{ + 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(stmt, &mysql_stmt, MYSQLI_STATUS_INITIALIZED); + array_init(return_value); +#if defined(MYSQLI_USE_MYSQLND) + if (stmt->stmt && stmt->stmt->data && stmt->stmt->data->error_info->error_list) { + MYSQLND_ERROR_LIST_ELEMENT * message; + zend_llist_position pos; + for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(stmt->stmt->data->error_info->error_list, &pos); + message; + message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(stmt->stmt->data->error_info->error_list, &pos)) + { + zval * single_error; + MAKE_STD_ZVAL(single_error); + array_init(single_error); + add_assoc_long_ex(single_error, "errno", sizeof("errno"), message->error_no); + add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), message->sqlstate, 1); + add_assoc_string_ex(single_error, "error", sizeof("error"), message->error, 1); + add_next_index_zval(return_value, single_error); + } + } +#else + if (mysql_stmt_errno(stmt->stmt)) { + zval * single_error; + MAKE_STD_ZVAL(single_error); + array_init(single_error); + add_assoc_long_ex(single_error, "errno", sizeof("errno"), mysql_stmt_errno(stmt->stmt)); + add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), mysql_stmt_sqlstate(stmt->stmt), 1); + add_assoc_string_ex(single_error, "error", sizeof("error"), mysql_stmt_error(stmt->stmt), 1); + add_next_index_zval(return_value, single_error); + } +#endif +} +/* }}} */ + /* {{{ proto mixed mysqli_fetch_object (object result [, string class_name [, NULL|array ctor_params]]) Fetch a result row as an object */ @@ -463,7 +539,7 @@ PHP_FUNCTION(mysqli_multi_query) strcpy(s_sqlstate, mysql_sqlstate(mysql->mysql)); s_errno = mysql_errno(mysql->mysql); #else - MYSQLND_ERROR_INFO error_info = mysql->mysql->error_info; + MYSQLND_ERROR_INFO error_info = *mysql->mysql->data->error_info; #endif MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); MYSQLI_DISABLE_MQ; @@ -474,7 +550,7 @@ PHP_FUNCTION(mysqli_multi_query) strcpy(mysql->mysql->net.sqlstate, s_sqlstate); mysql->mysql->net.last_errno = s_errno; #else - mysql->mysql->error_info = error_info; + *mysql->mysql->data->error_info = error_info; #endif RETURN_FALSE; } @@ -837,7 +913,11 @@ PHP_FUNCTION(mysqli_get_warnings) MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); if (mysql_warning_count(mysql->mysql)) { +#ifdef MYSQLI_USE_MYSQLND + w = php_get_warnings(mysql->mysql->data TSRMLS_CC); +#else w = php_get_warnings(mysql->mysql TSRMLS_CC); +#endif } else { RETURN_FALSE; } @@ -848,6 +928,7 @@ PHP_FUNCTION(mysqli_get_warnings) } /* }}} */ + /* {{{ proto object mysqli_stmt_get_warnings(object link) */ PHP_FUNCTION(mysqli_stmt_get_warnings) { @@ -873,6 +954,7 @@ PHP_FUNCTION(mysqli_stmt_get_warnings) } /* }}} */ + #ifdef HAVE_MYSQLI_SET_CHARSET /* {{{ proto bool mysqli_set_charset(object link, string csname) sets client character set */ @@ -928,7 +1010,7 @@ PHP_FUNCTION(mysqli_get_charset) state = cs.state; comment = cs.comment; #else - cs = mysql->mysql->charset; + cs = mysql->mysql->data->charset; if (!cs) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "The connection has no charset associated"); RETURN_NULL(); diff --git a/ext/mysqli/mysqli_priv.h b/ext/mysqli/mysqli_priv.h index 3a7788dba7..9dd11117d1 100644 --- a/ext/mysqli/mysqli_priv.h +++ b/ext/mysqli/mysqli_priv.h @@ -52,11 +52,11 @@ extern const mysqli_property_entry mysqli_stmt_property_entries[]; extern const mysqli_property_entry mysqli_driver_property_entries[]; extern const mysqli_property_entry mysqli_warning_property_entries[]; -extern zend_property_info mysqli_link_property_info_entries[]; -extern zend_property_info mysqli_result_property_info_entries[]; -extern zend_property_info mysqli_stmt_property_info_entries[]; -extern zend_property_info mysqli_driver_property_info_entries[]; -extern zend_property_info mysqli_warning_property_info_entries[]; +extern const zend_property_info mysqli_link_property_info_entries[]; +extern const zend_property_info mysqli_result_property_info_entries[]; +extern const zend_property_info mysqli_stmt_property_info_entries[]; +extern const zend_property_info mysqli_driver_property_info_entries[]; +extern const zend_property_info mysqli_warning_property_info_entries[]; extern int php_le_pmysqli(void); extern void php_mysqli_dtor_p_elements(void *data); @@ -66,7 +66,12 @@ extern void php_mysqli_close(MY_MYSQL * mysql, int close_type, int resource_stat extern void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flag, int into_object); extern void php_clear_stmt_bind(MY_STMT *stmt TSRMLS_DC); extern void php_clear_mysql(MY_MYSQL *); -extern MYSQLI_WARNING *php_get_warnings(MYSQL *mysql TSRMLS_DC); +#ifdef MYSQLI_USE_MYSQLND +extern MYSQLI_WARNING *php_get_warnings(MYSQLND_CONN_DATA * mysql TSRMLS_DC); +#else +extern MYSQLI_WARNING *php_get_warnings(MYSQL * mysql TSRMLS_DC); +#endif + extern void php_clear_warnings(MYSQLI_WARNING *w); extern void php_free_stmt_bind_buffer(BIND_BUFFER bbuf, int type); extern void php_mysqli_report_error(const char *sqlstate, int errorno, const char *error TSRMLS_DC); @@ -78,13 +83,6 @@ extern void php_mysqli_throw_sql_exception(char *sqlstate, int errorno TSRMLS_DC extern PHPAPI zend_class_entry *spl_ce_RuntimeException; #endif -#define REGISTER_MYSQLI_CLASS_ENTRY(name, mysqli_entry, class_functions) { \ - zend_class_entry tmp_ce; \ - INIT_CLASS_ENTRY(tmp_ce, name,class_functions); \ - tmp_ce.create_object = mysqli_objects_new; \ - mysqli_entry = zend_register_internal_class(&tmp_ce TSRMLS_CC); \ -} \ - #define PHP_MYSQLI_EXPORT(__type) PHP_MYSQLI_API __type PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry * TSRMLS_DC); diff --git a/ext/mysqli/mysqli_prop.c b/ext/mysqli/mysqli_prop.c index a9155702a6..908de63d23 100644 --- a/ext/mysqli/mysqli_prop.c +++ b/ext/mysqli/mysqli_prop.c @@ -13,6 +13,7 @@ | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Georg Richter <georg@php.net> | + | Andrey Hristov <andrey@php.net> | +----------------------------------------------------------------------+ $Id$ @@ -189,6 +190,54 @@ static int link_affected_rows_read(mysqli_object *obj, zval **retval TSRMLS_DC) } /* }}} */ + +/* {{{ property link_error_list_read */ +static int link_error_list_read(mysqli_object *obj, zval **retval TSRMLS_DC) +{ + MY_MYSQL *mysql; + + MAKE_STD_ZVAL(*retval); + + CHECK_STATUS(MYSQLI_STATUS_VALID); + + mysql = (MY_MYSQL *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; + + array_init(*retval); + if (mysql) { +#if defined(MYSQLI_USE_MYSQLND) + if (mysql->mysql->data->error_info->error_list) { + MYSQLND_ERROR_LIST_ELEMENT * message; + zend_llist_position pos; + for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(mysql->mysql->data->error_info->error_list, &pos); + message; + message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(mysql->mysql->data->error_info->error_list, &pos)) + { + zval * single_error; + MAKE_STD_ZVAL(single_error); + array_init(single_error); + add_assoc_long_ex(single_error, "errno", sizeof("errno"), message->error_no); + add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), message->sqlstate, 1); + add_assoc_string_ex(single_error, "error", sizeof("error"), message->error, 1); + add_next_index_zval(*retval, single_error); + } + } +#else + if (mysql_errno(mysql->mysql)) { + zval * single_error; + MAKE_STD_ZVAL(single_error); + array_init(single_error); + add_assoc_long_ex(single_error, "errno", sizeof("errno"), mysql_errno(mysql->mysql)); + add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), mysql_sqlstate(mysql->mysql), 1); + add_assoc_string_ex(single_error, "error", sizeof("error"), mysql_error(mysql->mysql), 1); + add_next_index_zval(*retval, single_error); + } +#endif + } + return SUCCESS; +} +/* }}} */ + + /* link properties */ MYSQLI_MAP_PROPERTY_FUNC_LONG(link_errno_read, mysql_errno, MYSQLI_GET_MYSQL(MYSQLI_STATUS_INITIALIZED), ulong, "%lu") MYSQLI_MAP_PROPERTY_FUNC_STRING(link_error_read, mysql_error, MYSQLI_GET_MYSQL(MYSQLI_STATUS_INITIALIZED)) @@ -236,6 +285,7 @@ static int link_stat_read(mysqli_object *obj, zval **retval TSRMLS_DC)\ } /* }}} */ + /* result properties */ /* {{{ property result_type_read */ @@ -340,6 +390,51 @@ static int stmt_affected_rows_read(mysqli_object *obj, zval **retval TSRMLS_DC) } /* }}} */ +/* {{{ property stmt_error_list_read */ +static int stmt_error_list_read(mysqli_object *obj, zval **retval TSRMLS_DC) +{ + MY_STMT * stmt; + + MAKE_STD_ZVAL(*retval); + CHECK_STATUS(MYSQLI_STATUS_INITIALIZED); + + stmt = (MY_STMT *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; + array_init(*retval); + if (stmt && stmt->stmt) { +#if defined(MYSQLI_USE_MYSQLND) + if (stmt->stmt->data && stmt->stmt->data->error_info->error_list) { + MYSQLND_ERROR_LIST_ELEMENT * message; + zend_llist_position pos; + for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(stmt->stmt->data->error_info->error_list, &pos); + message; + message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(stmt->stmt->data->error_info->error_list, &pos)) + { + zval * single_error; + MAKE_STD_ZVAL(single_error); + array_init(single_error); + add_assoc_long_ex(single_error, "errno", sizeof("errno"), message->error_no); + add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), message->sqlstate, 1); + add_assoc_string_ex(single_error, "error", sizeof("error"), message->error, 1); + add_next_index_zval(*retval, single_error); + } + } +#else + if (mysql_stmt_errno(stmt->stmt)) { + zval * single_error; + MAKE_STD_ZVAL(single_error); + array_init(single_error); + add_assoc_long_ex(single_error, "errno", sizeof("errno"), mysql_stmt_errno(stmt->stmt)); + add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), mysql_stmt_sqlstate(stmt->stmt), 1); + add_assoc_string_ex(single_error, "error", sizeof("error"), mysql_stmt_error(stmt->stmt), 1); + add_next_index_zval(*retval, single_error); + } +#endif + } + return SUCCESS; +} +/* }}} */ + + MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_insert_id_read, mysql_stmt_insert_id, MYSQLI_GET_STMT(MYSQLI_STATUS_VALID), my_ulonglong, MYSQLI_LLU_SPEC) MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_num_rows_read, mysql_stmt_num_rows, MYSQLI_GET_STMT(MYSQLI_STATUS_VALID), my_ulonglong, MYSQLI_LLU_SPEC) MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_param_count_read, mysql_stmt_param_count, MYSQLI_GET_STMT(MYSQLI_STATUS_VALID), ulong, "%lu") @@ -357,6 +452,7 @@ const mysqli_property_entry mysqli_link_property_entries[] = { {"connect_error", sizeof("connect_error") - 1, link_connect_error_read, NULL}, {"errno", sizeof("errno") - 1, link_errno_read, NULL}, {"error", sizeof("error") - 1, link_error_read, NULL}, + {"error_list", sizeof("error_list") - 1, link_error_list_read, NULL}, {"field_count", sizeof("field_count") - 1, link_field_count_read, NULL}, {"host_info", sizeof("host_info") - 1, link_host_info_read, NULL}, {"info", sizeof("info") - 1, link_info_read, NULL}, @@ -371,27 +467,28 @@ const mysqli_property_entry mysqli_link_property_entries[] = { {NULL, 0, NULL, NULL} }; -/* should not be const, as it is patched during runtime */ -zend_property_info mysqli_link_property_info_entries[] = { - {ZEND_ACC_PUBLIC, "affected_rows", sizeof("affected_rows") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "client_info", sizeof("client_info") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "client_version", sizeof("client_version") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "connect_errno", sizeof("connect_errno") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "connect_error", sizeof("connect_error") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "errno", sizeof("errno") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "error", sizeof("error") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "field_count", sizeof("field_count") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "host_info", sizeof("host_info") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "info", sizeof("info") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "insert_id", sizeof("insert_id") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "server_info", sizeof("server_info") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "server_version", sizeof("server_version") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "stat", sizeof("stat") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "sqlstate", sizeof("sqlstate") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "protocol_version", sizeof("protocol_version")-1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "thread_id", sizeof("thread_id") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "warning_count", sizeof("warning_count") - 1, 0, NULL, 0, NULL}, - {0, NULL, 0, 0, NULL, 0, NULL} + +const zend_property_info mysqli_link_property_info_entries[] = { + {ZEND_ACC_PUBLIC, "affected_rows", sizeof("affected_rows") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "client_info", sizeof("client_info") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "client_version", sizeof("client_version") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "connect_errno", sizeof("connect_errno") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "connect_error", sizeof("connect_error") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "errno", sizeof("errno") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "error", sizeof("error") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "error_list", sizeof("error_list") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "field_count", sizeof("field_count") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "host_info", sizeof("host_info") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "info", sizeof("info") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "insert_id", sizeof("insert_id") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "server_info", sizeof("server_info") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "server_version", sizeof("server_version") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "stat", sizeof("stat") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "sqlstate", sizeof("sqlstate") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "protocol_version", sizeof("protocol_version")-1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "thread_id", sizeof("thread_id") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "warning_count", sizeof("warning_count") - 1, -1, 0, NULL, 0, NULL}, + {0, NULL, 0, -1, 0, NULL, 0, NULL} }; @@ -404,13 +501,13 @@ const mysqli_property_entry mysqli_result_property_entries[] = { {NULL, 0, NULL, NULL} }; -zend_property_info mysqli_result_property_info_entries[] = { - {ZEND_ACC_PUBLIC, "current_field", sizeof("current_field")-1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "field_count", sizeof("field_count") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "lengths", sizeof("lengths") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "num_rows", sizeof("num_rows") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "type", sizeof("type") - 1, 0, NULL, 0, NULL}, - {0, NULL, 0, 0, NULL, 0, NULL} +const zend_property_info mysqli_result_property_info_entries[] = { + {ZEND_ACC_PUBLIC, "current_field", sizeof("current_field")-1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "field_count", sizeof("field_count") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "lengths", sizeof("lengths") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "num_rows", sizeof("num_rows") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "type", sizeof("type") - 1, -1, 0, NULL, 0, NULL}, + {0, NULL, 0, -1, 0, NULL, 0, NULL} }; const mysqli_property_entry mysqli_stmt_property_entries[] = { @@ -421,23 +518,25 @@ const mysqli_property_entry mysqli_stmt_property_entries[] = { {"field_count", sizeof("field_count") - 1, stmt_field_count_read, NULL}, {"errno", sizeof("errno") - 1, stmt_errno_read, NULL}, {"error", sizeof("error") - 1, stmt_error_read, NULL}, + {"error_list", sizeof("error_list") - 1, stmt_error_list_read, NULL}, {"sqlstate", sizeof("sqlstate") - 1, stmt_sqlstate_read, NULL}, {"id", sizeof("id") - 1, stmt_id_read, NULL}, {NULL, 0, NULL, NULL} }; -zend_property_info mysqli_stmt_property_info_entries[] = { - {ZEND_ACC_PUBLIC, "affected_rows", sizeof("affected_rows") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "insert_id", sizeof("insert_id") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "num_rows", sizeof("num_rows") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "param_count",sizeof("param_count") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "field_count",sizeof("field_count") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "errno", sizeof("errno") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "error", sizeof("error") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "sqlstate", sizeof("sqlstate") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "id", sizeof("id") - 1, 0, NULL, 0, NULL}, - {0, NULL, 0, 0, NULL, 0, NULL} +const zend_property_info mysqli_stmt_property_info_entries[] = { + {ZEND_ACC_PUBLIC, "affected_rows", sizeof("affected_rows") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "insert_id", sizeof("insert_id") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "num_rows", sizeof("num_rows") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "param_count",sizeof("param_count") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "field_count",sizeof("field_count") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "errno", sizeof("errno") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "error", sizeof("error") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "error_list", sizeof("error_list") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "sqlstate", sizeof("sqlstate") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "id", sizeof("id") - 1, -1, 0, NULL, 0, NULL}, + {0, NULL, 0, -1, 0, NULL, 0, NULL} }; /* diff --git a/ext/mysqli/mysqli_report.h b/ext/mysqli/mysqli_report.h index 1675439f34..4035a4b917 100644 --- a/ext/mysqli/mysqli_report.h +++ b/ext/mysqli/mysqli_report.h @@ -34,7 +34,7 @@ #endif typedef struct { - struct timeval starttime, + struct timeval starttime, endtime; /* execution time */ } PR_TIME_INFO; diff --git a/ext/mysqli/mysqli_result_iterator.c b/ext/mysqli/mysqli_result_iterator.c new file mode 100644 index 0000000000..9a2e2634e6 --- /dev/null +++ b/ext/mysqli/mysqli_result_iterator.c @@ -0,0 +1,182 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2012 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 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_01.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. | + +----------------------------------------------------------------------+ + | Authors: Georg Richter <georg@php.net> | + | Andrey Hristov <andrey@php.net> | + | Ulf Wendel <uw@php.net> | + +----------------------------------------------------------------------+ + + $Id: mysqli.c 299335 2010-05-13 11:05:09Z andrey $ +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <signal.h> + +#include "php.h" +#include "php_ini.h" +#include "php_mysqli_structs.h" +#include "mysqli_priv.h" +#include "zend_interfaces.h" + + +extern zend_object_iterator_funcs php_mysqli_result_iterator_funcs; + +typedef struct { + zend_object_iterator intern; + mysqli_object *result; + zval *current_row; + my_longlong row_num; +} php_mysqli_result_iterator; + + +/* {{{ */ +zend_object_iterator *php_mysqli_result_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC) +{ + php_mysqli_result_iterator *iterator; + + if (by_ref) { + zend_error(E_ERROR, "An iterator cannot be used with foreach by reference"); + } + iterator = ecalloc(1, sizeof(php_mysqli_result_iterator)); + + Z_ADDREF_P(object); + iterator->intern.data = (void*)object; + iterator->intern.funcs = &php_mysqli_result_iterator_funcs; + iterator->result = (mysqli_object *) zend_object_store_get_object(object TSRMLS_CC); + iterator->row_num = -1; + + return (zend_object_iterator*)iterator; +} +/* }}} */ + + +/* {{{ */ +static void php_mysqli_result_iterator_dtor(zend_object_iterator *iter TSRMLS_DC) +{ + php_mysqli_result_iterator *iterator = (php_mysqli_result_iterator*) iter; + + /* cleanup handled in sxe_object_dtor as we dont always have an iterator wrapper */ + if (iterator->intern.data) { + zval_ptr_dtor((zval**)&iterator->intern.data); + } + if (iterator->current_row) { + zval_ptr_dtor(&iterator->current_row); + } + efree(iterator); +} +/* }}} */ + + +/* {{{ */ +static int php_mysqli_result_iterator_valid(zend_object_iterator *iter TSRMLS_DC) +{ + php_mysqli_result_iterator *iterator = (php_mysqli_result_iterator*) iter; + + return iterator->current_row && Z_TYPE_P(iterator->current_row) == IS_ARRAY ? SUCCESS : FAILURE; +} +/* }}} */ + + +/* {{{ */ +static void php_mysqli_result_iterator_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC) +{ + php_mysqli_result_iterator *iterator = (php_mysqli_result_iterator*) iter; + + *data = &iterator->current_row; +} +/* }}} */ + + +/* {{{ */ +static void php_mysqli_result_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC) +{ + + php_mysqli_result_iterator *iterator = (php_mysqli_result_iterator*) iter; + mysqli_object *intern = iterator->result; + MYSQL_RES *result; + + MYSQLI_FETCH_RESOURCE_BY_OBJ(result, MYSQL_RES *, intern, "mysqli_result", MYSQLI_STATUS_VALID); + if (iterator->current_row) { + zval_ptr_dtor(&iterator->current_row); + } + MAKE_STD_ZVAL(iterator->current_row); + php_mysqli_fetch_into_hash_aux(iterator->current_row, result, MYSQLI_ASSOC TSRMLS_CC); + if (Z_TYPE_P(iterator->current_row) == IS_ARRAY) { + iterator->row_num++; + } +} +/* }}} */ + + +/* {{{ */ +static void php_mysqli_result_iterator_rewind(zend_object_iterator *iter TSRMLS_DC) +{ + php_mysqli_result_iterator *iterator = (php_mysqli_result_iterator*) iter; + mysqli_object *intern = iterator->result; + MYSQL_RES *result; + + MYSQLI_FETCH_RESOURCE_BY_OBJ(result, MYSQL_RES *, intern, "mysqli_result", MYSQLI_STATUS_VALID); + + if (mysqli_result_is_unbuffered(result)) { +#if MYSQLI_USE_MYSQLND + if (result->unbuf->eof_reached) { +#else + if (result->eof) { +#endif + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Data fetched with MYSQLI_USE_RESULT can be iterated only once"); + return; + } + } else { + mysql_data_seek(result, 0); + } + iterator->row_num = -1; + php_mysqli_result_iterator_move_forward(iter TSRMLS_CC); +} +/* }}} */ + + +/* {{{ php_mysqli_result_iterator_current_key */ +static int php_mysqli_result_iterator_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) +{ + php_mysqli_result_iterator *iterator = (php_mysqli_result_iterator*) iter; + + *int_key = (ulong) iterator->row_num; + return HASH_KEY_IS_LONG; +} +/* }}} */ + + +/* {{{ php_mysqli_result_iterator_funcs */ +zend_object_iterator_funcs php_mysqli_result_iterator_funcs = { + php_mysqli_result_iterator_dtor, + php_mysqli_result_iterator_valid, + php_mysqli_result_iterator_current_data, + php_mysqli_result_iterator_current_key, + php_mysqli_result_iterator_move_forward, + php_mysqli_result_iterator_rewind, +}; +/* }}} */ + + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/mysqli/mysqli_warning.c b/ext/mysqli/mysqli_warning.c index d897a82b8f..33e2b85a2c 100644 --- a/ext/mysqli/mysqli_warning.c +++ b/ext/mysqli/mysqli_warning.c @@ -102,7 +102,7 @@ MYSQLI_WARNING *php_get_warnings(MYSQL *mysql TSRMLS_DC) #else /* {{{ MYSQLI_WARNING *php_new_warning */ static -MYSQLI_WARNING *php_new_warning(const zval *reason, int errorno TSRMLS_DC) +MYSQLI_WARNING *php_new_warning(const zval * reason, int errorno TSRMLS_DC) { MYSQLI_WARNING *w; @@ -123,17 +123,17 @@ MYSQLI_WARNING *php_new_warning(const zval *reason, int errorno TSRMLS_DC) /* {{{ MYSQLI_WARNING *php_get_warnings(MYSQL *mysql TSRMLS_DC) */ -MYSQLI_WARNING *php_get_warnings(MYSQL *mysql TSRMLS_DC) +MYSQLI_WARNING * php_get_warnings(MYSQLND_CONN_DATA * mysql TSRMLS_DC) { MYSQLI_WARNING *w, *first = NULL, *prev = NULL; MYSQL_RES *result; zval *row; - if (mysql_real_query(mysql, "SHOW WARNINGS", 13)) { + if (mysql->m->query(mysql, "SHOW WARNINGS", 13 TSRMLS_CC)) { return NULL; } - result = mysql_use_result(mysql); + result = mysql->m->use_result(mysql TSRMLS_CC); for (;;) { zval **entry; @@ -267,7 +267,9 @@ PHP_METHOD(mysqli_warning, __construct) { zval *z; mysqli_object *obj; +#ifndef MYSQLI_USE_MYSQLND MYSQL *hdl; +#endif MYSQLI_WARNING *w; MYSQLI_RESOURCE *mysqli_resource; @@ -282,23 +284,36 @@ PHP_METHOD(mysqli_warning, __construct) if (obj->zo.ce == mysqli_link_class_entry) { MY_MYSQL *mysql; MYSQLI_FETCH_RESOURCE_CONN(mysql, &z, MYSQLI_STATUS_VALID); - hdl = mysql->mysql; + if (mysql_warning_count(mysql->mysql)) { +#ifndef MYSQLI_USE_MYSQLND + w = php_get_warnings(mysql->mysql TSRMLS_CC); +#else + w = php_get_warnings(mysql->mysql->data TSRMLS_CC); +#endif + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "No warnings found"); + RETURN_FALSE; + } } else if (obj->zo.ce == mysqli_stmt_class_entry) { MY_STMT *stmt; MYSQLI_FETCH_RESOURCE_STMT(stmt, &z, MYSQLI_STATUS_VALID); +#ifndef MYSQLI_USE_MYSQLND hdl = mysqli_stmt_get_connection(stmt->stmt); + if (mysql_warning_count(hdl)) { + w = php_get_warnings(hdl TSRMLS_CC); +#else + if (mysqlnd_stmt_warning_count(stmt->stmt)) { + w = php_get_warnings(mysqli_stmt_get_connection(stmt->stmt) TSRMLS_CC); +#endif + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "No warnings found"); + RETURN_FALSE; + } } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid class argument"); RETURN_FALSE; } - if (mysql_warning_count(hdl)) { - w = php_get_warnings(hdl TSRMLS_CC); - } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "No warnings found"); - RETURN_FALSE; - } - mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); mysqli_resource->ptr = mysqli_resource->info = (void *)w; mysqli_resource->status = MYSQLI_STATUS_VALID; @@ -330,11 +345,11 @@ const mysqli_property_entry mysqli_warning_property_entries[] = { /* }}} */ /* {{{ mysqli_warning_property_info_entries */ -zend_property_info mysqli_warning_property_info_entries[] = { - {ZEND_ACC_PUBLIC, "message", sizeof("message") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "sqlstate", sizeof("sqlstate") - 1, 0, NULL, 0, NULL}, - {ZEND_ACC_PUBLIC, "errno", sizeof("errno") - 1, 0, NULL, 0, NULL}, - {0, NULL, 0, 0, NULL, 0, NULL} +const zend_property_info mysqli_warning_property_info_entries[] = { + {ZEND_ACC_PUBLIC, "message", sizeof("message") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "sqlstate", sizeof("sqlstate") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "errno", sizeof("errno") - 1, -1, 0, NULL, 0, NULL}, + {0, NULL, 0, -1, 0, NULL, 0, NULL} }; /* }}} */ diff --git a/ext/mysqli/php_mysqli_structs.h b/ext/mysqli/php_mysqli_structs.h index 3ef47ef0f1..ed468e2823 100644 --- a/ext/mysqli/php_mysqli_structs.h +++ b/ext/mysqli/php_mysqli_structs.h @@ -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$ @@ -207,6 +209,36 @@ extern zend_class_entry *mysqli_result_class_entry; extern zend_class_entry *mysqli_driver_class_entry; extern zend_class_entry *mysqli_warning_class_entry; extern zend_class_entry *mysqli_exception_class_entry; +extern int php_le_pmysqli(void); +extern void php_mysqli_dtor_p_elements(void *data); + +extern void php_mysqli_close(MY_MYSQL * mysql, int close_type, int resource_status TSRMLS_DC); + +extern zend_object_iterator_funcs php_mysqli_result_iterator_funcs; +extern zend_object_iterator *php_mysqli_result_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC); + +extern void php_mysqli_fetch_into_hash_aux(zval *return_value, MYSQL_RES * result, long fetchtype TSRMLS_DC); + +#ifdef HAVE_SPL +extern PHPAPI zend_class_entry *spl_ce_RuntimeException; +#endif + +#define MYSQLI_DISABLE_MQ if (mysql->multi_query) { \ + mysql_set_server_option(mysql->mysql, MYSQL_OPTION_MULTI_STATEMENTS_OFF); \ + mysql->multi_query = 0; \ +} + +#define MYSQLI_ENABLE_MQ if (!mysql->multi_query) { \ + mysql_set_server_option(mysql->mysql, MYSQL_OPTION_MULTI_STATEMENTS_ON); \ + mysql->multi_query = 1; \ +} + +#define REGISTER_MYSQLI_CLASS_ENTRY(name, mysqli_entry, class_functions) { \ + zend_class_entry ce; \ + INIT_CLASS_ENTRY(ce, name,class_functions); \ + ce.create_object = mysqli_objects_new; \ + mysqli_entry = zend_register_internal_class(&ce TSRMLS_CC); \ +} \ #define MYSQLI_REGISTER_RESOURCE_EX(__ptr, __zval) \ ((mysqli_object *) zend_object_store_get_object(__zval TSRMLS_CC))->ptr = __ptr; @@ -242,6 +274,21 @@ extern zend_class_entry *mysqli_exception_class_entry; }\ } +#define MYSQLI_FETCH_RESOURCE_BY_OBJ(__ptr, __type, __obj, __name, __check) \ +{ \ + MYSQLI_RESOURCE *my_res; \ + if (!(my_res = (MYSQLI_RESOURCE *)(__obj->ptr))) {\ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %s", intern->zo.ce->name);\ + return;\ + }\ + __ptr = (__type)my_res->ptr; \ + if (__check && my_res->status < __check) { \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid object or resource %s\n", intern->zo.ce->name); \ + return;\ + }\ +} + + #define MYSQLI_FETCH_RESOURCE_CONN(__ptr, __id, __check) \ { \ MYSQLI_FETCH_RESOURCE((__ptr), MY_MYSQL *, (__id), "mysqli_link", (__check)); \ @@ -285,7 +332,6 @@ ZEND_BEGIN_MODULE_GLOBALS(mysqli) long num_inactive_persistent; long max_persistent; long allow_persistent; - long cache_size; unsigned long default_port; char *default_host; char *default_user; diff --git a/ext/mysqli/tests/057.phpt b/ext/mysqli/tests/057.phpt index 8c8b3eeed7..2cb887506a 100644 --- a/ext/mysqli/tests/057.phpt +++ b/ext/mysqli/tests/057.phpt @@ -91,6 +91,9 @@ object(mysqli_stmt)#%d (%d) { int(0) [%u|b%"error"]=> %unicode|string%(0) "" + [%u|b%"error_list"]=> + array(0) { + } [%u|b%"sqlstate"]=> %unicode|string%(5) "00000" [%u|b%"id"]=> diff --git a/ext/mysqli/tests/bug34810.phpt b/ext/mysqli/tests/bug34810.phpt index f975506187..1ea89d9bee 100644 --- a/ext/mysqli/tests/bug34810.phpt +++ b/ext/mysqli/tests/bug34810.phpt @@ -77,6 +77,9 @@ object(mysqli)#%d (%d) { int(0) [%u|b%"error"]=> %unicode|string%(0) "" + [%u|b%"error_list"]=> + array(0) { + } [%u|b%"field_count"]=> int(0) [%u|b%"host_info"]=> @@ -89,8 +92,8 @@ object(mysqli)#%d (%d) { %unicode|string%(%d) "%s" [%u|b%"server_version"]=> int(%d) - ["stat"]=> - %s + [%u|b%"stat"]=> + string(%d) "Uptime: %d Threads: %d Questions: %d Slow queries: %d Opens: %d Flush tables: %d Open tables: %d Queries per second avg: %d.%d" [%u|b%"sqlstate"]=> %unicode|string%(5) "00000" [%u|b%"protocol_version"]=> @@ -115,6 +118,8 @@ object(mysqli)#%d (%d) { int(0) [%u|b%"error"]=> %unicode|string%(0) "" + [%u|b%"error_list"]=> + NULL [%u|b%"field_count"]=> NULL [%u|b%"host_info"]=> @@ -127,7 +132,7 @@ object(mysqli)#%d (%d) { NULL [%u|b%"server_version"]=> NULL - ["stat"]=> + [%u|b%"stat"]=> NULL [%u|b%"sqlstate"]=> NULL diff --git a/ext/mysqli/tests/bug55582.phpt b/ext/mysqli/tests/bug55582.phpt index 85fc7f6ce8..3933845147 100644 --- a/ext/mysqli/tests/bug55582.phpt +++ b/ext/mysqli/tests/bug55582.phpt @@ -38,4 +38,4 @@ Warning: mysqli_num_rows(): Function cannot be used with MYSQL_USE_RESULT in %s int(0) NULL int(1) -done
\ No newline at end of file +done diff --git a/ext/mysqli/tests/mysqli_auth_pam.phpt b/ext/mysqli/tests/mysqli_auth_pam.phpt new file mode 100644 index 0000000000..fe1552954a --- /dev/null +++ b/ext/mysqli/tests/mysqli_auth_pam.phpt @@ -0,0 +1,98 @@ +--TEST-- +PAM auth plugin +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('connect.inc'); + +if (version_compare(PHP_VERSION, '5.3.99') >= 0) { + die("SKIP Available as of PHP 5.3.99"); +} + +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + die(sprintf("SKIP Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket)); +} + +if ($link->server_version < 50500) + die(sprintf("SKIP Needs MySQL 5.5 or newer, found MySQL %s\n", $link->server_info)); + +if (!$res = $link->query("SHOW PLUGINS")) + die(sprintf("SKIP [%d] %s\n", $link->errno, $link->error)); + +$have_pam = false; +while ($row = $res->fetch_assoc()) { + if (isset($row['Name']) && ('mysql_clear_password' == $row['Name'])) { + $have_pam = true; + break; + } +} +$res->close(); + +if (!$have_pam) + die("SKIP Server PAM plugin not installed"); + + +mysqli_query($link, 'DROP USER pamtest'); +mysqli_query($link, 'DROP USER pamtest@localhost'); + +if (!mysqli_query($link, 'CREATE USER pamtest@"%" IDENTIFIED WITH mysql_clear_password') || + !mysqli_query($link, 'CREATE USER pamtest@"localhost" IDENTIFIED WITH mysql_clear_password')) { + printf("skip Cannot create second DB user [%d] %s", mysqli_errno($link), mysqli_error($link)); + mysqli_close($link); + die("skip CREATE USER failed"); +} + +if (!$link->query("CREATE TABLE test (id INT)") || !$link->query("INSERT INTO test(id) VALUES (1)")) + die(sprintf("SKIP [%d] %s\n", $link->errno, $link->error)); + + + +if (!mysqli_query($link, sprintf("GRANT SELECT ON TABLE %s.test TO pamtest@'%%'", $db)) || + !mysqli_query($link, sprintf("GRANT SELECT ON TABLE %s.test TO pamtest@'localhost'", $db))) { + printf("skip Cannot grant SELECT to user [%d] %s", mysqli_errno($link), mysqli_error($link)); + mysqli_close($link); + die("skip GRANT failed"); +} +?> +--INI-- +max_execution_time=240 +--FILE-- +<?php + require_once('connect.inc'); + require_once('table.inc'); + + if (!$link = my_mysqli_connect($host, 'pamtest', 'pamtest', $db, $port, $socket)) { + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + } else { + + if (!$res = $link->query("SELECT id FROM test WHERE id = 1")) + printf("[002] [%d] %s\n", $link->errno, $link->error); + + if (!$row = mysqli_fetch_assoc($res)) { + printf("[003] [%d] %s\n", $link->errno, $link->error); + } + + if ($row['id'] != 1) { + printf("[004] Expecting 1 got %s/'%s'", gettype($row['id']), $row['id']); + } + + $res->close(); + $link->close(); + } + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); + mysqli_query($link, 'DROP USER pamtest'); + mysqli_query($link, 'DROP USER pamtest@localhost'); +?> +--EXPECTF-- + +Warning: mysqli_real_connect(): (28000/1045): Access denied for user %s +[001] Cannot connect to the server using host=%s +done! diff --git a/ext/mysqli/tests/mysqli_class_mysqli_properties_no_conn.phpt b/ext/mysqli/tests/mysqli_class_mysqli_properties_no_conn.phpt index 530b4647c4..e4d0b08a85 100644 --- a/ext/mysqli/tests/mysqli_class_mysqli_properties_no_conn.phpt +++ b/ext/mysqli/tests/mysqli_class_mysqli_properties_no_conn.phpt @@ -68,11 +68,6 @@ require_once('skipifconnectfailure.inc'); @$mysqli->sqlstate, gettype(@$mysqli->sqlstate), @mysqli_sqlstate($mysqli), gettype(@mysqli_sqlstate($mysqli))); - assert(@mysqli_stat($mysqli) === @$mysqli->sstat); - printf("mysqli->stat = '%s'/%s ('%s'/%s)\n", - @$mysqli->stat, gettype(@$mysqli->stat), - @mysqli_stat($mysqli), gettype(@mysqli_stat($mysqli))); - assert(@mysqli_get_host_info($mysqli) === @$mysqli->host_info); printf("mysqli->host_info = '%s'/%s ('%s'/%s)\n", @$mysqli->host_info, gettype(@$mysqli->host_info), @@ -151,11 +146,12 @@ Without RS Class variables: affected_rows = 'NULL' client_info = 'NULL' -client_version = '%d' -connect_errno = '%d' -connect_error = '%s' +client_version = '%s' +connect_errno = '%s' +connect_error = ''%s' errno = 'NULL' error = 'NULL' +error_list = 'NULL' field_count = 'NULL' host_info = 'NULL' info = 'NULL' @@ -171,11 +167,12 @@ warning_count = 'NULL' Object variables: affected_rows = 'NULL' client_info = 'NULL' -client_version = '%d' -connect_errno = '%d' +client_version = '%s' +connect_errno = '%s' connect_error = '%s' errno = 'NULL' error = 'NULL' +error_list = 'NULL' field_count = 'NULL' host_info = 'NULL' info = 'NULL' @@ -192,18 +189,17 @@ Magic, magic properties: mysqli->affected_rows = ''/NULL (''/NULL) Warning: assert(): Assertion failed in %s on line %d -mysqli->client_info = ''/NULL ('%s'/string) -mysqli->client_version = '%d'/integer ('%d'/integer) +mysqli->client_info = ''/NULL ('%s'/%s) +mysqli->client_version = '%s'/integer ('%s'/integer) mysqli->errno = ''/NULL (''/NULL) mysqli->error = ''/NULL (''/NULL) mysqli->field_count = ''/NULL (''/NULL) mysqli->insert_id = ''/NULL (''/NULL) mysqli->sqlstate = ''/NULL (''/NULL) -mysqli->stat = ''/NULL (''/NULL) mysqli->host_info = ''/NULL (''/NULL) mysqli->info = ''/NULL (''/NULL) -Warning: assert(): Assertion failed in %s on line 78 +Warning: assert(): Assertion failed in %s on line %d mysqli->thread_id = ''/NULL (''/NULL) mysqli->protocol_version = ''/NULL (''/NULL) mysqli->server_info = ''/NULL (''/NULL) @@ -216,18 +212,19 @@ setting mysqli->unknown, @mysqli_unknown = '13' setting mysqli->unknown, @mysqli_unknown = 'friday' Access hidden properties for MYSLQI_STATUS_INITIALIZED (TODO documentation): -mysqli->connect_error = '%s'/string ('%s'/string) -mysqli->connect_errno = '%d'/integer ('%d'/integer) +mysqli->connect_error = '%s'/%s) +mysqli->connect_errno = '%s'/integer ('%s'/integer) With RS Class variables: affected_rows = 'NULL' client_info = 'NULL' -client_version = '%d' -connect_errno = '%d' +client_version = '%s' +connect_errno = '%s' connect_error = '%s' errno = 'NULL' error = 'NULL' +error_list = 'NULL' field_count = 'NULL' host_info = 'NULL' info = 'NULL' @@ -243,11 +240,12 @@ warning_count = 'NULL' Object variables: affected_rows = 'NULL' client_info = 'NULL' -client_version = '%d' -connect_errno = '%d' +client_version = '%s' +connect_errno = '%s' connect_error = '%s' errno = 'NULL' error = 'NULL' +error_list = 'NULL' field_count = 'NULL' host_info = 'NULL' info = 'NULL' @@ -263,15 +261,14 @@ warning_count = 'NULL' Magic, magic properties: mysqli->affected_rows = ''/NULL (''/NULL) -Warning: assert(): Assertion failed in %s on line %s -mysqli->client_info = ''/NULL ('%s'/string) -mysqli->client_version = '%d'/integer ('%d'/integer) +Warning: assert(): Assertion failed in %s on line %d +mysqli->client_info = ''/NULL ('%s'/%s) +mysqli->client_version = '%s'/integer ('%s'/integer) mysqli->errno = ''/NULL (''/NULL) mysqli->error = ''/NULL (''/NULL) mysqli->field_count = ''/NULL (''/NULL) mysqli->insert_id = ''/NULL (''/NULL) mysqli->sqlstate = ''/NULL (''/NULL) -mysqli->stat = ''/NULL (''/NULL) mysqli->host_info = ''/NULL (''/NULL) mysqli->info = ''/NULL (''/NULL) @@ -288,6 +285,6 @@ setting mysqli->unknown, @mysqli_unknown = '13' setting mysqli->unknown, @mysqli_unknown = 'friday' Access hidden properties for MYSLQI_STATUS_INITIALIZED (TODO documentation): -mysqli->connect_error = '%s'/string ('%s'/string) -mysqli->connect_errno = '%d'/integer ('%d'/integer) +mysqli->connect_error = '%s'/%s) +mysqli->connect_errno = '%s'/integer ('%s'/integer) done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_class_mysqli_reflection.phpt b/ext/mysqli/tests/mysqli_class_mysqli_reflection.phpt index 0e0fe6cf57..5fd4b6f45c 100644 --- a/ext/mysqli/tests/mysqli_class_mysqli_reflection.phpt +++ b/ext/mysqli/tests/mysqli_class_mysqli_reflection.phpt @@ -173,22 +173,6 @@ Modifiers: 256 Number of Parameters: 0 Number of Required Parameters: 0 -Inspecting method 'client_encoding' -isFinal: no -isAbstract: no -isPublic: yes -isPrivate: no -isProtected: no -isStatic: no -isConstructor: no -isDestructor: no -isInternal: yes -isUserDefined: no -returnsReference: no -Modifiers: 256 -Number of Parameters: 0 -Number of Required Parameters: 0 - Inspecting method 'close' isFinal: no isAbstract: no @@ -1145,6 +1129,14 @@ isStatic: no isDefault: yes Modifiers: 256 +Inspecting property 'error_list' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 + Inspecting property 'field_count' isPublic: yes isPrivate: no @@ -1239,6 +1231,7 @@ Default property 'connect_errno' Default property 'connect_error' Default property 'errno' Default property 'error' +Default property 'error_list' Default property 'field_count' Default property 'host_info' Default property 'info' diff --git a/ext/mysqli/tests/mysqli_class_mysqli_result_reflection.phpt b/ext/mysqli/tests/mysqli_class_mysqli_result_reflection.phpt index b86129c57e..988b82732a 100644 --- a/ext/mysqli/tests/mysqli_class_mysqli_result_reflection.phpt +++ b/ext/mysqli/tests/mysqli_class_mysqli_result_reflection.phpt @@ -35,7 +35,7 @@ isInstantiable: yes isInterface: no isAbstract: no isFinal: no -isIteratable: no +isIteratable: yes Modifiers: '0' Parent Class: '' Extension: 'mysqli' @@ -234,9 +234,23 @@ isInternal: yes isUserDefined: no returnsReference: no Modifiers: 256 -Number of Parameters: 0 +Number of Parameters: 2 Number of Required Parameters: 0 +Inspecting parameter 'class_name' of method 'fetch_object' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + +Inspecting parameter 'params' of method 'fetch_object' +isArray: yes +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + Inspecting method 'fetch_row' isFinal: no isAbstract: no diff --git a/ext/mysqli/tests/mysqli_class_mysqli_stmt_interface.phpt b/ext/mysqli/tests/mysqli_class_mysqli_stmt_interface.phpt index 7cbb127212..acf7379198 100644 --- a/ext/mysqli/tests/mysqli_class_mysqli_stmt_interface.phpt +++ b/ext/mysqli/tests/mysqli_class_mysqli_stmt_interface.phpt @@ -97,6 +97,9 @@ printf("stmt->errno = '%s'\n", $stmt->errno); assert(mysqli_stmt_error($stmt) === $stmt->error); printf("stmt->error = '%s'\n", $stmt->error); +assert(mysqli_stmt_error_list($stmt) === $stmt->error_list); +var_dump("stmt->error = ", $stmt->error_list); + assert(mysqli_stmt_field_count($stmt) === $stmt->field_count); printf("stmt->field_count = '%s'\n", $stmt->field_count); @@ -143,6 +146,7 @@ Class variables: affected_rows errno error +error_list field_count id insert_id @@ -158,6 +162,7 @@ param_count field_count errno error +error_list sqlstate id @@ -173,6 +178,9 @@ stmt->affected_rows = '' stmt->affected_rows = '1' stmt->errno = '0' stmt->error = '' +string(14) "stmt->error = " +array(0) { +} stmt->field_count = '0' stmt->id = '%d' stmt->insert_id = '0' diff --git a/ext/mysqli/tests/mysqli_fetch_array_large.phpt b/ext/mysqli/tests/mysqli_fetch_array_large.phpt index ae83b3f8b1..3c6a0f03f3 100644 --- a/ext/mysqli/tests/mysqli_fetch_array_large.phpt +++ b/ext/mysqli/tests/mysqli_fetch_array_large.phpt @@ -5,6 +5,8 @@ mysqli_fetch_array() - large packages (to test compression) require_once('skipif.inc'); require_once('skipifconnectfailure.inc'); ?> +--INI-- +memory_limit=-1 --FILE-- <?php require_once("connect.inc"); @@ -164,4 +166,4 @@ require_once('skipifconnectfailure.inc'); --EXPECTF-- stop: %s stop: %s -done!
\ No newline at end of file +done! diff --git a/ext/mysqli/tests/mysqli_fetch_object.phpt b/ext/mysqli/tests/mysqli_fetch_object.phpt index f164c4e19b..c70871e6ea 100644 --- a/ext/mysqli/tests/mysqli_fetch_object.phpt +++ b/ext/mysqli/tests/mysqli_fetch_object.phpt @@ -10,6 +10,8 @@ require_once('skipifconnectfailure.inc'); <?php include_once("connect.inc"); + set_error_handler('handle_catchable_fatal'); + $tmp = NULL; $link = NULL; @@ -57,7 +59,7 @@ require_once('skipifconnectfailure.inc'); } - $obj = mysqli_fetch_object($res, 'mysqli_fetch_object_construct', null); + $obj = mysqli_fetch_object($res, 'mysqli_fetch_object_construct', array()); if (($obj->ID !== "3") || ($obj->label !== "c") || ($obj->a !== NULL) || ($obj->b !== NULL) || (get_class($obj) != 'mysqli_fetch_object_construct')) { printf("[006] Object seems wrong. [%d] %s\n", mysqli_errno($link), mysqli_error($link)); @@ -97,7 +99,7 @@ require_once('skipifconnectfailure.inc'); Also, I did not ask to get exceptions using the mysqli_options() */ try { - if (false !== ($obj = mysqli_fetch_object($res, 'mysqli_fetch_object_construct', 'a'))) + if (false !== ($obj = @mysqli_fetch_object($res, 'mysqli_fetch_object_construct', 'a'))) printf("[011] Should have failed\n"); } catch (Exception $e) { printf("%s\n", $e->getMessage()); @@ -136,22 +138,19 @@ require_once('skipifconnectfailure.inc'); require_once("clean_table.inc"); ?> --EXPECTF-- -Warning: Missing argument 1 for mysqli_fetch_object_construct::__construct() in %s on line %d - -Warning: Missing argument 2 for mysqli_fetch_object_construct::__construct() in %s on line %d - -Notice: Undefined variable: a in %s on line %d - -Notice: Undefined variable: b in %s on line %d - -Warning: Missing argument 2 for mysqli_fetch_object_construct::__construct() in %s on line %d - -Notice: Undefined variable: b in %s on line %d +[E_WARNING] mysqli_fetch_object() expects at least 1 parameter, 0 given in %s on line %d +[E_WARNING] mysqli_fetch_object() expects parameter 1 to be mysqli_result, null given in %s on line %d +[E_WARNING] Missing argument 1 for mysqli_fetch_object_construct::__construct() in %s on line %d +[E_WARNING] Missing argument 2 for mysqli_fetch_object_construct::__construct() in %s on line %d +[E_NOTICE] Undefined variable: a in %s on line %d +[E_NOTICE] Undefined variable: b in %s on line %d +[E_WARNING] Missing argument 2 for mysqli_fetch_object_construct::__construct() in %s on line %d +[E_NOTICE] Undefined variable: b in %s on line %d NULL NULL - -Warning: mysqli_fetch_object(): Couldn't fetch mysqli_result in %s on line %d +[E_WARNING] mysqli_fetch_object(): Couldn't fetch mysqli_result in %s on line %d NULL +[E_RECOVERABLE_ERROR] Argument 3 passed to mysqli_fetch_object() must be of the type array, string given in %s on line %d Parameter ctor_params must be an array Fatal error: Class 'this_class_does_not_exist' not found in %s on line %d
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_fetch_object_oo.phpt b/ext/mysqli/tests/mysqli_fetch_object_oo.phpt index 3b263e49e4..1d62c6dd4f 100644 --- a/ext/mysqli/tests/mysqli_fetch_object_oo.phpt +++ b/ext/mysqli/tests/mysqli_fetch_object_oo.phpt @@ -9,6 +9,7 @@ require_once('skipifconnectfailure.inc'); --FILE-- <?php require_once("connect.inc"); + set_error_handler('handle_catchable_fatal'); $tmp = NULL; $link = NULL; @@ -110,21 +111,24 @@ require_once('skipifconnectfailure.inc'); require_once("clean_table.inc"); ?> --EXPECTF-- -Warning: Missing argument 1 for mysqli_fetch_object_construct::__construct() in %s on line %d - -Warning: Missing argument 2 for mysqli_fetch_object_construct::__construct() in %s on line %d - -Notice: Undefined variable: a in %s on line %d - -Notice: Undefined variable: b in %s on line %d - -Warning: Missing argument 2 for mysqli_fetch_object_construct::__construct() in %s on line %d - -Notice: Undefined variable: b in %s on line %d +[E_WARNING] mysqli_result::__construct(): invalid object or resource mysql%s +%s on line %d +[E_WARNING] mysqli_result::fetch_object(): Couldn't fetch mysqli_result in %s on line %d +[E_WARNING] mysqli_result::fetch_object() expects parameter 1 to be string, object given in %s on line %d +[E_RECOVERABLE_ERROR] Argument 2 passed to mysqli_result::fetch_object() must be of the type array, object given in %s on line %d +[E_WARNING] mysqli_result::fetch_object() expects parameter 1 to be string, object given in %s on line %d +[E_RECOVERABLE_ERROR] Argument 2 passed to mysqli_result::fetch_object() must be of the type array, object given in %s on line %d +[E_WARNING] mysqli_result::fetch_object() expects at most 2 parameters, 3 given in %s on line %d +[E_RECOVERABLE_ERROR] Argument 2 passed to mysqli_result::fetch_object() must be of the type array, null given in %s on line %d +[E_WARNING] Missing argument 1 for mysqli_fetch_object_construct::__construct() in %s on line %d +[E_WARNING] Missing argument 2 for mysqli_fetch_object_construct::__construct() in %s on line %d +[E_NOTICE] Undefined variable: a in %s on line %d +[E_NOTICE] Undefined variable: b in %s on line %d +[E_WARNING] Missing argument 2 for mysqli_fetch_object_construct::__construct() in %s on line %d +[E_NOTICE] Undefined variable: b in %s on line %d NULL NULL - -Warning: mysqli_fetch_object(): Couldn't fetch mysqli_result in %s on line %d +[E_WARNING] mysqli_fetch_object(): Couldn't fetch mysqli_result in %s on line %d NULL Fatal error: Class 'this_class_does_not_exist' not found in %s on line %d
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_free_result.phpt b/ext/mysqli/tests/mysqli_free_result.phpt index a065e14821..28f338ac6d 100644 --- a/ext/mysqli/tests/mysqli_free_result.phpt +++ b/ext/mysqli/tests/mysqli_free_result.phpt @@ -10,7 +10,6 @@ require_once('skipifconnectfailure.inc'); <?php require_once("connect.inc"); - $db = 'test'; $tmp = NULL; $link = NULL; @@ -76,4 +75,4 @@ bool(false) Warning: mysqli_free_result() expects parameter 1 to be mysqli_result, boolean given in %s on line %d NULL -done!
\ No newline at end of file +done! diff --git a/ext/mysqli/tests/mysqli_get_cache_stats_off.phpt b/ext/mysqli/tests/mysqli_get_cache_stats_off.phpt deleted file mode 100644 index bbfe503b2b..0000000000 --- a/ext/mysqli/tests/mysqli_get_cache_stats_off.phpt +++ /dev/null @@ -1,56 +0,0 @@ ---TEST-- -mysqli_get_cache_stats() - disabled via php.ini ---INI-- -mysqlnd.collect_statistics="0" -mysqlnd.collect_memory_statistics="0" ---SKIPIF-- -<?PHP -require_once('skipif.inc'); -require_once('skipifemb.inc'); -require_once('skipifconnectfailure.inc'); -if (!function_exists('mysqli_get_cache_stats')) { - die("skip only available with mysqlnd"); -} -?> ---FILE-- -<?php - $before = mysqli_get_cache_stats(); - /* - NOTE: the function belongs to the mysqnd zval cache. The - mysqlnd zval cache was part of PHP from PHP 5.3.0(-dev) to - PHP 5.3.0RC3 or something. And it was turned off by default. - The function never returned anything meaningful in any released version of PHP. - */ - if (!is_array($before)) { - printf("[001] Expecting array, got %s.\n", gettype($before)); - var_dump($before); - } - - require_once('table.inc'); - if (!$res = mysqli_query($link, "SELECT id, label FROM test")) { - printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - } - while ($row = mysqli_fetch_assoc($res)) - ; - if (!$res = mysqli_query($link, "SELECT id, label FROM test")) { - printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - } - while ($row = mysqli_fetch_assoc($res)) - ; - - $after = mysqli_get_cache_stats(); - if ($before !== $after) { - printf("[002] Statistics have changed\n"); - var_dump($before); - var_dump($after); - } - mysqli_close($link); - - print "done!"; -?> ---CLEAN-- -<?php - require_once("clean_table.inc"); -?> ---EXPECTF-- -done! diff --git a/ext/mysqli/tests/mysqli_kill.phpt b/ext/mysqli/tests/mysqli_kill.phpt index 3606fda0b1..94e4e8f2e0 100644 --- a/ext/mysqli/tests/mysqli_kill.phpt +++ b/ext/mysqli/tests/mysqli_kill.phpt @@ -42,33 +42,33 @@ require_once('skipifconnectfailure.inc'); var_dump($link); if ($IS_MYSQLND) { if ($link->info != 'Records: 6 Duplicates: 0 Warnings: 0') { - printf("[008] mysqlnd used to be more verbose and used to support SELECT"); + printf("[008] mysqlnd used to be more verbose and used to support SELECT\n"); } if ($link->stat != NULL) { printf("[009] NULL expected because of error.\n"); } } else { if ($link->info != NULL) { - printf("[010] Time for wonders - libmysql has started to support SELECT, change test"); + printf("[008] Time for wonders - libmysql has started to support SELECT, change test\n"); } } mysqli_close($link); if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) - printf("[011] Cannot connect, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + printf("[010] Cannot connect, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); mysqli_kill($link, -1); if ((!$res = mysqli_query($link, "SELECT id FROM test LIMIT 1")) || (!$tmp = mysqli_fetch_assoc($res))) { - printf("[012] Connection should not be gone, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + printf("[011] Connection should not be gone, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } var_dump($tmp); mysqli_free_result($res); mysqli_close($link); if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) - printf("[013] Cannot connect, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + printf("[012] Cannot connect, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); mysqli_change_user($link, "This might work if you accept anonymous users in your setup", "password", $db); mysqli_kill($link, -1); @@ -99,6 +99,18 @@ object(mysqli)#%d (%d) { int(2006) [%u|b%"error"]=> %unicode|string%(%d) "%s" + [%u|b%"error_list"]=> + array(1) { + [0]=> + array(3) { + [%u|b%"errno"]=> + int(2006) + [%u|b%"sqlstate"]=> + %unicode|string%(5) "%s" + [%u|b%"error"]=> + %unicode|string%(%d) "%s" + } + } [%u|b%"field_count"]=> int(0) [%u|b%"host_info"]=> @@ -111,7 +123,7 @@ object(mysqli)#%d (%d) { %unicode|string%(%d) "%s" [%u|b%"server_version"]=> int(%d) - ["stat"]=> + [%u|b%"stat"]=> %s [%u|b%"sqlstate"]=> %unicode|string%(5) "HY000" @@ -130,4 +142,4 @@ array(1) { } Warning: mysqli_kill(): processid should have positive value in %s on line %d -done! +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_magic_quotes.phpt b/ext/mysqli/tests/mysqli_magic_quotes.phpt deleted file mode 100644 index 16848a8e8f..0000000000 --- a/ext/mysqli/tests/mysqli_magic_quotes.phpt +++ /dev/null @@ -1,128 +0,0 @@ ---TEST-- -magic_quotes_runtime (DEPRECATED) ---SKIPIF-- -<?php -require_once('skipif.inc'); -require_once('skipifemb.inc'); -require_once('skipifconnectfailure.inc'); - -if (version_compare(PHP_VERSION, '5.3.98') >= 0) { - die("skip: PHP 5.3 test"); -} -?> ---INI-- -magic_quotes_runtime=1 ---FILE-- -<?php - require('connect.inc'); - - if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) - printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); - - $query = sprintf("SELECT '%s', '%s', '%s', '%s' FROM DUAL", - mysqli_real_escape_string($link, "'"), - mysqli_real_escape_string($link, '"'), - mysqli_real_escape_string($link, '\0'), - mysqli_real_escape_string($link, '\\')); - - if (!$res = mysqli_query($link, $query)) { - printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - } - - while ($row = $res->fetch_assoc()) { - var_dump($row); - } - - $res->free(); - - $expected = array( - "'" => "\\'", - '"' => "\\\"", - "\\0" => "\\\\0", - "\\" => "\\\\", - ); - $expectedBoth = array( - 0 => "\\'", - "'" => "\\'", - 1 => "\\\"", - '"' => "\\\"", - 2 => "\\\\0", - "\\0" => "\\\\0", - 3 => "\\\\", - "\\" => "\\\\", - ); - - if (!$res = mysqli_query($link, $query)) { - printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - } - $row = mysqli_fetch_row($res); - echo "Equal:";var_dump($row === array_values($expected)); - if ($row !== array_values($expected)) { - var_dump($row, array_values($expected)); - } - $res->free(); - - if (!$res = mysqli_query($link, $query)) { - printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - } - $row = mysqli_fetch_array($res, MYSQLI_BOTH); - echo "Equal:";var_dump($row === $expectedBoth); - if ($row !== $expectedBoth) { - var_dump($row, $expectedBoth); - } - $res->free(); - - class fetch_object { - public function __set($key, $value) { - printf(">%s< => >%s<\n", $key, $value); - } - } - - if (!$res = mysqli_query($link, $query)) { - printf("[013] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - } - $obj = mysqli_fetch_object($res, "fetch_object"); - $res->free(); - - if (false && $IS_MYSQLND) { - if (!$res = mysqli_query($link, $query)) { - printf("[014] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - } - $row = @mysqli_fetch_all($res, MYSQLI_ASSOC); - if ($row[0] !== $expected) { - printf("[015] Wrong data, dumping\n"); - var_dump($row); - } - } - - $link->close(); - - print "done!"; -?> ---EXPECTF-- -Deprecated: Directive 'magic_quotes_runtime' is deprecated in PHP 5.3 and greater in Unknown on line %d - -Warning: mysqli_result::fetch_assoc(): magic_quotes_runtime are deprecated since PHP 5.3 in %s on line %d -array(4) { - ["'"]=> - string(2) "\'" - ["""]=> - string(2) "\"" - ["\0"]=> - string(3) "\\0" - ["\"]=> - string(2) "\\" -} - -Warning: mysqli_fetch_row(): magic_quotes_runtime are deprecated since PHP 5.3 in %s on line %d -Equal:bool(true) - -Warning: mysqli_fetch_array(): magic_quotes_runtime are deprecated since PHP 5.3 in %s on line %d -Equal:bool(true) - -Warning: mysqli_fetch_object(): magic_quotes_runtime are deprecated since PHP 5.3 in %s on line %d ->'< => >\'< ->"< => >\"< ->\0< => >\\0< ->\< => >\\< -done! diff --git a/ext/mysqli/tests/mysqli_options_openbasedir.phpt b/ext/mysqli/tests/mysqli_options_openbasedir.phpt index 81d8ffef64..500baf3781 100644 --- a/ext/mysqli/tests/mysqli_options_openbasedir.phpt +++ b/ext/mysqli/tests/mysqli_options_openbasedir.phpt @@ -7,10 +7,10 @@ require_once('skipifemb.inc'); require_once('skipifconnectfailure.inc'); ?> --INI-- -open_basedir="." --FILE-- <?php require_once('connect.inc'); + ini_set("open_basedir", __DIR__); if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[001] Cannot connect, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); diff --git a/ext/mysqli/tests/mysqli_phpinfo.phpt b/ext/mysqli/tests/mysqli_phpinfo.phpt index d60636ae40..e23a5f696f 100644 --- a/ext/mysqli/tests/mysqli_phpinfo.phpt +++ b/ext/mysqli/tests/mysqli_phpinfo.phpt @@ -46,7 +46,7 @@ require_once('skipifconnectfailure.inc'); if ($IS_MYSQLND) { $expected = array( - 'client statistics', + 'mysqlnd statistics', 'bytes_sent', 'bytes_received', 'packets_sent', 'packets_received', 'protocol_overhead_in', 'protocol_overhead_out', 'result_set_queries', 'non_result_set_queries', 'no_index_used', 'bad_index_used', diff --git a/ext/mysqli/tests/mysqli_query_iterators.phpt b/ext/mysqli/tests/mysqli_query_iterators.phpt new file mode 100644 index 0000000000..2577aa76ee --- /dev/null +++ b/ext/mysqli/tests/mysqli_query_iterators.phpt @@ -0,0 +1,201 @@ +--TEST-- +mysqli iterators +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + require('table.inc'); + + echo "--- Testing default ---\n"; + if (!is_object($res = mysqli_query($link, "SELECT id FROM test ORDER BY id"))) + printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + else { + foreach ($res as $row) { + var_dump($row); + } + echo "======\n"; + foreach ($res as $row) { + var_dump($row); + } + mysqli_free_result($res); + foreach ($res as $row) { + var_dump($row); + } + } + echo "--- Testing USE_RESULT ---\n"; + if (!is_object($res = mysqli_query($link, "SELECT id FROM test ORDER BY id", MYSQLI_USE_RESULT))) + printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + else { + foreach ($res as $row) { + var_dump($row); + } + echo "======\n"; + foreach ($res as $row) { + var_dump($row); + } + mysqli_free_result($res); + } + + echo "--- Testing STORE_RESULT ---\n"; + if (!is_object($res = mysqli_query($link, "SELECT id FROM test ORDER BY id", MYSQLI_STORE_RESULT))) + printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + else { + foreach ($res as $row) { + var_dump($row); + } + echo "======\n"; + foreach ($res as $row) { + var_dump($row); + } + mysqli_free_result($res); + } + + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +--- Testing default --- +array(1) { + ["id"]=> + string(1) "1" +} +array(1) { + ["id"]=> + string(1) "2" +} +array(1) { + ["id"]=> + string(1) "3" +} +array(1) { + ["id"]=> + string(1) "4" +} +array(1) { + ["id"]=> + string(1) "5" +} +array(1) { + ["id"]=> + string(1) "6" +} +====== +array(1) { + ["id"]=> + string(1) "1" +} +array(1) { + ["id"]=> + string(1) "2" +} +array(1) { + ["id"]=> + string(1) "3" +} +array(1) { + ["id"]=> + string(1) "4" +} +array(1) { + ["id"]=> + string(1) "5" +} +array(1) { + ["id"]=> + string(1) "6" +} + +Warning: main(): Couldn't fetch mysqli_result in %s on line %d +--- Testing USE_RESULT --- +array(1) { + ["id"]=> + string(1) "1" +} +array(1) { + ["id"]=> + string(1) "2" +} +array(1) { + ["id"]=> + string(1) "3" +} +array(1) { + ["id"]=> + string(1) "4" +} +array(1) { + ["id"]=> + string(1) "5" +} +array(1) { + ["id"]=> + string(1) "6" +} +====== + +Warning: main(): Data fetched with MYSQLI_USE_RESULT can be iterated only once in %s on line %d +--- Testing STORE_RESULT --- +array(1) { + ["id"]=> + string(1) "1" +} +array(1) { + ["id"]=> + string(1) "2" +} +array(1) { + ["id"]=> + string(1) "3" +} +array(1) { + ["id"]=> + string(1) "4" +} +array(1) { + ["id"]=> + string(1) "5" +} +array(1) { + ["id"]=> + string(1) "6" +} +====== +array(1) { + ["id"]=> + string(1) "1" +} +array(1) { + ["id"]=> + string(1) "2" +} +array(1) { + ["id"]=> + string(1) "3" +} +array(1) { + ["id"]=> + string(1) "4" +} +array(1) { + ["id"]=> + string(1) "5" +} +array(1) { + ["id"]=> + string(1) "6" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_real_connect.phpt b/ext/mysqli/tests/mysqli_real_connect.phpt index b9ba98693f..5477ea1745 100644 --- a/ext/mysqli/tests/mysqli_real_connect.phpt +++ b/ext/mysqli/tests/mysqli_real_connect.phpt @@ -175,43 +175,45 @@ require_once('skipifconnectfailure.inc'); require_once("clean_table.inc"); ?> --EXPECTF-- -Warning: mysqli_real_connect(): (%d/%d): Access denied for user '%s'@'%s' (using password: YES) in %s on line %d -object(mysqli)#%d (18) { - ["affected_rows"]=> +Warning: mysqli_real_connect(): (%s/%d): Access denied for user '%s'@'%s' (using password: YES) in %s on line %d +object(mysqli)#%d (%d) { + [%u|b%"affected_rows"]=> NULL - ["client_info"]=> + [%u|b%"client_info"]=> %s - ["client_version"]=> + [%u|b%"client_version"]=> int(%d) - ["connect_errno"]=> - int(0) - ["connect_error"]=> - %s - ["errno"]=> + [%u|b%"connect_errno"]=> + int(%d) + [%u|b%"connect_error"]=> + NULL + [%u|b%"errno"]=> %s - ["error"]=> + [%u|b%"error"]=> %s - ["field_count"]=> + [%u|b%"error_list"]=> NULL - ["host_info"]=> - %s - ["info"]=> + [%u|b%"field_count"]=> + NULL + [%u|b%"host_info"]=> + NULL + [%u|b%"info"]=> NULL - ["insert_id"]=> + [%u|b%"insert_id"]=> NULL - ["server_info"]=> + [%u|b%"server_info"]=> NULL - ["server_version"]=> + [%u|b%"server_version"]=> NULL - ["stat"]=> + [%u|b%"stat"]=> NULL - ["sqlstate"]=> + [%u|b%"sqlstate"]=> NULL - ["protocol_version"]=> + [%u|b%"protocol_version"]=> NULL - ["thread_id"]=> + [%u|b%"thread_id"]=> NULL - ["warning_count"]=> + [%u|b%"warning_count"]=> NULL } diff --git a/ext/mysqli/tests/mysqli_real_connect_pconn.phpt b/ext/mysqli/tests/mysqli_real_connect_pconn.phpt index 5dedd47c96..4cc18198c6 100644 --- a/ext/mysqli/tests/mysqli_real_connect_pconn.phpt +++ b/ext/mysqli/tests/mysqli_real_connect_pconn.phpt @@ -151,5 +151,5 @@ mysqli.max_persistent=10 require_once("clean_table.inc"); ?> --EXPECTF-- -Warning: mysqli_real_connect(): (%d/%d): Access denied for user '%s'@'%s' (using password: YES) in %s on line %d +Warning: mysqli_real_connect(): (%s/%d): Access denied for user '%s'@'%s' (using password: YES) in %s on line %d done! |