diff options
author | Georg Richter <georg@php.net> | 2006-09-26 13:06:13 +0000 |
---|---|---|
committer | Georg Richter <georg@php.net> | 2006-09-26 13:06:13 +0000 |
commit | 1432e7b40f08515d95b035fe47daeb39aaee3197 (patch) | |
tree | 88445bf63ab26557ee57c1e4db6228f570c42b41 | |
parent | 798d93c4daa3f417314e1107124bc820ae73bdfc (diff) | |
download | php-git-1432e7b40f08515d95b035fe47daeb39aaee3197.tar.gz |
added unicode support for mysqli extension
55 files changed, 956 insertions, 518 deletions
diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c index 81a1f9924b..d76845faf4 100644 --- a/ext/mysqli/mysqli.c +++ b/ext/mysqli/mysqli.c @@ -243,21 +243,30 @@ zval *mysqli_read_property(zval *object, zval *member, int type TSRMLS_DC) ret = FAILURE; obj = (mysqli_object *)zend_objects_get_address(object TSRMLS_CC); - if (member->type != IS_STRING) { + if (member->type != IS_STRING && member->type != IS_UNICODE) { tmp_member = *member; zval_copy_ctor(&tmp_member); - convert_to_string(&tmp_member); + convert_to_text(&tmp_member); member = &tmp_member; } if (obj->prop_handler != NULL) { - ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd); + ret = zend_u_hash_find(obj->prop_handler, UG(unicode)?IS_UNICODE:IS_STRING, Z_UNIVAL_P(member), Z_UNILEN_P(member)+1, (void **) &hnd); } if (ret == SUCCESS) { - if (strcmp(obj->zo.ce->name.s, "mysqli_driver") && - (!obj->ptr || ((MYSQLI_RESOURCE *)(obj->ptr))->status < MYSQLI_STATUS_INITIALIZED)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %s", obj->zo.ce->name ); + int is_driver; + + if (UG(unicode)) { + UChar *ustr = USTR_MAKE("mysqli_driver"); + is_driver = u_strcmp(obj->zo.ce->name.u, ustr); + USTR_FREE(ustr); + } else { + is_driver = strcmp(obj->zo.ce->name.s, "mysqli_driver"); + } + + if (is_driver && (!obj->ptr || ((MYSQLI_RESOURCE *)(obj->ptr))->status < MYSQLI_STATUS_INITIALIZED)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %R", UG(unicode)?IS_UNICODE:IS_STRING, obj->zo.ce->name ); retval = EG(uninitialized_zval_ptr); return(retval); } @@ -301,7 +310,7 @@ void mysqli_write_property(zval *object, zval *member, zval *value TSRMLS_DC) obj = (mysqli_object *)zend_objects_get_address(object TSRMLS_CC); if (obj->prop_handler != NULL) { - ret = zend_hash_find((HashTable *)obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd); + ret = zend_u_hash_find((HashTable *)obj->prop_handler, Z_TYPE_P(member), Z_UNIVAL_P(member), Z_UNILEN_P(member)+1, (void **) &hnd); } if (ret == SUCCESS) { hnd->write_func(obj, value TSRMLS_CC); @@ -387,7 +396,7 @@ PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry *class_ mysqli_base_class = mysqli_base_class->parent; } - zend_hash_find(&classes, mysqli_base_class->name.s, mysqli_base_class->name_length + 1, + zend_u_hash_find(&classes, UG(unicode)?IS_UNICODE:IS_STRING, mysqli_base_class->name, mysqli_base_class->name_length + 1, (void **) &intern->prop_handler); zend_object_std_init(&intern->zo, class_type TSRMLS_CC); @@ -490,7 +499,7 @@ PHP_MINIT_FUNCTION(mysqli) mysqli_object_handlers.get_property_ptr_ptr = std_hnd->get_property_ptr_ptr; mysqli_object_handlers.get_constructor = php_mysqli_constructor_get; - zend_hash_init(&classes, 0, NULL, NULL, 1); + zend_u_hash_init(&classes, 0, NULL, NULL, 1, 1); INIT_CLASS_ENTRY(cex, "mysqli_sql_exception", mysqli_exception_methods); #ifdef HAVE_SPL @@ -504,36 +513,37 @@ PHP_MINIT_FUNCTION(mysqli) REGISTER_MYSQLI_CLASS_ENTRY("mysqli_driver", mysqli_driver_class_entry, mysqli_driver_methods); ce = mysqli_driver_class_entry; - zend_hash_init(&mysqli_driver_properties, 0, NULL, NULL, 1); + zend_u_hash_init(&mysqli_driver_properties, 0, NULL, NULL, 1, 1); MYSQLI_ADD_PROPERTIES(&mysqli_driver_properties, mysqli_driver_property_entries); zend_hash_add(&classes, ce->name.s, ce->name_length+1, &mysqli_driver_properties, sizeof(mysqli_driver_properties), NULL); ce->ce_flags |= ZEND_ACC_FINAL_CLASS; REGISTER_MYSQLI_CLASS_ENTRY("mysqli", mysqli_link_class_entry, mysqli_link_methods); ce = mysqli_link_class_entry; - zend_hash_init(&mysqli_link_properties, 0, NULL, NULL, 1); + zend_u_hash_init(&mysqli_link_properties, 0, NULL, NULL, 1, 1); MYSQLI_ADD_PROPERTIES(&mysqli_link_properties, mysqli_link_property_entries); zend_hash_add(&classes, ce->name.s, ce->name_length+1, &mysqli_link_properties, sizeof(mysqli_link_properties), NULL); REGISTER_MYSQLI_CLASS_ENTRY("mysqli_warning", mysqli_warning_class_entry, mysqli_warning_methods); ce = mysqli_warning_class_entry; ce->ce_flags |= ZEND_ACC_FINAL_CLASS | ZEND_ACC_PROTECTED; - zend_hash_init(&mysqli_warning_properties, 0, NULL, NULL, 1); + zend_u_hash_init(&mysqli_warning_properties, 0, NULL, NULL, 1, 1); MYSQLI_ADD_PROPERTIES(&mysqli_warning_properties, mysqli_warning_property_entries); zend_hash_add(&classes, ce->name.s, ce->name_length+1, &mysqli_warning_properties, sizeof(mysqli_warning_properties), NULL); REGISTER_MYSQLI_CLASS_ENTRY("mysqli_result", mysqli_result_class_entry, mysqli_result_methods); ce = mysqli_result_class_entry; - zend_hash_init(&mysqli_result_properties, 0, NULL, NULL, 1); + zend_u_hash_init(&mysqli_result_properties, 0, NULL, NULL, 1, 1); MYSQLI_ADD_PROPERTIES(&mysqli_result_properties, mysqli_result_property_entries); zend_hash_add(&classes, ce->name.s, ce->name_length+1, &mysqli_result_properties, sizeof(mysqli_result_properties), NULL); REGISTER_MYSQLI_CLASS_ENTRY("mysqli_stmt", mysqli_stmt_class_entry, mysqli_stmt_methods); ce = mysqli_stmt_class_entry; - zend_hash_init(&mysqli_stmt_properties, 0, NULL, NULL, 1); + zend_u_hash_init(&mysqli_stmt_properties, 0, NULL, NULL, 1, 1); MYSQLI_ADD_PROPERTIES(&mysqli_stmt_properties, mysqli_stmt_property_entries); zend_hash_add(&classes, ce->name.s, ce->name_length+1, &mysqli_stmt_properties, sizeof(mysqli_stmt_properties), NULL); - + + /* mysqli_options */ REGISTER_LONG_CONSTANT("MYSQLI_READ_DEFAULT_GROUP", MYSQL_READ_DEFAULT_GROUP, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_READ_DEFAULT_FILE", MYSQL_READ_DEFAULT_FILE, CONST_CS | CONST_PERSISTENT); @@ -698,7 +708,7 @@ PHP_MINFO_FUNCTION(mysqli) } /* }}} */ -/* {{{ mixed mysqli_stmt_construct() +/* {{{ mixed mysqli_stmt_construct() U constructor for statement object. Parameters: object -> mysqli_stmt_init @@ -710,8 +720,7 @@ ZEND_FUNCTION(mysqli_stmt_construct) zval *mysql_link; MY_STMT *stmt; MYSQLI_RESOURCE *mysqli_resource; - char *statement; - int stmt_len; + MYSQLI_STRING statement; switch (ZEND_NUM_ARGS()) { @@ -726,16 +735,19 @@ ZEND_FUNCTION(mysqli_stmt_construct) stmt->stmt = mysql_stmt_init(mysql->mysql); break; case 2: - if (zend_parse_parameters(2 TSRMLS_CC, "Os", &mysql_link, mysqli_link_class_entry, &statement, &stmt_len)==FAILURE) { + if (zend_parse_parameters(2 TSRMLS_CC, "OT", &mysql_link, mysqli_link_class_entry, MYSQLI_GET_STRING(statement))==FAILURE) { return; } MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); stmt = (MY_STMT *)ecalloc(1,sizeof(MY_STMT)); + + MYSQLI_CONVERT_PARAM_STRING(statement, MYSQLI_CONV_UTF8); if ((stmt->stmt = mysql_stmt_init(mysql->mysql))) { - mysql_stmt_prepare(stmt->stmt, statement, stmt_len); + mysql_stmt_prepare(stmt->stmt, (char *)statement.buf, statement.buflen); } + MYSQLI_FREE_STRING(statement); break; default: WRONG_PARAM_COUNT; @@ -755,7 +767,7 @@ ZEND_FUNCTION(mysqli_stmt_construct) } /* }}} */ -/* {{{ mixed mysqli_result_construct() +/* {{{ mixed mysqli_result_construct() U constructor for result object. Parameters: object [, mode] -> mysqli_store/use_result @@ -813,21 +825,22 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags unsigned long *field_len; zval *ctor_params = NULL; zend_class_entry *ce = NULL; + void *classname; + int classname_len; + zend_uchar classname_type; 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) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|Tz", &mysql_result, mysqli_result_class_entry, + &classname, &classname_len, &classname_type, &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); + ce = zend_u_fetch_class(classname_type, ZSTR(classname), classname_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC); } if (!ce) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not find class '%s'", class_name); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not find class '%R'", classname_type, ZSTR(classname)); return; } fetchtype = MYSQLI_ASSOC; @@ -868,7 +881,15 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags MAKE_STD_ZVAL(res); - ZVAL_STRINGL(res, row[i], field_len[i], 1); + if (UG(unicode)) { + UChar *ustr; + int ulen; + + zend_string_to_unicode(MYSQLI_CONV_UTF8, &ustr, &ulen, row[i], field_len[i]); + ZVAL_UNICODEL(res, ustr, ulen, 0); + } else { + ZVAL_STRINGL(res, row[i], field_len[i], 1); + } if (fetchtype & MYSQLI_NUM) { add_index_zval(return_value, i, res); @@ -877,7 +898,17 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags if (fetchtype & MYSQLI_NUM) { ZVAL_ADDREF(res); } - add_assoc_zval(return_value, fields[i].name, res); + if (UG(unicode)) { + UChar *ustr; + int ulen; + + zend_string_to_unicode(MYSQLI_CONV_UTF8, &ustr, &ulen, fields[i].name, strlen(fields[i].name)); + /* maybe a bug in add_u_assoc_zval_ex: string is truncated when specifying ulen only */ + add_u_assoc_zval_ex(return_value, IS_UNICODE, ZSTR(ustr), ulen + 1, res); + efree(ustr); + } else { + add_assoc_zval(return_value, fields[i].name, res); + } } } else { if (fetchtype & MYSQLI_NUM) { diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index 891bacd2fe..2031aca73b 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -29,7 +29,7 @@ #include "ext/standard/info.h" #include "php_mysqli.h" -/* {{{ proto mixed mysqli_affected_rows(object link) +/* {{{ proto mixed mysqli_affected_rows(object link) U Get number of affected rows in previous MySQL operation */ PHP_FUNCTION(mysqli_affected_rows) { @@ -51,7 +51,7 @@ PHP_FUNCTION(mysqli_affected_rows) } /* }}} */ -/* {{{ proto bool mysqli_autocommit(object link, bool mode) +/* {{{ proto bool mysqli_autocommit(object link, bool mode) U Turn auto commit on or of */ PHP_FUNCTION(mysqli_autocommit) { @@ -71,7 +71,7 @@ PHP_FUNCTION(mysqli_autocommit) } /* }}} */ -/* {{{ proto bool mysqli_stmt_bind_param(object stmt, string types, mixed variable [,mixed,....]) +/* {{{ proto bool mysqli_stmt_bind_param(object stmt, string types, mixed variable [,mixed,....]) U Bind variables to a prepared statement as parameters */ PHP_FUNCTION(mysqli_stmt_bind_param) { @@ -84,8 +84,7 @@ PHP_FUNCTION(mysqli_stmt_bind_param) MY_STMT *stmt; zval *mysql_stmt; MYSQL_BIND *bind; - char *types; - int typelen; + MYSQLI_STRING types; unsigned long rc; /* calculate and check number of parameters */ @@ -94,11 +93,12 @@ PHP_FUNCTION(mysqli_stmt_bind_param) WRONG_PARAM_COUNT; } - if (zend_parse_method_parameters((getThis()) ? 1:2 TSRMLS_CC, getThis(), "Os", &mysql_stmt, mysqli_stmt_class_entry, &types, &typelen) == FAILURE) { + if (zend_parse_method_parameters((getThis()) ? 1:2 TSRMLS_CC, getThis(), "Os", &mysql_stmt, mysqli_stmt_class_entry, MYSQLI_GET_STRING(types)) == FAILURE) { return; } MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt", MYSQLI_STATUS_VALID); + MYSQLI_CONVERT_PARAM_STRING(types, MYSQLI_CONV_ASCII); num_vars = argc - 1; if (getThis()) { @@ -108,15 +108,17 @@ PHP_FUNCTION(mysqli_stmt_bind_param) --num_vars; } - if (typelen != argc - start) { + if (types.buflen != argc - start) { /* number of bind variables doesn't match number of elements in type definition string */ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of elements in type definition string doesn't match number of bind variables"); - RETURN_FALSE; + RETVAL_FALSE; + goto end_2; } - if (typelen != stmt->stmt->param_count) { + if (types.buflen != stmt->stmt->param_count) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of variables doesn't match number of parameters in prepared statement"); - RETURN_FALSE; + RETVAL_FALSE; + goto end_2; } /* prevent leak if variables are already bound */ @@ -128,7 +130,8 @@ PHP_FUNCTION(mysqli_stmt_bind_param) if (zend_get_parameters_array_ex(argc, args) == FAILURE) { efree(args); - WRONG_PARAM_COUNT; + zend_wrong_param_count(TSRMLS_C); + goto end_2; } stmt->param.is_null = ecalloc(num_vars, sizeof(char)); @@ -138,7 +141,7 @@ PHP_FUNCTION(mysqli_stmt_bind_param) for (i=start; i < argc; i++) { /* set specified type */ - switch (types[ofs]) { + switch (((char *)types.buf)[ofs]) { case 'd': /* Double */ bind[ofs].buffer_type = MYSQL_TYPE_DOUBLE; bind[ofs].buffer = (gptr)&Z_DVAL_PP(args[i]); @@ -163,9 +166,9 @@ PHP_FUNCTION(mysqli_stmt_bind_param) break; default: - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Undefined fieldtype %c (parameter %d)", types[ofs], i+1); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Undefined fieldtype %c (parameter %d)", ((char *)types.buf)[ofs], i+1); RETVAL_FALSE; - goto end; + goto end_1; } ofs++; } @@ -174,7 +177,7 @@ PHP_FUNCTION(mysqli_stmt_bind_param) if (rc) { RETVAL_FALSE; - goto end; + goto end_1; } stmt->param.var_cnt = num_vars; @@ -188,13 +191,15 @@ PHP_FUNCTION(mysqli_stmt_bind_param) } } RETVAL_TRUE; -end: +end_1: efree(args); efree(bind); +end_2: + MYSQLI_FREE_STRING(types); } /* }}} */ -/* {{{ proto bool mysqli_stmt_bind_result(object stmt, mixed var, [,mixed, ...]) +/* {{{ proto bool mysqli_stmt_bind_result(object stmt, mixed var, [,mixed, ...]) U Bind variables to a prepared statement for result storage */ /* TODO: @@ -398,24 +403,32 @@ PHP_FUNCTION(mysqli_stmt_bind_result) } /* }}} */ -/* {{{ proto bool mysqli_change_user(object link, string user, string password, string database) +/* {{{ proto bool mysqli_change_user(object link, string user, string password, string database) U Change logged-in user of the active connection */ PHP_FUNCTION(mysqli_change_user) { - MY_MYSQL *mysql; - zval *mysql_link = NULL; - char *user, *password, *dbname; - int user_len, password_len, dbname_len; + MY_MYSQL *mysql; + zval *mysql_link = NULL; + MYSQLI_STRING user, password, dbname; ulong rc; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Osss", &mysql_link, mysqli_link_class_entry, &user, &user_len, &password, &password_len, &dbname, &dbname_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Osss", &mysql_link, mysqli_link_class_entry, + MYSQLI_GET_STRING(user), MYSQLI_GET_STRING(password), MYSQLI_GET_STRING(dbname)) == FAILURE) { return; } MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); - rc = mysql_change_user(mysql->mysql, user, password, dbname); + MYSQLI_CONVERT_PARAM_STRING(user, MYSQLI_CONV_UTF8); + MYSQLI_CONVERT_PARAM_STRING(password, MYSQLI_CONV_UTF8); + MYSQLI_CONVERT_PARAM_STRING(dbname, MYSQLI_CONV_UTF8); + + rc = mysql_change_user(mysql->mysql, user.buf, password.buf, dbname.buf); MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); + MYSQLI_FREE_STRING(user); + MYSQLI_FREE_STRING(password); + MYSQLI_FREE_STRING(dbname); + if (rc) { RETURN_FALSE; } @@ -424,12 +437,13 @@ PHP_FUNCTION(mysqli_change_user) } /* }}} */ -/* {{{ proto string mysqli_character_set_name(object link) +/* {{{ proto string mysqli_character_set_name(object link) U Returns the name of the character set used for this connection */ PHP_FUNCTION(mysqli_character_set_name) { MY_MYSQL *mysql; zval *mysql_link; + char *csname; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { return; @@ -437,11 +451,13 @@ PHP_FUNCTION(mysqli_character_set_name) MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); - RETURN_STRING((char *) mysql_character_set_name(mysql->mysql), 1); + csname = (char *)mysql_character_set_name(mysql->mysql); + + MYSQLI_RETURN_CONV_STRINGL(MYSQLI_CONV_UTF8, csname, strlen(csname), 1); } /* }}} */ -/* {{{ proto bool mysqli_close(object link) +/* {{{ proto bool mysqli_close(object link) U Close connection */ PHP_FUNCTION(mysqli_close) { @@ -462,7 +478,7 @@ PHP_FUNCTION(mysqli_close) } /* }}} */ -/* {{{ proto bool mysqli_commit(object link) +/* {{{ proto bool mysqli_commit(object link) U Commit outstanding actions and close transaction */ PHP_FUNCTION(mysqli_commit) { @@ -480,7 +496,7 @@ PHP_FUNCTION(mysqli_commit) } /* }}} */ -/* {{{ proto bool mysqli_data_seek(object result, int offset) +/* {{{ proto bool mysqli_data_seek(object result, int offset) U Move internal result pointer */ PHP_FUNCTION(mysqli_data_seek) { @@ -508,23 +524,25 @@ PHP_FUNCTION(mysqli_data_seek) } /* }}} */ -/* {{{ proto void mysqli_debug(string debug) +/* {{{ proto void mysqli_debug(string debug) U */ PHP_FUNCTION(mysqli_debug) { - char *debug; - int debug_len; + MYSQLI_STRING debug; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &debug, &debug_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", MYSQLI_GET_STRING(debug)) == FAILURE) { return; } - mysql_debug(debug); + MYSQLI_CONVERT_PARAM_STRING(debug, MYSQLI_CONV_ASCII); + + mysql_debug((char *)debug.buf); + MYSQLI_FREE_STRING(debug); RETURN_TRUE; } /* }}} */ -/* {{{ proto bool mysqli_dump_debug_info(object link) +/* {{{ proto bool mysqli_dump_debug_info(object link) U */ PHP_FUNCTION(mysqli_dump_debug_info) { @@ -546,7 +564,7 @@ PHP_FUNCTION(mysqli_dump_debug_info) } /* }}} */ -/* {{{ proto int mysqli_errno(object link) +/* {{{ proto int mysqli_errno(object link) U Returns the numerical value of the error message from previous MySQL operation */ PHP_FUNCTION(mysqli_errno) { @@ -561,22 +579,25 @@ PHP_FUNCTION(mysqli_errno) } /* }}} */ -/* {{{ proto string mysqli_error(object link) +/* {{{ proto string mysqli_error(object link) U Returns the text of the error message from previous MySQL operation */ PHP_FUNCTION(mysqli_error) { MY_MYSQL *mysql; zval *mysql_link; + char *strerr; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { return; } MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); - RETURN_STRING((char *)mysql_error(mysql->mysql),1); + + strerr = (char *)mysql_error(mysql->mysql); + MYSQLI_RETURN_CONV_STRINGL(MYSQLI_CONV_UTF8, strerr, strlen(strerr), 1); } /* }}} */ -/* {{{ proto bool mysqli_stmt_execute(object stmt) +/* {{{ proto bool mysqli_stmt_execute(object stmt) U Execute a prepared statement */ PHP_FUNCTION(mysqli_stmt_execute) { @@ -594,9 +615,16 @@ PHP_FUNCTION(mysqli_stmt_execute) if ( !(stmt->param.is_null[i] = (stmt->param.vars[i]->type == IS_NULL)) ) { switch (stmt->stmt->params[i].buffer_type) { case MYSQL_TYPE_VAR_STRING: - convert_to_string_ex(&stmt->param.vars[i]); - stmt->stmt->params[i].buffer = Z_STRVAL_PP(&stmt->param.vars[i]); - stmt->stmt->params[i].buffer_length = Z_STRLEN_PP(&stmt->param.vars[i]); + if (UG(unicode) && Z_TYPE_P(stmt->param.vars[i]) == IS_UNICODE) { + zend_unicode_to_string(MYSQLI_CONV_UTF8, &stmt->stmt->params[i].buffer, (int *)&stmt->stmt->params[i].buffer_length, + Z_USTRVAL_PP(&stmt->param.vars[i]), Z_USTRLEN_PP(&stmt->param.vars[i])); + } else { + if (Z_TYPE_P(stmt->param.vars[i]) != IS_STRING) { + convert_to_string_ex(&stmt->param.vars[i]); + } + stmt->stmt->params[i].buffer = Z_STRVAL_PP(&stmt->param.vars[i]); + stmt->stmt->params[i].buffer_length = Z_STRLEN_PP(&stmt->param.vars[i]); + } break; case MYSQL_TYPE_DOUBLE: convert_to_double_ex(&stmt->param.vars[i]); @@ -614,18 +642,27 @@ PHP_FUNCTION(mysqli_stmt_execute) } if (mysql_stmt_execute(stmt->stmt)) { MYSQLI_REPORT_STMT_ERROR(stmt->stmt); - RETURN_FALSE; + RETVAL_FALSE; + } else { + RETVAL_TRUE; } if (MyG(report_mode) & MYSQLI_REPORT_INDEX) { php_mysqli_report_index(stmt->query, stmt->stmt->mysql->server_status TSRMLS_CC); } - - RETURN_TRUE; + + /* free converted utf8 strings */ + if (UG(unicode)) { + for (i = 0; i < stmt->param.var_cnt; i++) { + if (stmt->stmt->params[i].buffer_type == MYSQL_TYPE_VAR_STRING) { + efree(stmt->stmt->params[i].buffer); + } + } + } } /* }}} */ -/* {{{ proto mixed mysqli_stmt_fetch(object stmt) +/* {{{ proto mixed mysqli_stmt_fetch(object stmt) U Fetch results from a prepared statement into the bound variables */ PHP_FUNCTION(mysqli_stmt_fetch) { @@ -661,6 +698,9 @@ PHP_FUNCTION(mysqli_stmt_fetch) if (Z_TYPE_P(stmt->result.vars[i]) == IS_STRING) { efree(stmt->result.vars[i]->value.str.val); } + if (Z_TYPE_P(stmt->result.vars[i]) == IS_UNICODE) { + USTR_FREE(stmt->result.vars[i]->value.ustr.val); + } if (!stmt->result.is_null[i]) { switch (stmt->result.buf[i].type) { case IS_LONG: @@ -681,7 +721,15 @@ PHP_FUNCTION(mysqli_stmt_fetch) } while (--j > 0); tmp[10]= '\0'; /* unsigned int > INT_MAX is 10 digis - ALWAYS */ - ZVAL_STRINGL(stmt->result.vars[i], tmp, 10, 0); + if (UG(unicode)) { + UChar *ubuf = NULL; + int ulen; + zend_string_to_unicode(MYSQLI_CONV_ASCII, &ubuf, &ulen, tmp, strlen(tmp)); + ZVAL_UNICODEL(stmt->result.vars[i], ubuf, ulen, 0); + efree(tmp); + } else { + ZVAL_STRINGL(stmt->result.vars[i], tmp, 10, 0); + } break; } } @@ -702,7 +750,8 @@ PHP_FUNCTION(mysqli_stmt_fetch) if (uns && llval > 9223372036854775807L) { #elif SIZEOF_LONG==4 if ((uns && llval > L64(2147483647)) || - (!uns && (( L64(2147483647) < (my_longlong) llval) || (L64(-2147483648) > (my_longlong) llval)))) + (!uns && (( L64(2147483647) < (my_longlong) llval) || + (L64(-2147483648) > (my_longlong) llval)))) { #endif char tmp[22]; @@ -711,11 +760,18 @@ PHP_FUNCTION(mysqli_stmt_fetch) * use MYSQLI_LL_SPEC. */ sprintf((char *)&tmp, (stmt->stmt->fields[i].flags & UNSIGNED_FLAG)? MYSQLI_LLU_SPEC : MYSQLI_LL_SPEC, llval); - ZVAL_STRING(stmt->result.vars[i], tmp, 1); + if (UG(unicode)) { + UChar *ubuf = NULL; + int ulen; + zend_string_to_unicode(MYSQLI_CONV_UTF8, &ubuf, &ulen, tmp, strlen(tmp)); + ZVAL_UNICODEL(stmt->result.vars[i], ubuf, ulen, 0); + } else { + ZVAL_STRING(stmt->result.vars[i], tmp, 1); + } } else { ZVAL_LONG(stmt->result.vars[i], llval); } - } + } #if MYSQL_VERSION_ID > 50002 else if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_BIT) { llval = *(my_ulonglong *)stmt->result.buf[i].val; @@ -723,8 +779,17 @@ PHP_FUNCTION(mysqli_stmt_fetch) } #endif else { - ZVAL_STRINGL(stmt->result.vars[i], stmt->result.buf[i].val, stmt->result.buf[i].buflen, 1); - } + if (UG(unicode)) { + UChar *ubuf = NULL; + int ulen; + zend_string_to_unicode(MYSQLI_CONV_UTF8, &ubuf, &ulen, stmt->result.buf[i].val, + stmt->result.buf[i].buflen); + ZVAL_UNICODEL(stmt->result.vars[i], ubuf, ulen, 0); + } else { + ZVAL_STRINGL(stmt->result.vars[i], stmt->result.buf[i].val, stmt->result.buf[i].buflen, 1); + } + + } break; default: break; @@ -758,7 +823,44 @@ PHP_FUNCTION(mysqli_stmt_fetch) } /* }}} */ -/* {{{ proto mixed mysqli_fetch_field (object result) + +void php_add_field_properties(zval *value, MYSQL_FIELD *field) +{ + if (UG(unicode)) { + UChar *ustr; + int ulen; + + zend_string_to_unicode(MYSQLI_CONV_UTF8, &ustr, &ulen, (field->name) ? field->name : "", + (field->name) ? strlen(field->name) : 0); + add_property_unicodel(value, "name", ustr, ulen, 0); + zend_string_to_unicode(MYSQLI_CONV_UTF8, &ustr, &ulen, (field->org_name) ? field->org_name : "", + (field->org_name) ? strlen(field->org_name) : 0); + add_property_unicodel(value, "orgname", ustr, ulen, 0); + zend_string_to_unicode(MYSQLI_CONV_UTF8, &ustr, &ulen, (field->table) ? field->table : "", + (field->table) ? strlen(field->table) : 0); + add_property_unicodel(value, "table", ustr, ulen, 0); + zend_string_to_unicode(MYSQLI_CONV_UTF8, &ustr, &ulen, (field->org_table) ? field->org_table : "", + (field->org_table) ? strlen(field->org_table) : 0); + add_property_unicodel(value, "orgtable", ustr, ulen, 0); + zend_string_to_unicode(MYSQLI_CONV_UTF8, &ustr, &ulen, (field->def) ? field->def : "", + (field->def) ? strlen(field->def) : 0); + add_property_unicodel(value, "def", ustr, ulen, 0); + } else { + add_property_string(value, "name",(field->name ? field->name : ""), 1); + add_property_string(value, "orgname",(field->org_name ? field->org_name : ""), 1); + add_property_string(value, "table",(field->table ? field->table : ""), 1); + add_property_string(value, "orgtable",(field->org_table ? field->org_table : ""), 1); + add_property_string(value, "def",(field->def ? field->def : ""), 1); + } + add_property_long(value, "max_length", field->max_length); + add_property_long(value, "length", field->length); + add_property_long(value, "charsetnr", field->charsetnr); + add_property_long(value, "flags", field->flags); + add_property_long(value, "type", field->type); + add_property_long(value, "decimals", field->decimals); +} + +/* {{{ proto mixed mysqli_fetch_field (object result) U Get column information from a result and return as an object */ PHP_FUNCTION(mysqli_fetch_field) { @@ -777,22 +879,11 @@ PHP_FUNCTION(mysqli_fetch_field) } object_init(return_value); - - add_property_string(return_value, "name",(field->name ? field->name : ""), 1); - add_property_string(return_value, "orgname",(field->org_name ? field->org_name : ""), 1); - add_property_string(return_value, "table",(field->table ? field->table : ""), 1); - add_property_string(return_value, "orgtable",(field->org_table ? field->org_table : ""), 1); - add_property_string(return_value, "def",(field->def ? field->def : ""), 1); - add_property_long(return_value, "max_length", field->max_length); - add_property_long(return_value, "length", field->length); - add_property_long(return_value, "charsetnr", field->charsetnr); - add_property_long(return_value, "flags", field->flags); - add_property_long(return_value, "type", field->type); - add_property_long(return_value, "decimals", field->decimals); + php_add_field_properties(return_value, field); } /* }}} */ -/* {{{ proto mixed mysqli_fetch_fields (object result) +/* {{{ proto mixed mysqli_fetch_fields (object result) U Return array of objects containing field meta-data */ PHP_FUNCTION(mysqli_fetch_fields) { @@ -814,28 +905,16 @@ PHP_FUNCTION(mysqli_fetch_fields) for (i = 0; i < mysql_num_fields(result); i++) { field = mysql_fetch_field_direct(result, i); - MAKE_STD_ZVAL(obj); object_init(obj); - add_property_string(obj, "name",(field->name ? field->name : ""), 1); - add_property_string(obj, "orgname",(field->org_name ? field->org_name : ""), 1); - add_property_string(obj, "table",(field->table ? field->table : ""), 1); - add_property_string(obj, "orgtable",(field->org_table ? field->org_table : ""), 1); - add_property_string(obj, "def",(field->def ? field->def : ""), 1); - add_property_long(obj, "max_length", field->max_length); - add_property_long(obj, "length", field->length); - add_property_long(obj, "charsetnr", field->charsetnr); - add_property_long(obj, "flags", field->flags); - add_property_long(obj, "type", field->type); - add_property_long(obj, "decimals", field->decimals); - + php_add_field_properties(obj, field); add_index_zval(return_value, i, obj); } } /* }}} */ -/* {{{ proto mixed mysqli_fetch_field_direct (object result, int offset) +/* {{{ proto mixed mysqli_fetch_field_direct (object result, int offset) U Fetch meta-data for a single field */ PHP_FUNCTION(mysqli_fetch_field_direct) { @@ -860,22 +939,11 @@ PHP_FUNCTION(mysqli_fetch_field_direct) } object_init(return_value); - - add_property_string(return_value, "name",(field->name ? field->name : ""), 1); - add_property_string(return_value, "orgname",(field->org_name ? field->org_name : ""), 1); - add_property_string(return_value, "table",(field->table ? field->table : ""), 1); - add_property_string(return_value, "orgtable",(field->org_table ? field->org_table : ""), 1); - add_property_string(return_value, "def",(field->def ? field->def : ""), 1); - add_property_long(return_value, "max_length", field->max_length); - add_property_long(return_value, "length", field->length); - add_property_long(return_value, "charsetnr", field->charsetnr); - add_property_long(return_value, "flags", field->flags); - add_property_long(return_value, "type", field->type); - add_property_long(return_value, "decimals", field->decimals); + php_add_field_properties(return_value, field); } /* }}} */ -/* {{{ proto mixed mysqli_fetch_lengths (object result) +/* {{{ proto mixed mysqli_fetch_lengths (object result) U Get the length of each output in a result */ PHP_FUNCTION(mysqli_fetch_lengths) { @@ -902,7 +970,7 @@ PHP_FUNCTION(mysqli_fetch_lengths) } /* }}} */ -/* {{{ proto array mysqli_fetch_row (object result) +/* {{{ proto array mysqli_fetch_row (object result) U Get a result row as an enumerated array */ PHP_FUNCTION(mysqli_fetch_row) { @@ -910,7 +978,7 @@ PHP_FUNCTION(mysqli_fetch_row) } /* }}} */ -/* {{{ proto int mysqli_field_count(object link) +/* {{{ proto int mysqli_field_count(object link) U Fetch the number of fields returned by the last query for the given link */ PHP_FUNCTION(mysqli_field_count) @@ -927,7 +995,7 @@ PHP_FUNCTION(mysqli_field_count) } /* }}} */ -/* {{{ proto int mysqli_field_seek(object result, int fieldnr) +/* {{{ proto int mysqli_field_seek(object result, int fieldnr) U Set result pointer to a specified field offset */ PHP_FUNCTION(mysqli_field_seek) @@ -951,7 +1019,7 @@ PHP_FUNCTION(mysqli_field_seek) } /* }}} */ -/* {{{ proto int mysqli_field_tell(object result) +/* {{{ proto int mysqli_field_tell(object result) U Get current field offset of result pointer */ PHP_FUNCTION(mysqli_field_tell) { @@ -967,7 +1035,7 @@ PHP_FUNCTION(mysqli_field_tell) } /* }}} */ -/* {{{ proto void mysqli_free_result(object result) +/* {{{ proto void mysqli_free_result(object result) U Free query result memory for the given result handle */ PHP_FUNCTION(mysqli_free_result) { @@ -984,7 +1052,7 @@ PHP_FUNCTION(mysqli_free_result) } /* }}} */ -/* {{{ proto string mysqli_get_client_info(void) +/* {{{ proto string mysqli_get_client_info(void) U Get MySQL client info */ PHP_FUNCTION(mysqli_get_client_info) { @@ -992,7 +1060,7 @@ PHP_FUNCTION(mysqli_get_client_info) } /* }}} */ -/* {{{ proto int mysqli_get_client_version(void) +/* {{{ proto int mysqli_get_client_version(void) U Get MySQL client info */ PHP_FUNCTION(mysqli_get_client_version) { @@ -1000,9 +1068,9 @@ PHP_FUNCTION(mysqli_get_client_version) } /* }}} */ -/* {{{ proto string mysqli_get_host_info (object link) +/* {{{ proto string mysqli_get_host_info (object link) U Get MySQL host info */ -PHP_FUNCTION(mysqli_get_host_info) +PHP_FUNCTION(mysqli_get_host_info) { MY_MYSQL *mysql; zval *mysql_link = NULL; @@ -1012,11 +1080,11 @@ PHP_FUNCTION(mysqli_get_host_info) } MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); - RETURN_STRING((mysql->mysql->host_info) ? mysql->mysql->host_info : "", 1); + MYSQLI_RETURN_CONV_STRING(MYSQLI_CONV_ASCII, mysql->mysql->host_info); } /* }}} */ -/* {{{ proto int mysqli_get_proto_info(object link) +/* {{{ proto int mysqli_get_proto_info(object link) U Get MySQL protocol information */ PHP_FUNCTION(mysqli_get_proto_info) { @@ -1032,7 +1100,7 @@ PHP_FUNCTION(mysqli_get_proto_info) } /* }}} */ -/* {{{ proto string mysqli_get_server_info(object link) +/* {{{ proto string mysqli_get_server_info(object link) U Get MySQL server info */ PHP_FUNCTION(mysqli_get_server_info) { @@ -1044,12 +1112,12 @@ PHP_FUNCTION(mysqli_get_server_info) } MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); - RETURN_STRING((char *)mysql_get_server_info(mysql->mysql), 1); + MYSQLI_RETURN_CONV_STRING(MYSQLI_CONV_ASCII, (char *)mysql_get_server_info(mysql->mysql)); } /* }}} */ -/* {{{ proto int mysqli_get_server_version(object link) +/* {{{ proto int mysqli_get_server_version(object link) U Return the MySQL version for the server referenced by the given link */ PHP_FUNCTION(mysqli_get_server_version) { @@ -1077,11 +1145,11 @@ PHP_FUNCTION(mysqli_info) } MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); - RETURN_STRING((mysql->mysql->info) ? mysql->mysql->info : "", 1); + MYSQLI_RETURN_CONV_STRING(MYSQLI_CONV_ASCII, mysql->mysql->info); } /* }}} */ -/* {{{ proto resource mysqli_init(void) +/* {{{ proto resource mysqli_init(void) U Initialize mysqli and return a resource for use with mysql_real_connect */ PHP_FUNCTION(mysqli_init) { @@ -1105,7 +1173,7 @@ PHP_FUNCTION(mysqli_init) } /* }}} */ -/* {{{ proto mixed mysqli_insert_id(object link) +/* {{{ proto mixed mysqli_insert_id(object link) U Get the ID generated from the previous INSERT operation */ PHP_FUNCTION(mysqli_insert_id) { @@ -1122,7 +1190,7 @@ PHP_FUNCTION(mysqli_insert_id) } /* }}} */ -/* {{{ proto bool mysqli_kill(object link, int processid) +/* {{{ proto bool mysqli_kill(object link, int processid) U Kill a mysql process on the server */ PHP_FUNCTION(mysqli_kill) { @@ -1143,7 +1211,7 @@ PHP_FUNCTION(mysqli_kill) } /* }}} */ -/* {{{ proto void mysqli_set_local_infile_default(object link) +/* {{{ proto void mysqli_set_local_infile_default(object link) U unsets user defined handler for load local infile command */ PHP_FUNCTION(mysqli_set_local_infile_default) { @@ -1164,7 +1232,7 @@ PHP_FUNCTION(mysqli_set_local_infile_default) } /* }}} */ -/* {{{ proto bool mysqli_set_local_infile_handler(object link, callback read_func) +/* {{{ proto bool mysqli_set_local_infile_handler(object link, callback read_func) U Set callback functions for LOAD DATA LOCAL INFILE */ PHP_FUNCTION(mysqli_set_local_infile_handler) { @@ -1180,6 +1248,10 @@ PHP_FUNCTION(mysqli_set_local_infile_handler) MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); + if (UG(unicode)) { + convert_to_string(callback_func); + } + /* check callback function */ if (!zend_is_callable(callback_func, 0, &callback_name)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not a valid callback function %R", Z_TYPE(callback_name), Z_UNIVAL(callback_name)); @@ -1196,7 +1268,7 @@ PHP_FUNCTION(mysqli_set_local_infile_handler) } /* }}} */ -/* {{{ proto bool mysqli_more_results(object link) +/* {{{ proto bool mysqli_more_results(object link) U check if there any more query results from a multi query */ PHP_FUNCTION(mysqli_more_results) { @@ -1212,7 +1284,7 @@ PHP_FUNCTION(mysqli_more_results) } /* }}} */ -/* {{{ proto bool mysqli_next_result(object link) +/* {{{ proto bool mysqli_next_result(object link) U read next result from multi_query */ PHP_FUNCTION(mysqli_next_result) { MY_MYSQL *mysql; @@ -1227,7 +1299,7 @@ PHP_FUNCTION(mysqli_next_result) { } /* }}} */ -/* {{{ proto int mysqli_num_fields(object result) +/* {{{ proto int mysqli_num_fields(object result) U Get number of fields in result */ PHP_FUNCTION(mysqli_num_fields) { @@ -1243,7 +1315,7 @@ PHP_FUNCTION(mysqli_num_fields) } /* }}} */ -/* {{{ proto mixed mysqli_num_rows(object result) +/* {{{ proto mixed mysqli_num_rows(object result) U Get number of rows in result */ PHP_FUNCTION(mysqli_num_rows) { @@ -1264,7 +1336,7 @@ PHP_FUNCTION(mysqli_num_rows) } /* }}} */ -/* {{{ proto bool mysqli_options(object link, int flags, mixed values) +/* {{{ proto bool mysqli_options(object link, int flags, mixed values) U Set options */ PHP_FUNCTION(mysqli_options) { @@ -1284,6 +1356,18 @@ PHP_FUNCTION(mysqli_options) case IS_STRING: ret = mysql_options(mysql->mysql, mysql_option, Z_STRVAL_PP(&mysql_value)); break; + case IS_UNICODE: + { + MYSQLI_STRING optstr; + + optstr.buf = Z_USTRVAL_P(mysql_value); + optstr.buflen = Z_USTRLEN_P(mysql_value); + optstr.buftype = IS_UNICODE; + MYSQLI_CONVERT_PARAM_STRING(optstr, MYSQLI_CONV_UTF8); + ret = mysql_options(mysql->mysql, mysql_option, (char *)optstr.buf); + MYSQLI_FREE_STRING(optstr); + break; + } default: convert_to_long_ex(&mysql_value); l_value = Z_LVAL_PP(&mysql_value); @@ -1295,8 +1379,7 @@ PHP_FUNCTION(mysqli_options) } /* }}} */ - -/* {{{ proto bool mysqli_ping(object link) +/* {{{ proto bool mysqli_ping(object link) U Ping a server connection or reconnect if there is no connection */ PHP_FUNCTION(mysqli_ping) { @@ -1315,18 +1398,17 @@ PHP_FUNCTION(mysqli_ping) } /* }}} */ -/* {{{ proto mixed mysqli_prepare(object link, string query) +/* {{{ proto mixed mysqli_prepare(object link, string query) U Prepare a SQL statement for execution */ PHP_FUNCTION(mysqli_prepare) { MY_MYSQL *mysql; MY_STMT *stmt; - char *query = NULL; - unsigned int query_len; + MYSQLI_STRING query; zval *mysql_link; MYSQLI_RESOURCE *mysqli_resource; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os",&mysql_link, mysqli_link_class_entry, &query, &query_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OT",&mysql_link, mysqli_link_class_entry, MYSQLI_GET_STRING(query)) == FAILURE) { return; } MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); @@ -1338,7 +1420,8 @@ PHP_FUNCTION(mysqli_prepare) stmt = (MY_STMT *)ecalloc(1,sizeof(MY_STMT)); if ((stmt->stmt = mysql_stmt_init(mysql->mysql))) { - if (mysql_stmt_prepare(stmt->stmt, query, query_len)) { + MYSQLI_CONVERT_PARAM_STRING(query, MYSQLI_CONV_UTF8); + if (mysql_stmt_prepare(stmt->stmt, query.buf, query.buflen)) { char last_error[MYSQL_ERRMSG_SIZE]; char sqlstate[SQLSTATE_LENGTH+1]; unsigned int last_errno; @@ -1357,7 +1440,18 @@ PHP_FUNCTION(mysqli_prepare) memcpy(mysql->mysql->net.sqlstate, sqlstate, SQLSTATE_LENGTH+1); } } - /* don't joing to the previous if because it won't work if mysql_stmt_prepare_fails */ + + /* don't initialize stmt->query with NULL, we ecalloc()-ed the memory */ + /* Get performance boost if reporting is switched off */ + if (stmt->stmt && query.buflen && (MyG(report_mode) & MYSQLI_REPORT_INDEX)) { + stmt->query = (char *)emalloc(query.buflen + 1); + memcpy(stmt->query, query.buf, query.buflen); + stmt->query[query.buflen] = '\0'; + } + + MYSQLI_FREE_STRING(query); + + /* don't join to the previous if because it won't work if mysql_stmt_prepare_fails */ if (!stmt->stmt) { MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); efree(stmt); @@ -1367,13 +1461,6 @@ PHP_FUNCTION(mysqli_prepare) mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); mysqli_resource->ptr = (void *)stmt; - /* don't initialize stmt->query with NULL, we ecalloc()-ed the memory */ - /* Get performance boost if reporting is switched off */ - if (query_len && (MyG(report_mode) & MYSQLI_REPORT_INDEX)) { - stmt->query = (char *)emalloc(query_len + 1); - memcpy(stmt->query, query, query_len); - stmt->query[query_len] = '\0'; - } /* change status */ mysqli_resource->status = MYSQLI_STATUS_VALID; @@ -1381,39 +1468,35 @@ PHP_FUNCTION(mysqli_prepare) } /* }}} */ -/* {{{ proto bool mysqli_real_connect(object link [,string hostname [,string username [,string passwd [,string dbname [,int port [,string socket [,int flags]]]]]]]) +/* {{{ proto bool mysqli_real_connect(object link [,string hostname [,string username [,string passwd [,string dbname [,int port [,string socket [,int flags]]]]]]]) U Open a connection to a mysql server */ PHP_FUNCTION(mysqli_real_connect) { MY_MYSQL *mysql; - char *hostname = NULL, *username=NULL, *passwd=NULL, *dbname=NULL, *socket=NULL; - unsigned int hostname_len = 0, username_len = 0, passwd_len = 0, dbname_len = 0, socket_len = 0; + MYSQLI_STRING hostname, username, passwd, dbname, socket; unsigned long port=0, flags=0; zval *mysql_link; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|sssslsl", &mysql_link, mysqli_link_class_entry, - &hostname, &hostname_len, &username, &username_len, &passwd, &passwd_len, &dbname, &dbname_len, &port, &socket, &socket_len, + /* optional MYSQLI_STRING parameters have to be initialized */ + memset(&hostname, 0, sizeof(MYSQLI_STRING)); + memset(&username, 0, sizeof(MYSQLI_STRING)); + memset(&dbname, 0, sizeof(MYSQLI_STRING)); + memset(&passwd, 0, sizeof(MYSQLI_STRING)); + memset(&socket, 0, sizeof(MYSQLI_STRING)); + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|TTTTlTl", &mysql_link, mysqli_link_class_entry, + MYSQLI_GET_STRING(hostname), MYSQLI_GET_STRING(username), MYSQLI_GET_STRING(passwd), MYSQLI_GET_STRING(dbname), &port, MYSQLI_GET_STRING(socket), &flags) == FAILURE) { return; } - if (!socket_len) { - socket = NULL; - } + MYSQLI_CONVERT_PARAM_STRING(hostname, MYSQLI_CONV_ASCII); + MYSQLI_CONVERT_PARAM_STRING(username, MYSQLI_CONV_UTF8); + MYSQLI_CONVERT_PARAM_STRING(passwd, MYSQLI_CONV_UTF8); + MYSQLI_CONVERT_PARAM_STRING(dbname, MYSQLI_CONV_UTF8); + MYSQLI_CONVERT_PARAM_STRING(socket, MYSQLI_CONV_ASCII); - /* TODO: safe mode handling */ - if (PG(sql_safe_mode)) { - } else { - if (!passwd) { - passwd = MyG(default_pw); - if (!username){ - username = MyG(default_user); - if (!hostname) { - hostname = MyG(default_host); - } - } - } - } + /* TODO: default values */ MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_INITIALIZED); @@ -1423,18 +1506,15 @@ PHP_FUNCTION(mysqli_real_connect) flags ^= CLIENT_LOCAL_FILES; } - if (!socket) { - socket = MyG(default_socket); - } - - if (mysql_real_connect(mysql->mysql,hostname,username,passwd,dbname,port,socket,flags) == NULL) { + if (mysql_real_connect(mysql->mysql, hostname.buf, username.buf, passwd.buf, dbname.buf ,port,(socket.buflen) ? socket.buf : NULL,flags) == NULL) { php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql) TSRMLS_CC); php_mysqli_throw_sql_exception( mysql->mysql->net.sqlstate, mysql->mysql->net.last_errno TSRMLS_CC, "%s", mysql->mysql->net.last_error); /* change status */ MYSQLI_SET_STATUS(&mysql_link, MYSQLI_STATUS_INITIALIZED); - RETURN_FALSE; + RETVAL_FALSE; + goto end; } php_mysqli_set_error(mysql_errno(mysql->mysql), (char *)mysql_error(mysql->mysql) TSRMLS_CC); @@ -1447,63 +1527,72 @@ PHP_FUNCTION(mysqli_real_connect) /* change status */ MYSQLI_SET_STATUS(&mysql_link, MYSQLI_STATUS_VALID); - RETURN_TRUE; + RETVAL_TRUE; +end: + MYSQLI_FREE_STRING(hostname); + MYSQLI_FREE_STRING(username); + MYSQLI_FREE_STRING(passwd); + MYSQLI_FREE_STRING(dbname); + MYSQLI_FREE_STRING(socket); } /* }}} */ -/* {{{ proto bool mysqli_real_query(object link, string query) +/* {{{ proto bool mysqli_real_query(object link, string query) U Binary-safe version of mysql_query() */ PHP_FUNCTION(mysqli_real_query) { MY_MYSQL *mysql; zval *mysql_link; - char *query = NULL; - unsigned int query_len; + MYSQLI_STRING query; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &query, &query_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, MYSQLI_GET_STRING(query)) == FAILURE) { return; } MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); + MYSQLI_CONVERT_PARAM_STRING(query, MYSQLI_CONV_UTF8); MYSQLI_DISABLE_MQ; /* disable multi statements/queries */ - if (mysql_real_query(mysql->mysql, query, query_len)) { + if (mysql_real_query(mysql->mysql, query.buf, query.buflen)) { MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); - RETURN_FALSE; - } - - if (!mysql_field_count(mysql->mysql)) { - if (MyG(report_mode) & MYSQLI_REPORT_INDEX) { - php_mysqli_report_index(query, mysql->mysql->server_status TSRMLS_CC); + RETVAL_FALSE; + } else { + if (!mysql_field_count(mysql->mysql)) { + if (MyG(report_mode) & MYSQLI_REPORT_INDEX) { + php_mysqli_report_index(query.buf, mysql->mysql->server_status TSRMLS_CC); + } } + RETVAL_TRUE; } - - RETURN_TRUE; + MYSQLI_FREE_STRING(query); } /* }}} */ -/* {{{ proto string mysqli_real_escape_string(object link, string escapestr) +/* {{{ proto string mysqli_real_escape_string(object link, string escapestr) U Escapes special characters in a string for use in a SQL statement, taking into account the current charset of the connection */ PHP_FUNCTION(mysqli_real_escape_string) { - MY_MYSQL *mysql; - zval *mysql_link = NULL; - char *escapestr, *newstr; - int escapestr_len, newstr_len; + MY_MYSQL *mysql; + zval *mysql_link = NULL; + MYSQLI_STRING escapestr; + char *newstr; + int newstr_len; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &escapestr, &escapestr_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, MYSQLI_GET_STRING(escapestr)) == FAILURE) { return; } MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); + MYSQLI_CONVERT_PARAM_STRING(escapestr, MYSQLI_CONV_UTF8); - newstr = safe_emalloc(2, escapestr_len, 1); - newstr_len = mysql_real_escape_string(mysql->mysql, newstr, escapestr, escapestr_len); + newstr = safe_emalloc(2, escapestr.buflen, 1); + newstr_len = mysql_real_escape_string(mysql->mysql, newstr, escapestr.buf, escapestr.buflen); newstr = erealloc(newstr, newstr_len + 1); - - RETURN_STRINGL(newstr, newstr_len, 0); + + MYSQLI_FREE_STRING(escapestr); + MYSQLI_RETURN_CONV_STRINGL(MYSQLI_CONV_UTF8, newstr, newstr_len, 0); } /* }}} */ -/* {{{ proto bool mysqli_rollback(object link) +/* {{{ proto bool mysqli_rollback(object link) U Undo actions from current transaction */ PHP_FUNCTION(mysqli_rollback) { @@ -1522,35 +1611,38 @@ PHP_FUNCTION(mysqli_rollback) } /* }}} */ -/* {{{ proto bool mysqli_send_long_data(object stmt, int param_nr, string data) +/* {{{ proto bool mysqli_send_long_data(object stmt, int param_nr, string data) U */ PHP_FUNCTION(mysqli_stmt_send_long_data) { MY_STMT *stmt; zval *mysql_stmt; - char *data; long param_nr; - int data_len; + MYSQLI_STRING data; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ols", &mysql_stmt, mysqli_stmt_class_entry, ¶m_nr, &data, &data_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ols", &mysql_stmt, mysqli_stmt_class_entry, ¶m_nr, MYSQLI_GET_STRING(data)) == FAILURE) { return; } MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt", MYSQLI_STATUS_VALID); + MYSQLI_CONVERT_PARAM_STRING(data, MYSQLI_CONV_UTF8); if (param_nr < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid parameter number"); - RETURN_FALSE; - } - if (mysql_stmt_send_long_data(stmt->stmt, param_nr, data, data_len)) { - RETURN_FALSE; + RETVAL_FALSE; + goto end; + } + if (mysql_stmt_send_long_data(stmt->stmt, param_nr, data.buf, data.buflen)) { + RETVAL_FALSE; + } else { + RETVAL_TRUE; } - RETURN_TRUE; +end: + MYSQLI_FREE_STRING(data); } /* }}} */ - -/* {{{ proto mixed mysqli_stmt_affected_rows(object stmt) +/* {{{ proto mixed mysqli_stmt_affected_rows(object stmt) U Return the number of rows affected in the last query for the given link */ PHP_FUNCTION(mysqli_stmt_affected_rows) { @@ -1571,7 +1663,7 @@ PHP_FUNCTION(mysqli_stmt_affected_rows) } /* }}} */ -/* {{{ proto bool mysqli_stmt_close(object stmt) +/* {{{ proto bool mysqli_stmt_close(object stmt) U Close statement */ PHP_FUNCTION(mysqli_stmt_close) { @@ -1591,7 +1683,7 @@ PHP_FUNCTION(mysqli_stmt_close) } /* }}} */ -/* {{{ proto void mysqli_stmt_data_seek(object stmt, int offset) +/* {{{ proto void mysqli_stmt_data_seek(object stmt, int offset) U Move internal result pointer */ PHP_FUNCTION(mysqli_stmt_data_seek) { @@ -1613,7 +1705,7 @@ PHP_FUNCTION(mysqli_stmt_data_seek) } /* }}} */ -/* {{{ proto int mysqli_stmt_field_count(object stmt) { +/* {{{ proto int mysqli_stmt_field_count(object stmt) { U Return the number of result columns for the given statement */ PHP_FUNCTION(mysqli_stmt_field_count) { @@ -1629,7 +1721,7 @@ PHP_FUNCTION(mysqli_stmt_field_count) } /* }}} */ -/* {{{ proto void mysqli_stmt_free_result(object stmt) +/* {{{ proto void mysqli_stmt_free_result(object stmt) U Free stored result memory for the given statement handle */ PHP_FUNCTION(mysqli_stmt_free_result) { @@ -1646,7 +1738,7 @@ PHP_FUNCTION(mysqli_stmt_free_result) } /* }}} */ -/* {{{ proto mixed mysqli_stmt_insert_id(object stmt) +/* {{{ proto mixed mysqli_stmt_insert_id(object stmt) U Get the ID generated from the previous INSERT operation */ PHP_FUNCTION(mysqli_stmt_insert_id) { @@ -1663,7 +1755,7 @@ PHP_FUNCTION(mysqli_stmt_insert_id) } /* }}} */ -/* {{{ proto int mysqli_stmt_param_count(object stmt) { +/* {{{ proto int mysqli_stmt_param_count(object stmt) U Return the number of parameter for the given statement */ PHP_FUNCTION(mysqli_stmt_param_count) { @@ -1679,7 +1771,7 @@ PHP_FUNCTION(mysqli_stmt_param_count) } /* }}} */ -/* {{{ proto bool mysqli_stmt_reset(object stmt) +/* {{{ proto bool mysqli_stmt_reset(object stmt) U reset a prepared statement */ PHP_FUNCTION(mysqli_stmt_reset) { @@ -1699,7 +1791,7 @@ PHP_FUNCTION(mysqli_stmt_reset) } /* }}} */ -/* {{{ proto mixed mysqli_stmt_num_rows(object stmt) +/* {{{ proto mixed mysqli_stmt_num_rows(object stmt) U Return the number of rows in statements result set */ PHP_FUNCTION(mysqli_stmt_num_rows) { @@ -1718,31 +1810,32 @@ PHP_FUNCTION(mysqli_stmt_num_rows) } /* }}} */ -/* {{{ proto string mysqli_select_db(object link, string dbname) +/* {{{ proto string mysqli_select_db(object link, string dbname) U Select a MySQL database */ PHP_FUNCTION(mysqli_select_db) { - MY_MYSQL *mysql; - zval *mysql_link; - char *dbname; - int dbname_len; + MY_MYSQL *mysql; + zval *mysql_link; + MYSQLI_STRING dbname; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &dbname, &dbname_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, MYSQLI_GET_STRING(dbname)) == FAILURE) { return; } MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); + MYSQLI_CONVERT_PARAM_STRING(dbname, MYSQLI_CONV_UTF8); - if (!mysql_select_db(mysql->mysql, dbname)) { - RETURN_TRUE; + if (!mysql_select_db(mysql->mysql, (char *)dbname.buf)) { + RETVAL_TRUE; + } else { + MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); + RETURN_FALSE; } - - MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); - RETURN_FALSE; + MYSQLI_FREE_STRING(dbname); } /* }}} */ -/* {{{ proto string mysqli_sqlstate(object link) +/* {{{ proto string mysqli_sqlstate(object link) U Returns the SQLSTATE error from previous MySQL operation */ PHP_FUNCTION(mysqli_sqlstate) { @@ -1753,37 +1846,44 @@ PHP_FUNCTION(mysqli_sqlstate) return; } MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); - RETURN_STRING((char *)mysql_sqlstate(mysql->mysql),1); + MYSQLI_RETURN_CONV_STRING(MYSQLI_CONV_ASCII, (char *)mysql_sqlstate(mysql->mysql)); } /* }}} */ -/* {{{ proto bool mysqli_ssl_set(object link ,string key ,string cert ,string ca ,string capath ,string cipher]) +/* {{{ proto bool mysqli_ssl_set(object link ,string key ,string cert ,string ca ,string capath ,string cipher]) U */ PHP_FUNCTION(mysqli_ssl_set) { - MY_MYSQL *mysql; - zval *mysql_link; - char *ssl_parm[5]; - int ssl_parm_len[5], i; + MY_MYSQL *mysql; + zval *mysql_link; + MYSQLI_STRING ssl_parm[5]; + int i; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Osssss", &mysql_link, mysqli_link_class_entry, &ssl_parm[0], &ssl_parm_len[0], &ssl_parm[1], &ssl_parm_len[1], &ssl_parm[2], &ssl_parm_len[2], &ssl_parm[3], &ssl_parm_len[3], &ssl_parm[4], &ssl_parm_len[4]) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Osssss", &mysql_link, mysqli_link_class_entry, + MYSQLI_GET_STRING(ssl_parm[0]), MYSQLI_GET_STRING(ssl_parm[1]), MYSQLI_GET_STRING(ssl_parm[2]), + MYSQLI_GET_STRING(ssl_parm[3]), MYSQLI_GET_STRING(ssl_parm[4])) == FAILURE) { return; } MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); for (i=0; i < 5; i++) { - if (!ssl_parm_len[i]) { - ssl_parm[i] = NULL; + MYSQLI_CONVERT_PARAM_STRING(ssl_parm[0], MYSQLI_CONV_ASCII); + if (!ssl_parm[i].buflen) { + ssl_parm[i].buf = NULL; } } - mysql_ssl_set(mysql->mysql, ssl_parm[0], ssl_parm[1], ssl_parm[2], ssl_parm[3], ssl_parm[4]); + mysql_ssl_set(mysql->mysql, ssl_parm[0].buf, ssl_parm[1].buf, ssl_parm[2].buf, ssl_parm[3].buf, ssl_parm[4].buf); + + for (i=0; i < 5; i++) { + MYSQLI_FREE_STRING(ssl_parm[i]); + } RETURN_TRUE; } /* }}} */ -/* {{{ proto mixed mysqli_stat(object link) +/* {{{ proto mixed mysqli_stat(object link) U Get current system status */ PHP_FUNCTION(mysqli_stat) { @@ -1797,14 +1897,14 @@ PHP_FUNCTION(mysqli_stat) MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); if ((stat = (char *)mysql_stat(mysql->mysql))) { - RETURN_STRING(stat, 1); + MYSQLI_RETURN_CONV_STRING(MYSQLI_CONV_ASCII, stat); } RETURN_FALSE; } /* }}} */ -/* {{{ proto int mysqli_stmt_attr_set(object stmt, long attr, long mode) +/* {{{ proto int mysqli_stmt_attr_set(object stmt, long attr, long mode) U */ PHP_FUNCTION(mysqli_stmt_attr_set) { @@ -1826,7 +1926,7 @@ PHP_FUNCTION(mysqli_stmt_attr_set) } /* }}} */ -/* {{{ proto int mysqli_stmt_attr_get(object stmt, long attr) +/* {{{ proto int mysqli_stmt_attr_get(object stmt, long attr) U */ PHP_FUNCTION(mysqli_stmt_attr_get) { @@ -1852,7 +1952,7 @@ PHP_FUNCTION(mysqli_stmt_attr_get) } /* }}} */ -/* {{{ proto int mysqli_stmt_errno(object stmt) +/* {{{ proto int mysqli_stmt_errno(object stmt) U */ PHP_FUNCTION(mysqli_stmt_errno) { @@ -1868,7 +1968,7 @@ PHP_FUNCTION(mysqli_stmt_errno) } /* }}} */ -/* {{{ proto string mysqli_stmt_error(object stmt) +/* {{{ proto string mysqli_stmt_error(object stmt) U */ PHP_FUNCTION(mysqli_stmt_error) { @@ -1880,11 +1980,11 @@ PHP_FUNCTION(mysqli_stmt_error) } MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt", MYSQLI_STATUS_INITIALIZED); - RETURN_STRING((char *)mysql_stmt_error(stmt->stmt),1); + MYSQLI_RETURN_CONV_STRING(MYSQLI_CONV_UTF8, (char *)mysql_stmt_error(stmt->stmt)); } /* }}} */ -/* {{{ proto mixed mysqli_stmt_init(object link) +/* {{{ proto mixed mysqli_stmt_init(object link) U Initialize statement object */ PHP_FUNCTION(mysqli_stmt_init) @@ -1913,32 +2013,35 @@ PHP_FUNCTION(mysqli_stmt_init) } /* }}} */ -/* {{{ proto bool mysqli_stmt_prepare(object stmt, string query) +/* {{{ proto bool mysqli_stmt_prepare(object stmt, string query) U prepare server side statement with query */ PHP_FUNCTION(mysqli_stmt_prepare) { - MY_STMT *stmt; - zval *mysql_stmt; - char *query; - int query_len; + MY_STMT *stmt; + zval *mysql_stmt; + MYSQLI_STRING query; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_stmt, mysqli_stmt_class_entry, &query, &query_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_stmt, mysqli_stmt_class_entry, MYSQLI_GET_STRING(query)) == FAILURE) { return; } MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt", MYSQLI_STATUS_INITIALIZED); + MYSQLI_CONVERT_PARAM_STRING(query, MYSQLI_CONV_UTF8); - if (mysql_stmt_prepare(stmt->stmt, query, query_len)) { + if (mysql_stmt_prepare(stmt->stmt, query.buf, query.buflen)) { MYSQLI_REPORT_STMT_ERROR(stmt->stmt); - RETURN_FALSE; + RETVAL_FALSE; + goto end; } /* change status */ MYSQLI_SET_STATUS(&mysql_stmt, MYSQLI_STATUS_VALID); - RETURN_TRUE; + RETVAL_TRUE; +end: + MYSQLI_FREE_STRING(query); } /* }}} */ -/* {{{ proto mixed mysqli_stmt_result_metadata(object stmt) +/* {{{ proto mixed mysqli_stmt_result_metadata(object stmt) U return result set from statement */ PHP_FUNCTION(mysqli_stmt_result_metadata) { @@ -1964,7 +2067,7 @@ PHP_FUNCTION(mysqli_stmt_result_metadata) } /* }}} */ -/* {{{ proto bool mysqli_stmt_store_result(stmt) +/* {{{ proto bool mysqli_stmt_store_result(stmt) U */ PHP_FUNCTION(mysqli_stmt_store_result) { @@ -2000,7 +2103,7 @@ PHP_FUNCTION(mysqli_stmt_store_result) } /* }}} */ -/* {{{ proto string mysqli_stmt_sqlstate(object stmt) +/* {{{ proto string mysqli_stmt_sqlstate(object stmt) U */ PHP_FUNCTION(mysqli_stmt_sqlstate) { @@ -2012,11 +2115,11 @@ PHP_FUNCTION(mysqli_stmt_sqlstate) } MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt", MYSQLI_STATUS_VALID); - RETURN_STRING((char *)mysql_stmt_sqlstate(stmt->stmt),1); + MYSQLI_RETURN_CONV_STRING(MYSQLI_CONV_ASCII, (char *)mysql_stmt_sqlstate(stmt->stmt)); } /* }}} */ -/* {{{ proto object mysqli_store_result(object link) +/* {{{ proto object mysqli_store_result(object link) U Buffer result set on client */ PHP_FUNCTION(mysqli_store_result) { @@ -2045,7 +2148,7 @@ PHP_FUNCTION(mysqli_store_result) } /* }}} */ -/* {{{ proto int mysqli_thread_id(object link) +/* {{{ proto int mysqli_thread_id(object link) U Return the current thread ID */ PHP_FUNCTION(mysqli_thread_id) { @@ -2061,7 +2164,7 @@ PHP_FUNCTION(mysqli_thread_id) } /* }}} */ -/* {{{ proto bool mysqli_thread_safe(void) +/* {{{ proto bool mysqli_thread_safe(void) U Return whether thread safety is given or not */ PHP_FUNCTION(mysqli_thread_safe) { @@ -2070,7 +2173,7 @@ PHP_FUNCTION(mysqli_thread_safe) /* }}} */ -/* {{{ proto mixed mysqli_use_result(object link) +/* {{{ proto mixed mysqli_use_result(object link) U Directly retrieve query results - do not buffer results on client side */ PHP_FUNCTION(mysqli_use_result) { @@ -2099,7 +2202,7 @@ PHP_FUNCTION(mysqli_use_result) } /* }}} */ -/* {{{ proto int mysqli_warning_count (object link) +/* {{{ proto int mysqli_warning_count (object link) U Return number of warnings from the last query for the given link */ PHP_FUNCTION(mysqli_warning_count) { diff --git a/ext/mysqli/mysqli_driver.c b/ext/mysqli/mysqli_driver.c index f193e3f9d3..50c33dbe10 100644 --- a/ext/mysqli/mysqli_driver.c +++ b/ext/mysqli/mysqli_driver.c @@ -112,7 +112,7 @@ static int driver_client_version_read(mysqli_object *obj, zval **retval TSRMLS_D static int driver_client_info_read(mysqli_object *obj, zval **retval TSRMLS_DC) { ALLOC_ZVAL(*retval); - ZVAL_STRING(*retval, MYSQL_SERVER_VERSION, 1); + ZVAL_RT_STRING(*retval, MYSQL_SERVER_VERSION, 1); return SUCCESS; } /* }}} */ diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c index 36bd45f39e..2e041ca96d 100644 --- a/ext/mysqli/mysqli_nonapi.c +++ b/ext/mysqli/mysqli_nonapi.c @@ -29,53 +29,54 @@ #include "ext/standard/info.h" #include "php_mysqli.h" -/* {{{ proto object mysqli_connect([string hostname [,string username [,string passwd [,string dbname [,int port [,string socket]]]]]]) +/* {{{ proto object mysqli_connect([string hostname [,string username [,string passwd [,string dbname [,int port [,string socket]]]]]]) U Open a connection to a mysql server */ PHP_FUNCTION(mysqli_connect) { MY_MYSQL *mysql; MYSQLI_RESOURCE *mysqli_resource; zval *object = getThis(); - char *hostname = NULL, *username=NULL, *passwd=NULL, *dbname=NULL, *socket=NULL; - unsigned int hostname_len = 0, username_len = 0, passwd_len = 0, dbname_len = 0, socket_len = 0; + MYSQLI_STRING hostname, username, passwd, dbname, socket; long port=0; if (getThis() && !ZEND_NUM_ARGS()) { RETURN_NULL(); } - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ssssls", &hostname, &hostname_len, &username, &username_len, - &passwd, &passwd_len, &dbname, &dbname_len, &port, &socket, &socket_len) == FAILURE) { + /* optional MYSQLI_STRING parameters have to be initialized */ + memset(&hostname, 0, sizeof(MYSQLI_STRING)); + memset(&username, 0, sizeof(MYSQLI_STRING)); + memset(&dbname, 0, sizeof(MYSQLI_STRING)); + memset(&passwd, 0, sizeof(MYSQLI_STRING)); + memset(&socket, 0, sizeof(MYSQLI_STRING)); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|TTTTlT", MYSQLI_GET_STRING(hostname), MYSQLI_GET_STRING(username), + MYSQLI_GET_STRING(passwd), MYSQLI_GET_STRING(dbname), &port, MYSQLI_GET_STRING(socket)) == FAILURE) { return; } - if (!socket_len) { - socket = NULL; - } - - /* TODO: safe mode handling */ - if (PG(sql_safe_mode)){ - } else { - if (!passwd) { - passwd = MyG(default_pw); - if (!username){ - username = MyG(default_user); - if (!hostname) { - hostname = MyG(default_host); - } - } - } + /* load defaults */ + if (!socket.buflen) { + socket.buf = NULL; } + /* convert strings */ + MYSQLI_CONVERT_PARAM_STRING(hostname, MYSQLI_CONV_ASCII); + MYSQLI_CONVERT_PARAM_STRING(username, MYSQLI_CONV_UTF8); + MYSQLI_CONVERT_PARAM_STRING(passwd, MYSQLI_CONV_UTF8); + MYSQLI_CONVERT_PARAM_STRING(dbname, MYSQLI_CONV_UTF8); + MYSQLI_CONVERT_PARAM_STRING(socket, MYSQLI_CONV_ASCII); + mysql = (MY_MYSQL *) ecalloc(1, sizeof(MY_MYSQL)); if (!(mysql->mysql = mysql_init(NULL))) { efree(mysql); - RETURN_FALSE; + RETVAL_FALSE; + goto end; } #ifdef HAVE_EMBEDDED_MYSQLI - if (hostname_len && hostname) { + if (hostname.cbuffer_len) { unsigned int external=1; mysql_options(mysql->mysql, MYSQL_OPT_USE_REMOTE_CONNECTION, (char *)&external); } else { @@ -83,11 +84,8 @@ PHP_FUNCTION(mysqli_connect) } #endif - if (!socket) { - socket = MyG(default_socket); - } - - if (mysql_real_connect(mysql->mysql,hostname,username,passwd,dbname,port,socket,CLIENT_MULTI_RESULTS) == NULL) { + if (mysql_real_connect(mysql->mysql, (char *)hostname.buf, (char *)username.buf, (char *)passwd.buf, (char *)dbname.buf, port, + (char *)socket.buf, CLIENT_MULTI_RESULTS) == NULL) { /* Save error messages */ php_mysqli_throw_sql_exception( mysql->mysql->net.sqlstate, mysql->mysql->net.last_errno TSRMLS_CC, @@ -98,9 +96,17 @@ PHP_FUNCTION(mysqli_connect) /* free mysql structure */ mysql_close(mysql->mysql); efree(mysql); - RETURN_FALSE; + RETVAL_FALSE; + goto end; + } + + /* when PHP runs in unicode, set default character set to utf8 */ + if (UG(unicode)) { + mysql_set_character_set(mysql->mysql, "utf8"); + mysql->conv = MYSQLI_CONV_UTF8; } + /* clear error */ php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql) TSRMLS_CC); @@ -118,10 +124,16 @@ PHP_FUNCTION(mysqli_connect) } else { ((mysqli_object *) zend_object_store_get_object(object TSRMLS_CC))->ptr = mysqli_resource; } +end: + MYSQLI_FREE_STRING(hostname); + MYSQLI_FREE_STRING(username); + MYSQLI_FREE_STRING(passwd); + MYSQLI_FREE_STRING(dbname); + MYSQLI_FREE_STRING(socket); } /* }}} */ -/* {{{ proto int mysqli_connect_errno(void) +/* {{{ proto int mysqli_connect_errno(void) U Returns the numerical value of the error message from last connect command */ PHP_FUNCTION(mysqli_connect_errno) { @@ -129,19 +141,28 @@ PHP_FUNCTION(mysqli_connect_errno) } /* }}} */ -/* {{{ proto string mysqli_connect_error(void) +/* {{{ proto string mysqli_connect_error(void) U Returns the text of the error message from previous MySQL operation */ PHP_FUNCTION(mysqli_connect_error) { if (MyG(error_msg)) { - RETURN_STRING(MyG(error_msg),1); + if (UG(unicode)) { + UErrorCode status = U_ZERO_ERROR; + UChar *ustr; + int ulen; + + zend_string_to_unicode(MYSQLI_CONV_UTF8, &ustr, &ulen, MyG(error_msg), strlen(MyG(error_msg))); + RETURN_UNICODEL(ustr, ulen, 0); + } else { + RETURN_STRING(MyG(error_msg),1); + } } else { RETURN_NULL(); } } /* }}} */ -/* {{{ proto mixed mysqli_fetch_array (object result [,int resulttype]) +/* {{{ proto mixed mysqli_fetch_array (object result [,int resulttype]) U Fetch a result row as an associative array, a numeric array, or both */ PHP_FUNCTION(mysqli_fetch_array) { @@ -149,7 +170,7 @@ PHP_FUNCTION(mysqli_fetch_array) } /* }}} */ -/* {{{ proto mixed mysqli_fetch_assoc (object result) +/* {{{ proto mixed mysqli_fetch_assoc (object result) U Fetch a result row as an associative array */ PHP_FUNCTION(mysqli_fetch_assoc) { @@ -157,7 +178,7 @@ PHP_FUNCTION(mysqli_fetch_assoc) } /* }}} */ -/* {{{ proto mixed mysqli_fetch_object (object result [, string class_name [, NULL|array ctor_params]]) +/* {{{ proto mixed mysqli_fetch_object (object result [, string class_name [, NULL|array ctor_params]]) Fetch a result row as an object */ PHP_FUNCTION(mysqli_fetch_object) { @@ -165,22 +186,22 @@ PHP_FUNCTION(mysqli_fetch_object) } /* }}} */ -/* {{{ proto bool mysqli_multi_query(object link, string query) - Binary-safe version of mysql_query() */ +/* {{{ proto bool mysqli_multi_query(object link, string query) U + allows to execute multiple queries */ PHP_FUNCTION(mysqli_multi_query) { MY_MYSQL *mysql; zval *mysql_link; - char *query = NULL; - unsigned int query_len; + MYSQLI_STRING query; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &query, &query_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, MYSQLI_GET_STRING(query)) == FAILURE) { return; } MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); + MYSQLI_CONVERT_PARAM_STRING(query, MYSQLI_CONV_UTF8); MYSQLI_ENABLE_MQ; - if (mysql_real_query(mysql->mysql, query, query_len)) { + if (mysql_real_query(mysql->mysql, (char *)query.buf, query.buflen)) { char s_error[MYSQL_ERRMSG_SIZE], s_sqlstate[SQLSTATE_LENGTH+1]; unsigned int s_errno; MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); @@ -198,31 +219,29 @@ PHP_FUNCTION(mysqli_multi_query) strcpy(mysql->mysql->net.sqlstate, s_sqlstate); mysql->mysql->net.last_errno = s_errno; - RETURN_FALSE; - } - RETURN_TRUE; + RETVAL_FALSE; + } else { + RETVAL_TRUE; + } + MYSQLI_FREE_STRING(query); } /* }}} */ -/* {{{ proto mixed mysqli_query(object link, string query [,int resultmode]) */ +/* {{{ proto mixed mysqli_query(object link, string query [,int resultmode]) U */ PHP_FUNCTION(mysqli_query) { MY_MYSQL *mysql; zval *mysql_link; MYSQLI_RESOURCE *mysqli_resource; MYSQL_RES *result; - char *query = NULL; - unsigned int query_len; + MYSQLI_STRING query; unsigned long resultmode = MYSQLI_STORE_RESULT; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|l", &mysql_link, mysqli_link_class_entry, &query, &query_len, &resultmode) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OT|l", &mysql_link, mysqli_link_class_entry, MYSQLI_GET_STRING(query), + &resultmode) == FAILURE) { return; } - if (!query_len) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty query"); - RETURN_FALSE; - } if (resultmode != MYSQLI_USE_RESULT && resultmode != MYSQLI_STORE_RESULT) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid value for resultmode"); RETURN_FALSE; @@ -230,19 +249,28 @@ PHP_FUNCTION(mysqli_query) MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL*, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); + MYSQLI_CONVERT_PARAM_STRING(query, MYSQLI_CONV_UTF8); + + if (!query.buflen) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty query"); + RETVAL_FALSE; + goto end; + } MYSQLI_DISABLE_MQ; - if (mysql_real_query(mysql->mysql, query, query_len)) { + if (mysql_real_query(mysql->mysql, (char *)query.buf, query.buflen)) { MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); - RETURN_FALSE; + RETVAL_FALSE; + goto end; } if (!mysql_field_count(mysql->mysql)) { /* no result set - not a SELECT */ if (MyG(report_mode) & MYSQLI_REPORT_INDEX) { - php_mysqli_report_index(query, mysql->mysql->server_status TSRMLS_CC); + php_mysqli_report_index(query.buf, mysql->mysql->server_status TSRMLS_CC); } - RETURN_TRUE; + RETVAL_TRUE; + goto end; } result = (resultmode == MYSQLI_USE_RESULT) ? mysql_use_result(mysql->mysql) : mysql_store_result(mysql->mysql); @@ -250,21 +278,24 @@ PHP_FUNCTION(mysqli_query) if (!result) { php_mysqli_throw_sql_exception(mysql->mysql->net.sqlstate, mysql->mysql->net.last_errno TSRMLS_CC, "%s", mysql->mysql->net.last_error); - RETURN_FALSE; + RETVAL_FALSE; + goto end; } if (MyG(report_mode) & MYSQLI_REPORT_INDEX) { - php_mysqli_report_index(query, mysql->mysql->server_status TSRMLS_CC); + php_mysqli_report_index((char *)query.buf, mysql->mysql->server_status TSRMLS_CC); } mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); mysqli_resource->ptr = (void *)result; mysqli_resource->status = MYSQLI_STATUS_VALID; MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry); +end: + MYSQLI_FREE_STRING(query); } /* }}} */ -/* {{{ proto object mysqli_get_warnings(object link) */ +/* {{{ proto object mysqli_get_warnings(object link) U */ PHP_FUNCTION(mysqli_get_warnings) { MY_MYSQL *mysql; @@ -284,11 +315,12 @@ PHP_FUNCTION(mysqli_get_warnings) } mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); mysqli_resource->ptr = mysqli_resource->info = (void *)w; + mysqli_resource->status = MYSQLI_STATUS_INITIALIZED; MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_warning_class_entry); } /* }}} */ -/* {{{ proto object mysqli_get_warnings(object link) */ +/* {{{ proto object mysqli_get_warnings(object link) U */ PHP_FUNCTION(mysqli_stmt_get_warnings) { MY_STMT *stmt; @@ -308,35 +340,46 @@ PHP_FUNCTION(mysqli_stmt_get_warnings) } mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); mysqli_resource->ptr = mysqli_resource->info = (void *)w; - MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_warning_class_entry); + mysqli_resource->status = MYSQLI_STATUS_INITIALIZED; + MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_warning_class_entry); } /* }}} */ #ifdef HAVE_MYSQLI_SET_CHARSET -/* {{{ proto bool mysqli_set_charset(object link, string csname) +/* {{{ proto bool mysqli_set_charset(object link, string csname) U sets client character set */ PHP_FUNCTION(mysqli_set_charset) { MY_MYSQL *mysql; zval *mysql_link; - char *cs_name = NULL; - unsigned int len; + MYSQLI_STRING csname; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &cs_name, &len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, MYSQLI_GET_STRING(csname)) == FAILURE) { return; } MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL*, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); + MYSQLI_CONVERT_PARAM_STRING(csname, MYSQLI_CONV_UTF8); + RETVAL_FALSE; + + /* check unicode modus */ + /* todo: we need also to support UCS2. This will not work when using SET NAMES */ + if (UG(unicode) && (csname.buflen != 4 || strncasecmp((char *)csname.buf, "utf8", 4))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Character set %s is not supported when running PHP with unicode.semantics=On.", csname); + RETVAL_FALSE; + goto end; + } - if (mysql_set_character_set(mysql->mysql, cs_name)) { - RETURN_FALSE; + if (!mysql_set_character_set(mysql->mysql, (char *)csname.buf)) { + RETVAL_TRUE; } - RETURN_TRUE; +end: + MYSQLI_FREE_STRING(csname); } /* }}} */ #endif #ifdef HAVE_MYSQLI_GET_CHARSET -/* {{{ proto object mysqli_get_charset(object link) +/* {{{ proto object mysqli_get_charset(object link) U returns a character set object */ PHP_FUNCTION(mysqli_get_charset) { @@ -353,10 +396,29 @@ PHP_FUNCTION(mysqli_get_charset) mysql_get_character_set_info(mysql->mysql, &cs); - add_property_string(return_value, "charset", (cs.name) ? (char *)cs.csname : "", 1); - add_property_string(return_value, "collation",(cs.name) ? (char *)cs.name : "", 1); - add_property_string(return_value, "comment", (cs.comment) ? (char *)cs.comment : "", 1); - add_property_string(return_value, "dir", (cs.dir) ? (char *)cs.dir : "", 1); + if (UG(unicode)) { + UErrorCode status = U_ZERO_ERROR; + UChar *ustr; + int ulen; + + zend_string_to_unicode(MYSQLI_CONV_UTF8, &ustr, &ulen, (cs.csname) ? cs.csname : "", + (cs.csname) ? strlen(cs.csname) : 0); + add_property_unicodel(return_value, "charset", ustr, ulen, 1); + zend_string_to_unicode(MYSQLI_CONV_UTF8, &ustr, &ulen, (cs.name) ? cs.name : "", + (cs.name) ? strlen(cs.name) : 0); + add_property_unicodel(return_value, "collation", ustr, ulen, 1); + zend_string_to_unicode(MYSQLI_CONV_UTF8, &ustr, &ulen, (cs.comment) ? cs.comment : "", + (cs.comment) ? strlen(cs.comment) : 0); + add_property_unicodel(return_value, "comment", ustr, ulen, 1); + zend_string_to_unicode(MYSQLI_CONV_UTF8, &ustr, &ulen, (cs.dir) ? cs.dir : "", + (cs.dir) ? strlen(cs.dir) : 0); + add_property_unicodel(return_value, "dir", ustr, ulen, 1); + } else { + add_property_string(return_value, "charset", (cs.name) ? (char *)cs.csname : "", 1); + add_property_string(return_value, "collation",(cs.name) ? (char *)cs.name : "", 1); + add_property_string(return_value, "comment", (cs.comment) ? (char *)cs.comment : "", 1); + add_property_string(return_value, "dir", (cs.dir) ? (char *)cs.dir : "", 1); + } add_property_long(return_value, "min_length", cs.mbminlen); add_property_long(return_value, "max_length", cs.mbmaxlen); add_property_long(return_value, "number", cs.number); diff --git a/ext/mysqli/mysqli_prop.c b/ext/mysqli/mysqli_prop.c index db7b637728..00170e3d54 100644 --- a/ext/mysqli/mysqli_prop.c +++ b/ext/mysqli/mysqli_prop.c @@ -105,7 +105,14 @@ static int __func(mysqli_object *obj, zval **retval TSRMLS_DC)\ if (!c) {\ ZVAL_NULL(*retval);\ } else {\ - ZVAL_STRING(*retval, c, 1);\ + if (UG(unicode)) {\ + UChar *ubuf = NULL;\ + uint ulen;\ + zend_string_to_unicode(MYSQLI_CONV_UTF8, &ubuf, &ulen, c, strlen(c));\ + ZVAL_UNICODEL(*retval, ubuf, ulen, 0);\ + } else {\ + ZVAL_STRING(*retval, c, 1);\ + }\ }\ }\ return SUCCESS;\ diff --git a/ext/mysqli/mysqli_report.c b/ext/mysqli/mysqli_report.c index 472e2d9a38..15829fa3c1 100644 --- a/ext/mysqli/mysqli_report.c +++ b/ext/mysqli/mysqli_report.c @@ -27,7 +27,7 @@ #include "ext/standard/info.h" #include "php_mysqli.h" -/* {{{ bool mysqli_report(int flags) +/* {{{ bool mysqli_report(int flags) U sets report level */ PHP_FUNCTION(mysqli_report) { diff --git a/ext/mysqli/php_mysqli.h b/ext/mysqli/php_mysqli.h index d908996291..d682f0a4c7 100644 --- a/ext/mysqli/php_mysqli.h +++ b/ext/mysqli/php_mysqli.h @@ -36,6 +36,9 @@ #define HAVE_MYSQLI_SET_CHARSET #endif +#define MYSQLI_UC_UTF8 1 +#define MYSQLI_UC_UCS2 2 + #include <errmsg.h> #ifndef PHP_MYSQLI_H @@ -51,6 +54,13 @@ enum mysqli_status { }; typedef struct { + void *buf; /* buffer: binary or unicode data */ + unsigned int buflen; /* buffer length */ + zend_uchar buftype; /* buffer type */ + UErrorCode status; /* error code */ +} MYSQLI_STRING; + +typedef struct { ulong buflen; char *val; ulong type; @@ -74,7 +84,8 @@ typedef struct { MYSQL *mysql; zval *li_read; php_stream *li_stream; - unsigned int multi_query; + unsigned int multi_query; + UConverter *conv; } MY_MYSQL; typedef struct { @@ -218,12 +229,13 @@ PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry * TSRML MYSQLI_RESOURCE *my_res; \ mysqli_object *intern = (mysqli_object *)zend_object_store_get_object(*(__id) TSRMLS_CC);\ if (!(my_res = (MYSQLI_RESOURCE *)intern->ptr)) {\ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %s", intern->zo.ce->name);\ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %R", UG(unicode)?IS_UNICODE:IS_STRING, intern->zo.ce->name);\ + printf("--------\n");\ RETURN_NULL();\ }\ __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); \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid object or resource %R\n", UG(unicode)?IS_UNICODE:IS_STRING, intern->zo.ce->name); \ RETURN_NULL();\ }\ } @@ -261,6 +273,43 @@ PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry * TSRML }\ } +#define MYSQLI_GET_STRING(a) &a.buf, &a.buflen, &a.buftype + +#define MYSQLI_FREE_STRING(a) \ +if (a.buftype == IS_UNICODE) {\ + efree(a.buf);\ +} + +#define MYSQLI_CONVERT_PARAM_STRING(a,c)\ +if (a.buftype == IS_UNICODE) {\ + a.status=U_ZERO_ERROR;\ + zend_unicode_to_string_ex(c, (char **)&a.buf, &a.buflen, a.buf, a.buflen, &a.status);\ +} + +#define MYSQLI_RETURN_CONV_STRING(conv, value) \ +if (UG(unicode)) { \ + UChar *ustr;\ + int ulen;\ + zend_string_to_unicode(conv, &ustr, &ulen, (value) ? value : "", (value) ? strlen(value) : 0);\ + RETURN_UNICODEL(ustr, ulen, 0);\ +} else {\ + RETURN_STRING((value) ? value : "", 1);\ +}\ + +#define MYSQLI_RETURN_CONV_STRINGL(conv, value, len, copy) \ +if (UG(unicode)) { \ + UChar *ustr;\ + int ulen;\ + zend_string_to_unicode(conv, &ustr, &ulen, (value) ? value : "", len);\ + RETURN_UNICODEL(ustr, ulen, 0);\ +} else {\ + RETURN_STRINGL((value) ? value : "", len, copy);\ +}\ + +#define MYSQLI_CONV_UTF8 unicode_globals.utf8_conv +#define MYSQLI_CONV_UCS2 unicode_globals.ucs2_conv +#define MYSQLI_CONV_ASCII unicode_globals.ascii_conv + #if WIN32|WINNT #define SCLOSE(a) closesocket(a) #else diff --git a/ext/mysqli/tests/001.phpt b/ext/mysqli/tests/001.phpt index 3f2f3c2d31..e5a69fe7df 100644 --- a/ext/mysqli/tests/001.phpt +++ b/ext/mysqli/tests/001.phpt @@ -43,5 +43,5 @@ mysqli connect var_dump($test); ?> ---EXPECT-- -string(5) "11111" +--EXPECTF-- +%s(5) "11111" diff --git a/ext/mysqli/tests/002.phpt b/ext/mysqli/tests/002.phpt index 301af98939..49145bb33e 100644 --- a/ext/mysqli/tests/002.phpt +++ b/ext/mysqli/tests/002.phpt @@ -36,7 +36,7 @@ mysqli bind_result 1 mysqli_stmt_close($stmt); mysqli_close($link); ?> ---EXPECT-- +--EXPECTF-- array(11) { [0]=> int(1) @@ -57,7 +57,7 @@ array(11) { [8]=> NULL [9]=> - string(4) "foo1" + %s(4) "foo1" [10]=> - string(4) "1000" + %s(4) "1000" } diff --git a/ext/mysqli/tests/003.phpt b/ext/mysqli/tests/003.phpt index 28aedb032c..ef6a9d551d 100644 --- a/ext/mysqli/tests/003.phpt +++ b/ext/mysqli/tests/003.phpt @@ -39,20 +39,20 @@ mysqli connect mysqli_stmt_close($stmt); mysqli_close($link); ?> ---EXPECT-- +--EXPECTF-- array(7) { [0]=> - string(10) "2002-01-02" + %s(10) "2002-01-02" [1]=> - string(8) "12:49:00" + %s(8) "12:49:00" [2]=> - string(19) "2002-01-02 17:46:59" + %s(19) "2002-01-02 17:46:59" [3]=> int(2010) [4]=> - string(19) "2010-07-10 00:00:00" + %s(19) "2010-07-10 00:00:00" [5]=> - string(19) "0000-00-00 00:00:00" + %s(19) "0000-00-00 00:00:00" [6]=> - string(19) "1999-12-29 00:00:00" + %s(19) "1999-12-29 00:00:00" } diff --git a/ext/mysqli/tests/004.phpt b/ext/mysqli/tests/004.phpt index fafc30ba0d..d7f0233d5b 100644 --- a/ext/mysqli/tests/004.phpt +++ b/ext/mysqli/tests/004.phpt @@ -33,28 +33,28 @@ mysqli fetch char/text mysqli_stmt_close($stmt); mysqli_close($link); ?> ---EXPECT-- +--EXPECTF-- array(2) { [0]=> - string(10) "1234567890" + %s(10) "1234567890" [1]=> - string(15) "this is a test0" + %s(15) "this is a test0" } array(2) { [0]=> - string(10) "1234567891" + %s(10) "1234567891" [1]=> - string(15) "this is a test1" + %s(15) "this is a test1" } array(2) { [0]=> - string(10) "1234567892" + %s(10) "1234567892" [1]=> - string(15) "this is a test2" + %s(15) "this is a test2" } array(2) { [0]=> - string(10) "1234567893" + %s(10) "1234567893" [1]=> - string(15) "this is a test3" + %s(15) "this is a test3" } diff --git a/ext/mysqli/tests/005.phpt b/ext/mysqli/tests/005.phpt index a9f75cfd7e..afe43a778e 100644 --- a/ext/mysqli/tests/005.phpt +++ b/ext/mysqli/tests/005.phpt @@ -31,10 +31,10 @@ mysqli fetch char/text long mysqli_stmt_close($stmt); mysqli_close($link); ?> ---EXPECT-- +--EXPECTF-- array(2) { [0]=> - string(10) "1234567890" + %s(10) "1234567890" [1]=> - string(13) "32K String ok" + %s(13) "32K String ok" } diff --git a/ext/mysqli/tests/009.phpt b/ext/mysqli/tests/009.phpt index 32ed3c18f0..ae35d97fc2 100644 --- a/ext/mysqli/tests/009.phpt +++ b/ext/mysqli/tests/009.phpt @@ -58,7 +58,7 @@ mysqli fetch bigint values (ok to fail with 4.1.x) mysqli_close($link); ?> ---EXPECT-- +--EXPECTF-- array(7) { [0]=> int(5) @@ -67,7 +67,7 @@ array(7) { [2]=> int(4) [3]=> - string(14) "33333333333333" + %s(14) "33333333333333" [4]=> int(0) [5]=> diff --git a/ext/mysqli/tests/011.phpt b/ext/mysqli/tests/011.phpt index 77a157f564..7cef7292b9 100644 --- a/ext/mysqli/tests/011.phpt +++ b/ext/mysqli/tests/011.phpt @@ -36,7 +36,7 @@ precision=12 mysqli_stmt_close($stmt); mysqli_close($link); ?> ---EXPECT-- +--EXPECTF-- array(8) { [0]=> int(19) @@ -51,7 +51,7 @@ array(8) { [5]=> float(5678.89563) [6]=> - string(6) "foobar" + %s(6) "foobar" [7]=> - string(11) "mysql rulez" + %s(11) "mysql rulez" } diff --git a/ext/mysqli/tests/012.phpt b/ext/mysqli/tests/012.phpt index 9c52f9c3e4..487019cc4d 100644 --- a/ext/mysqli/tests/012.phpt +++ b/ext/mysqli/tests/012.phpt @@ -37,7 +37,7 @@ precision=12 mysqli_stmt_close($stmt); mysqli_close($link); ?> ---EXPECT-- +--EXPECTF-- array(8) { [0]=> int(120) @@ -52,7 +52,7 @@ array(8) { [5]=> float(58.89) [6]=> - string(3) "206" + %s(3) "206" [7]=> - string(3) "6.7" + %s(3) "6.7" } diff --git a/ext/mysqli/tests/014.phpt b/ext/mysqli/tests/014.phpt index d6591fcab4..4c746a1a6c 100644 --- a/ext/mysqli/tests/014.phpt +++ b/ext/mysqli/tests/014.phpt @@ -53,17 +53,17 @@ mysqli autocommit/commit/rollback mysqli_close($link); ?> ---EXPECT-- +--EXPECTF-- Num_of_rows=1 array(2) { [0]=> - string(1) "1" + %s(1) "1" [1]=> - string(6) "foobar" + %s(6) "foobar" } array(2) { [0]=> - string(1) "2" + %s(1) "2" [1]=> - string(4) "egon" + %s(4) "egon" } diff --git a/ext/mysqli/tests/015.phpt b/ext/mysqli/tests/015.phpt index 7620f3c435..f8881987bd 100644 --- a/ext/mysqli/tests/015.phpt +++ b/ext/mysqli/tests/015.phpt @@ -54,16 +54,16 @@ mysqli autocommit/commit/rollback with myisam mysqli_close($link); ?> ---EXPECT-- +--EXPECTF-- array(2) { [0]=> - string(1) "2" + %s(1) "2" [1]=> - string(4) "egon" + %s(4) "egon" } array(2) { [0]=> - string(1) "2" + %s(1) "2" [1]=> - string(4) "egon" + %s(4) "egon" } diff --git a/ext/mysqli/tests/016.phpt b/ext/mysqli/tests/016.phpt index c61da29ec1..469795e710 100644 --- a/ext/mysqli/tests/016.phpt +++ b/ext/mysqli/tests/016.phpt @@ -23,5 +23,5 @@ mysqli fetch user variable mysqli_stmt_close($stmt); mysqli_close($link); ?> ---EXPECT-- -string(6) "foobar" +--EXPECTF-- +%s(6) "foobar" diff --git a/ext/mysqli/tests/017.phpt b/ext/mysqli/tests/017.phpt index 866a118a86..e8b19fb0da 100644 --- a/ext/mysqli/tests/017.phpt +++ b/ext/mysqli/tests/017.phpt @@ -24,12 +24,12 @@ mysqli fetch functions var_dump($test); mysqli_close($link); ?> ---EXPECT-- +--EXPECTF-- array(3) { [0]=> - string(32) "37b51d194a7513e45b56f6524f2d51f2" + %s(32) "37b51d194a7513e45b56f6524f2d51f2" [1]=> - string(4) "test" + %s(4) "test" [2]=> - string(3) "foo" + %s(3) "foo" } diff --git a/ext/mysqli/tests/019.phpt b/ext/mysqli/tests/019.phpt index 173c404909..bae37faf45 100644 --- a/ext/mysqli/tests/019.phpt +++ b/ext/mysqli/tests/019.phpt @@ -44,7 +44,7 @@ mysqli fetch (bind_param + bind_result) mysqli_stmt_close($stmt); mysqli_close($link); ?> ---EXPECT-- +--EXPECTF-- array(11) { [0]=> int(1) @@ -65,7 +65,7 @@ array(11) { [8]=> NULL [9]=> - string(3) "foo" + %s(3) "foo" [10]=> - string(6) "foobar" + %s(6) "foobar" } diff --git a/ext/mysqli/tests/020.phpt b/ext/mysqli/tests/020.phpt index 4ae140f620..17dc981b50 100644 --- a/ext/mysqli/tests/020.phpt +++ b/ext/mysqli/tests/020.phpt @@ -4,6 +4,7 @@ mysqli bind_param/bind_result date <?php require_once('skipif.inc'); ?> --FILE-- <?php + include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ @@ -23,13 +24,13 @@ mysqli bind_param/bind_result date $stmt = mysqli_prepare($link, "INSERT INTO test_bind_result VALUES (?,?,?,?,?,?,?)"); mysqli_bind_param($stmt, "sssssss", $d1, $d2, $d3, $d4, $d5, $d6, $d7); - $d1 = '2002-01-02'; - $d2 = '12:49:00'; - $d3 = '2002-01-02 17:46:59'; - $d4 = 2010; - $d5 ='2010-07-10'; - $d6 = '2020'; - $d7 = '1999-12-29'; + $d1 = "2002-01-02"; + $d2 = "12:49:00"; + $d3 = "2002-01-02 17:46:59"; + $d4 = "2010"; + $d5 = "2010-07-10"; + $d6 = "2020"; + $d7 = "1999-12-29"; mysqli_execute($stmt); mysqli_stmt_close($stmt); @@ -48,20 +49,20 @@ mysqli bind_param/bind_result date mysqli_stmt_close($stmt); mysqli_close($link); ?> ---EXPECT-- +--EXPECTF-- array(7) { [0]=> - string(10) "2002-01-02" + %s(10) "2002-01-02" [1]=> - string(8) "12:49:00" + %s(8) "12:49:00" [2]=> - string(19) "2002-01-02 17:46:59" + %s(19) "2002-01-02 17:46:59" [3]=> int(2010) [4]=> - string(19) "2010-07-10 00:00:00" + %s(19) "2010-07-10 00:00:00" [5]=> - string(19) "0000-00-00 00:00:00" + %s(19) "0000-00-00 00:00:00" [6]=> - string(19) "1999-12-29 00:00:00" + %s(19) "1999-12-29 00:00:00" } diff --git a/ext/mysqli/tests/021.phpt b/ext/mysqli/tests/021.phpt index 6f5bad3205..e351bd4540 100644 --- a/ext/mysqli/tests/021.phpt +++ b/ext/mysqli/tests/021.phpt @@ -33,10 +33,10 @@ mysqli bind_param+bind_result char/text mysqli_stmt_close($stmt); mysqli_close($link); ?> ---EXPECT-- +--EXPECTF-- array(2) { [0]=> - string(10) "1234567890" + %s(10) "1234567890" [1]=> - string(14) "this is a test" + %s(14) "this is a test" } diff --git a/ext/mysqli/tests/022.phpt b/ext/mysqli/tests/022.phpt index cce8ed8eb6..a716d848fd 100644 --- a/ext/mysqli/tests/022.phpt +++ b/ext/mysqli/tests/022.phpt @@ -37,10 +37,10 @@ mysqli bind_param/bind_result char/text long mysqli_stmt_close($stmt); mysqli_close($link); ?> ---EXPECT-- +--EXPECTF-- array(2) { [0]=> - string(10) "1234567890" + %s(10) "1234567890" [1]=> - string(13) "32K String ok" + %s(13) "32K String ok" } diff --git a/ext/mysqli/tests/026.phpt b/ext/mysqli/tests/026.phpt index d38e3c1807..ad4fe67b84 100644 --- a/ext/mysqli/tests/026.phpt +++ b/ext/mysqli/tests/026.phpt @@ -40,10 +40,10 @@ mysqli bind_param/bind_result with send_long_data mysqli_close($link); ?> ---EXPECT-- +--EXPECTF-- array(2) { [0]=> - string(10) "Hello Worl" + %s(10) "Hello Worl" [1]=> - string(99) "This is the first sentence. And this is the second sentence. And finally this is the last sentence." + %s(99) "This is the first sentence. And this is the second sentence. And finally this is the last sentence." } diff --git a/ext/mysqli/tests/028.phpt b/ext/mysqli/tests/028.phpt index 0e897d86f8..b11da2ae44 100644 --- a/ext/mysqli/tests/028.phpt +++ b/ext/mysqli/tests/028.phpt @@ -16,4 +16,4 @@ function test: mysqli_character_set_name mysqli_close($link); ?> --EXPECTF-- -string(%d) "%s" +%s(%d) "%s" diff --git a/ext/mysqli/tests/031.phpt b/ext/mysqli/tests/031.phpt index 743b4b2d0f..4e1e35f4ee 100644 --- a/ext/mysqli/tests/031.phpt +++ b/ext/mysqli/tests/031.phpt @@ -20,6 +20,6 @@ function test: mysqli_error mysqli_close($link); ?> ---EXPECT-- -string(0) "" -string(46) "Table 'test.non_exisiting_table' doesn't exist" +--EXPECTF-- +%s(0) "" +%s(46) "Table 'test.non_exisiting_table' doesn't exist" diff --git a/ext/mysqli/tests/032.phpt b/ext/mysqli/tests/032.phpt index 18bd756a23..f210869b92 100644 --- a/ext/mysqli/tests/032.phpt +++ b/ext/mysqli/tests/032.phpt @@ -21,5 +21,5 @@ function test: mysqli_info mysqli_close($link); ?> ---EXPECT-- -string(38) "Records: 3 Duplicates: 0 Warnings: 0" +--EXPECTF-- +%s(38) "Records: 3 Duplicates: 0 Warnings: 0" diff --git a/ext/mysqli/tests/042.phpt b/ext/mysqli/tests/042.phpt index 719e24925d..181461af84 100644 --- a/ext/mysqli/tests/042.phpt +++ b/ext/mysqli/tests/042.phpt @@ -60,3 +60,20 @@ object(stdClass)#%d (7) { ["c7"]=> string(1) "0" } +--UEXPECTF-- +object(stdClass)#%d (7) { + [u"c1"]=> + unicode(1) "0" + [u"c2"]=> + unicode(5) "35999" + [u"c3"]=> + NULL + [u"c4"]=> + unicode(4) "-500" + [u"c5"]=> + unicode(6) "-32768" + [u"c6"]=> + unicode(1) "0" + [u"c7"]=> + unicode(1) "0" +} diff --git a/ext/mysqli/tests/043.phpt b/ext/mysqli/tests/043.phpt index fb0284e06a..d218d8f868 100644 --- a/ext/mysqli/tests/043.phpt +++ b/ext/mysqli/tests/043.phpt @@ -35,8 +35,8 @@ mysqli_bind_param (UPDATE) mysqli_close($link); ?> ---EXPECT-- +--EXPECTF-- array(1) { [0]=> - string(15) "Rasmus is No. 1" + %s(15) "Rasmus is No. 1" } diff --git a/ext/mysqli/tests/045.phpt b/ext/mysqli/tests/045.phpt index dd491a6977..abb6404850 100644 --- a/ext/mysqli/tests/045.phpt +++ b/ext/mysqli/tests/045.phpt @@ -37,10 +37,10 @@ mysqli_bind_result (SHOW) mysqli_close($link); ?> ---EXPECT-- +--EXPECTF-- array(2) { [0]=> - string(4) "port" + %s(4) "port" [1]=> - string(4) "3306" + %s(4) "%s" } diff --git a/ext/mysqli/tests/047.phpt b/ext/mysqli/tests/047.phpt index 4b5df98676..d2bcda40d2 100644 --- a/ext/mysqli/tests/047.phpt +++ b/ext/mysqli/tests/047.phpt @@ -193,4 +193,158 @@ object(stdClass)#5 (11) { int(253) ["decimals"]=> int(0) -}
\ No newline at end of file +} +--UEXPECTF-- +=== fetch_fields === +array(2) { + [0]=> + object(stdClass)#5 (11) { + [u"name"]=> + unicode(3) "foo" + [u"orgname"]=> + unicode(3) "foo" + [u"table"]=> + unicode(13) "test_affected" + [u"orgtable"]=> + unicode(13) "test_affected" + [u"def"]=> + unicode(0) "" + [u"max_length"]=> + int(0) + [u"length"]=> + int(11) + [u"charsetnr"]=> + int(63) + [u"flags"]=> + int(32768) + [u"type"]=> + int(3) + [u"decimals"]=> + int(0) + } + [1]=> + object(stdClass)#6 (11) { + [u"name"]=> + unicode(3) "bar" + [u"orgname"]=> + unicode(3) "bar" + [u"table"]=> + unicode(13) "test_affected" + [u"orgtable"]=> + unicode(13) "test_affected" + [u"def"]=> + unicode(0) "" + [u"max_length"]=> + int(0) + [u"length"]=> + int(%d) + [u"charsetnr"]=> + int(%d) + [u"flags"]=> + int(0) + [u"type"]=> + int(253) + [u"decimals"]=> + int(0) + } +} + +=== fetch_field_direct === +object(stdClass)#6 (11) { + [u"name"]=> + unicode(3) "foo" + [u"orgname"]=> + unicode(3) "foo" + [u"table"]=> + unicode(13) "test_affected" + [u"orgtable"]=> + unicode(13) "test_affected" + [u"def"]=> + unicode(0) "" + [u"max_length"]=> + int(0) + [u"length"]=> + int(%d) + [u"charsetnr"]=> + int(%d) + [u"flags"]=> + int(32768) + [u"type"]=> + int(3) + [u"decimals"]=> + int(0) +} +object(stdClass)#6 (11) { + [u"name"]=> + unicode(3) "bar" + [u"orgname"]=> + unicode(3) "bar" + [u"table"]=> + unicode(13) "test_affected" + [u"orgtable"]=> + unicode(13) "test_affected" + [u"def"]=> + unicode(0) "" + [u"max_length"]=> + int(0) + [u"length"]=> + int(%d) + [u"charsetnr"]=> + int(%d) + [u"flags"]=> + int(0) + [u"type"]=> + int(253) + [u"decimals"]=> + int(0) +} + +=== fetch_field === +object(stdClass)#6 (11) { + [u"name"]=> + unicode(3) "foo" + [u"orgname"]=> + unicode(3) "foo" + [u"table"]=> + unicode(13) "test_affected" + [u"orgtable"]=> + unicode(13) "test_affected" + [u"def"]=> + unicode(0) "" + [u"max_length"]=> + int(0) + [u"length"]=> + int(%d) + [u"charsetnr"]=> + int(%d) + [u"flags"]=> + int(32768) + [u"type"]=> + int(3) + [u"decimals"]=> + int(0) +} +object(stdClass)#5 (11) { + [u"name"]=> + unicode(3) "bar" + [u"orgname"]=> + unicode(3) "bar" + [u"table"]=> + unicode(13) "test_affected" + [u"orgtable"]=> + unicode(13) "test_affected" + [u"def"]=> + unicode(0) "" + [u"max_length"]=> + int(0) + [u"length"]=> + int(%d) + [u"charsetnr"]=> + int(%d) + [u"flags"]=> + int(0) + [u"type"]=> + int(253) + [u"decimals"]=> + int(0) +} diff --git a/ext/mysqli/tests/048.phpt b/ext/mysqli/tests/048.phpt index 1cf5b67894..cf4eab9fe3 100644 --- a/ext/mysqli/tests/048.phpt +++ b/ext/mysqli/tests/048.phpt @@ -35,7 +35,7 @@ mysqli bind_result (OO-Style) $stmt->close(); $mysql->close(); ?> ---EXPECT-- +--EXPECTF-- array(11) { [0]=> int(1) @@ -56,7 +56,7 @@ array(11) { [8]=> NULL [9]=> - string(4) "foo1" + %s(4) "foo1" [10]=> - string(4) "1000" + %s(4) "1000" } diff --git a/ext/mysqli/tests/049.phpt b/ext/mysqli/tests/049.phpt index 4bb5bfef45..5e82040ffc 100644 --- a/ext/mysqli/tests/049.phpt +++ b/ext/mysqli/tests/049.phpt @@ -19,8 +19,8 @@ mysql_fetch_row (OO-Style) $mysql->close(); ?> ---EXPECT-- +--EXPECTF-- array(1) { [0]=> - string(4) "test" + %s(4) "test" } diff --git a/ext/mysqli/tests/057.phpt b/ext/mysqli/tests/057.phpt index a987c72381..6f2f797021 100644 --- a/ext/mysqli/tests/057.phpt +++ b/ext/mysqli/tests/057.phpt @@ -46,9 +46,9 @@ mysqli_get_metadata mysqli_stmt_close($stmt); mysqli_close($link); ?> ---EXPECT-- +--EXPECTF-- Rows: 3 array(1) { [0]=> - string(1) "1" + %s(1) "1" } diff --git a/ext/mysqli/tests/058.phpt b/ext/mysqli/tests/058.phpt index 7554d08f68..2c08090d99 100644 --- a/ext/mysqli/tests/058.phpt +++ b/ext/mysqli/tests/058.phpt @@ -44,14 +44,14 @@ multiple binds mysqli_close($link); ?> ---EXPECT-- +--EXPECTF-- array(4) { [0]=> int(1) [1]=> - string(3) "foo" + %s(3) "foo" [2]=> int(2) [3]=> - string(3) "bar" + %s(3) "bar" } diff --git a/ext/mysqli/tests/059.phpt b/ext/mysqli/tests/059.phpt index 0bc8a62bbf..98149f303a 100644 --- a/ext/mysqli/tests/059.phpt +++ b/ext/mysqli/tests/059.phpt @@ -39,3 +39,5 @@ sqlmode + bind ?> --EXPECT-- string(6) "foobar" +--UEXPECT-- +unicode(6) "foobar" diff --git a/ext/mysqli/tests/060.phpt b/ext/mysqli/tests/060.phpt index ba6c231c57..e06f25949d 100644 --- a/ext/mysqli/tests/060.phpt +++ b/ext/mysqli/tests/060.phpt @@ -58,3 +58,22 @@ object(test_class)#%d (7) { string(1) "0" } Done +--UEXPECTF-- +test_class::__construct(1,2) +object(test_class)#%d (7) { + [u"c1"]=> + unicode(1) "0" + [u"c2"]=> + unicode(5) "35999" + [u"c3"]=> + NULL + [u"c4"]=> + unicode(4) "-500" + [u"c5"]=> + unicode(6) "-32768" + [u"c6"]=> + unicode(1) "0" + [u"c7"]=> + unicode(1) "0" +} +Done diff --git a/ext/mysqli/tests/061.phpt b/ext/mysqli/tests/061.phpt index c7a217f274..9516d0ce53 100644 --- a/ext/mysqli/tests/061.phpt +++ b/ext/mysqli/tests/061.phpt @@ -2,7 +2,6 @@ local infile handler --SKIPIF-- <?php require_once('skipif.inc'); ?> -<?php require_once('skipifemb.inc'); ?> --FILE-- <?php include "connect.inc"; @@ -18,7 +17,7 @@ local infile handler /* create temporary file */ $filename = dirname(__FILE__) . "061.csv"; $fp = fopen($filename, "w"); - fwrite($fp, "foo;bar"); + @fwrite($fp, "foo;bar"); fclose($fp); mysqli_query($link,"DROP TABLE IF EXISTS t_061"); diff --git a/ext/mysqli/tests/062.phpt b/ext/mysqli/tests/062.phpt index 962abce162..cd1fc9b032 100644 --- a/ext/mysqli/tests/062.phpt +++ b/ext/mysqli/tests/062.phpt @@ -18,8 +18,8 @@ resultset constructor var_dump($row); ?> ---EXPECT-- +--EXPECTF-- array(1) { [0]=> - string(3) "foo" + %s(3) "foo" } diff --git a/ext/mysqli/tests/063.phpt b/ext/mysqli/tests/063.phpt index 9dd01629aa..86d66b1544 100644 --- a/ext/mysqli/tests/063.phpt +++ b/ext/mysqli/tests/063.phpt @@ -19,3 +19,5 @@ resultset constructor ?> --EXPECT-- string(3) "foo" +--UEXPECT-- +unicode(3) "foo" diff --git a/ext/mysqli/tests/065.phpt b/ext/mysqli/tests/065.phpt index 09ee886ec5..b064e744f4 100644 --- a/ext/mysqli/tests/065.phpt +++ b/ext/mysqli/tests/065.phpt @@ -6,6 +6,9 @@ require_once('skipif.inc'); if (!function_exists('mysqli_set_charset')) { die('skip mysqli_set_charset() not available'); } +if (unicode_semantics()) { + die('skip set character set not functional with unicode.semantics=On'); +} ?> --FILE-- <?php diff --git a/ext/mysqli/tests/069.phpt b/ext/mysqli/tests/069.phpt index d5110d02bf..49502513ed 100644 --- a/ext/mysqli/tests/069.phpt +++ b/ext/mysqli/tests/069.phpt @@ -22,13 +22,13 @@ mysqli multi_query, next_result, more_results } while ($mysql->next_result()); $mysql->close(); ?> ---EXPECT-- +--EXPECTF-- array(1) { [1]=> - string(1) "1" + %s(1) "1" } --- array(1) { [2]=> - string(1) "2" + %s(1) "2" } diff --git a/ext/mysqli/tests/072.phpt b/ext/mysqli/tests/072.phpt index 8c85175ea2..b3d847f30e 100644 --- a/ext/mysqli/tests/072.phpt +++ b/ext/mysqli/tests/072.phpt @@ -2,7 +2,6 @@ mysqli warning_count, get_warnings --SKIPIF-- <?php require_once('skipif.inc'); ?> -<?php die('skip mysqli_warning class not functional yet?'); ?> --FILE-- <?php include "connect.inc"; @@ -17,11 +16,12 @@ mysqli warning_count, get_warnings var_dump($w->errno); var_dump($w->message); -# var_dump($w->sqlstate); + var_dump($w->sqlstate); $mysql->close(); ?> --EXPECT-- -1 -1051 -Unknown table 'not_exists'
\ No newline at end of file +int(1) +int(1051) +string(26) "Unknown table 'not_exists'" +string(5) "HY000" diff --git a/ext/mysqli/tests/073.phpt b/ext/mysqli/tests/073.phpt index 5a017a2cb4..e4f9e49768 100644 --- a/ext/mysqli/tests/073.phpt +++ b/ext/mysqli/tests/073.phpt @@ -17,7 +17,7 @@ mysqli_driver properties --EXPECTF-- bool(%s) int(%d) -string(%d) "%s" +%s(%d) "%s" int(%d) bool(%s) int(%d) diff --git a/ext/mysqli/tests/074.phpt b/ext/mysqli/tests/074.phpt index ab407c1ad8..4150e81fe7 100644 --- a/ext/mysqli/tests/074.phpt +++ b/ext/mysqli/tests/074.phpt @@ -20,14 +20,14 @@ $result = $mysqli->query("SELECT @@autocommit"); var_dump($result->fetch_row()); ?> ---EXPECT-- +--EXPECTF-- bool(true) array(1) { [0]=> - string(1) "0" + %s(1) "0" } bool(true) array(1) { [0]=> - string(1) "1" + %s(1) "1" } diff --git a/ext/mysqli/tests/bug28817.phpt b/ext/mysqli/tests/bug28817.phpt index 0cc8b13612..c5398a09da 100644 --- a/ext/mysqli/tests/bug28817.phpt +++ b/ext/mysqli/tests/bug28817.phpt @@ -31,9 +31,9 @@ Bug #28817 testcase (properties) --EXPECTF-- array(2) { [0]=> - string(3) "foo" + %s(3) "foo" [1]=> - string(3) "bar" + %s(3) "bar" } NULL bool(true) diff --git a/ext/mysqli/tests/bug31141.phpt b/ext/mysqli/tests/bug31141.phpt index acad79f1f9..9afc9bf9bf 100644 --- a/ext/mysqli/tests/bug31141.phpt +++ b/ext/mysqli/tests/bug31141.phpt @@ -22,7 +22,7 @@ var_dump($my_test->test); --EXPECTF-- array(2) { [0]=> - string(3) "foo" + %s(3) "foo" [1]=> - string(3) "bar" + %s(3) "bar" } diff --git a/ext/mysqli/tests/bug31668.phpt b/ext/mysqli/tests/bug31668.phpt index b813096a2a..14903935cc 100644 --- a/ext/mysqli/tests/bug31668.phpt +++ b/ext/mysqli/tests/bug31668.phpt @@ -36,21 +36,21 @@ Bug #31668 multi_query works exactly every other time (multi_query was global, n --EXPECTF-- array(1) { [1]=> - string(1) "1" + %s(1) "1" } array(1) { [2]=> - string(1) "2" + %s(1) "2" } -string(0) "" +%s(0) "" int(%d) array(1) { [1]=> - string(1) "1" + %s(1) "1" } array(1) { [2]=> - string(1) "2" + %s(1) "2" } -string(0) "" +%s(0) "" int(%d) diff --git a/ext/mysqli/tests/bug32405.phpt b/ext/mysqli/tests/bug32405.phpt index f805dc7982..3ec0c3b970 100644 --- a/ext/mysqli/tests/bug32405.phpt +++ b/ext/mysqli/tests/bug32405.phpt @@ -28,12 +28,12 @@ Bug #32405 mysqli_query($link,"DROP TABLE test_users"); mysqli_close($link); ?> ---EXPECT-- +--EXPECTF-- int(1) -string(5) "user1" +%s(5) "user1" int(2) -string(5) "user2" +%s(5) "user2" int(3) -string(5) "user3" +%s(5) "user3" int(4) -string(5) "user4" +%s(5) "user4" diff --git a/ext/mysqli/tests/bug33263.phpt b/ext/mysqli/tests/bug33263.phpt index 8ccb1e7e53..200294318b 100644 --- a/ext/mysqli/tests/bug33263.phpt +++ b/ext/mysqli/tests/bug33263.phpt @@ -28,5 +28,5 @@ bug #33263 (mysqli_real_connect in __construct) $mysql->close(); ?> ---EXPECT-- -string(4) "test" +--EXPECTF-- +%s(4) "test" diff --git a/ext/mysqli/tests/bug34785.phpt b/ext/mysqli/tests/bug34785.phpt index a2b9f22881..051cc063b3 100644 --- a/ext/mysqli/tests/bug34785.phpt +++ b/ext/mysqli/tests/bug34785.phpt @@ -1,5 +1,5 @@ --TEST-- -Bug #32405 +Bug #34785 --SKIPIF-- <?php require_once('skipif.inc'); ?> --FILE-- @@ -42,6 +42,6 @@ Bug #32405 mysqli_close($link); ?> ---EXPECT-- -string(3) "foo" -string(3) "bar" +--EXPECTF-- +%s(3) "foo" +%s(3) "bar" diff --git a/ext/mysqli/tests/bug35517.phpt b/ext/mysqli/tests/bug35517.phpt index eb1b543463..222c48f780 100644 --- a/ext/mysqli/tests/bug35517.phpt +++ b/ext/mysqli/tests/bug35517.phpt @@ -23,7 +23,7 @@ Bug #35517 mysqli_stmt_fetch returns NULL $mysql->close(); ?> --EXPECTF-- -string(10) "3000000897" -string(10) "3800001532" -string(10) "3900002281" -string(10) "3100059612" +%s(10) "3000000897" +%s(10) "3800001532" +%s(10) "3900002281" +%s(10) "3100059612" diff --git a/ext/mysqli/tests/bug36745.phpt b/ext/mysqli/tests/bug36745.phpt index 868015c450..8188a6fb0a 100644 --- a/ext/mysqli/tests/bug36745.phpt +++ b/ext/mysqli/tests/bug36745.phpt @@ -19,5 +19,5 @@ bug #36745 : LOAD DATA LOCAL INFILE doesn't return correct error message printf("Done"); ?> --EXPECTF-- -string(%d) "%s" +%s(%d) "%s" Done diff --git a/ext/mysqli/tests/connect.inc b/ext/mysqli/tests/connect.inc index b6cea2632b..16462a1bbd 100644 --- a/ext/mysqli/tests/connect.inc +++ b/ext/mysqli/tests/connect.inc @@ -1,24 +1,14 @@ <?php /* default values are localhost, root and empty password - Change the values if you use another configuration */ + Change the MYSQL_TEST environment values if you want to + use another configuration */ $driver = new mysqli_driver; - if (!$driver->embedded) { - $host = "localhost"; - $user = "root"; - $passwd = ""; - } else { - $path = dirname(__FILE__); - $host = $user = $passwd = NULL; - $args = array( - "--datadir=$path", - "--innodb_data_home_dir=$path", - "--innodb_data_file_path=ibdata1:10M:autoextend", - "--log-error=$path/testrun.log", - "--init-connect='CREATE DATABASE IF NOT EXISTS test;'" - ); - $driver->embedded_server_start(TRUE, $args, NULL); - } - + $host = getenv("MYSQL_TEST_HOST") ? getenv("MYSQL_TEST_HOST") : "localhost"; + $port = getenv("MYSQL_TEST_PORT") ? getenv("MYSQL_TEST_PORT") : 3306; + $user = getenv("MYSQL_TEST_USER") ? getenv("MYSQL_TEST_USER") : "root"; + $passwd = getenv("MYSQL_TEST_PASSWD") ? getenv("MYSQL_TEST_PASSWD") : ""; + $db = getenv("MYSQL_TEST_DB") ? getenv("MYSQL_TEST_DB") : "phptest"; + $engine = getenv("MYSQL_TEST_ENGINE") ? getenv("MYSQL_TEST_ENGINE") : "MyISAM"; ?> diff --git a/ext/mysqli/tests/skipif.inc b/ext/mysqli/tests/skipif.inc index f471b5e126..e6b71cbd5d 100644 --- a/ext/mysqli/tests/skipif.inc +++ b/ext/mysqli/tests/skipif.inc @@ -3,8 +3,7 @@ if (!extension_loaded('mysqli')){ die('skip mysqli extension not available'); } include "connect.inc"; -$driver = new mysqli_driver(); -if (!$driver->embedded && !@mysqli_connect($host, $user, $passwd, "", 3306)) { +if (!@mysqli_connect($host, $user, $passwd, "", 3306)) { die('skip could not connect to MySQL'); } ?> |