Commit 045d005f809 for php.net
commit 045d005f80934d4a122145d1afef767f7b5039e5
Author: Gina Peter Banyard <girgias@php.net>
Date: Tue Aug 25 22:51:37 2026 +0100
mysqli: move behaviour existing only for mysqli_fetch_object() into it (#23451)
The shared function is effectively ignored for mysqli_fetch_object() so just move the relevant behaviour and simplify the common implementation
diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c
index 2f1fa1c21c5..e6f87643357 100644
--- a/ext/mysqli/mysqli.c
+++ b/ext/mysqli/mysqli.c
@@ -747,72 +747,30 @@ void php_mysqli_fetch_into_hash_aux(zval *return_value, MYSQL_RES * result, zend
/* TODO Split this up */
/* {{{ php_mysqli_fetch_into_hash */
-void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags, int into_object)
+void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags)
{
MYSQL_RES *result;
zval *mysql_result;
zend_long fetchtype;
- HashTable *ctor_params = NULL;
- zend_class_entry *ce = NULL;
- if (into_object) {
- if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|Ch", &mysql_result, mysqli_result_class_entry, &ce, &ctor_params) == FAILURE) {
+ if (override_flags) {
+ ZEND_ASSERT(override_flags >= MYSQLI_ASSOC && override_flags <= MYSQLI_BOTH);
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
RETURN_THROWS();
}
- if (ce == NULL) {
- ce = zend_standard_class_def;
- }
- if (UNEXPECTED(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) {
- zend_throw_error(NULL, "Class %s cannot be instantiated", ZSTR_VAL(ce->name));
+ fetchtype = override_flags;
+ } else {
+ fetchtype = MYSQLI_BOTH;
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|l", &mysql_result, mysqli_result_class_entry, &fetchtype) == FAILURE) {
RETURN_THROWS();
}
- fetchtype = MYSQLI_ASSOC;
- } else {
- if (override_flags) {
- if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
- RETURN_THROWS();
- }
- fetchtype = override_flags;
- } else {
- fetchtype = MYSQLI_BOTH;
- if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|l", &mysql_result, mysqli_result_class_entry, &fetchtype) == FAILURE) {
- RETURN_THROWS();
- }
+ if (fetchtype < MYSQLI_ASSOC || fetchtype > MYSQLI_BOTH) {
+ zend_argument_value_error(ERROR_ARG_POS(2), "must be one of MYSQLI_NUM, MYSQLI_ASSOC, or MYSQLI_BOTH");
+ RETURN_THROWS();
}
}
MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, MYSQLI_STATUS_VALID);
- if (fetchtype < MYSQLI_ASSOC || fetchtype > MYSQLI_BOTH) {
- zend_argument_value_error(ERROR_ARG_POS(2), "must be one of MYSQLI_NUM, MYSQLI_ASSOC, or MYSQLI_BOTH");
- RETURN_THROWS();
- }
-
php_mysqli_fetch_into_hash_aux(return_value, result, fetchtype);
-
- if (into_object && Z_TYPE_P(return_value) == IS_ARRAY) {
- zval dataset;
-
- ZVAL_COPY_VALUE(&dataset, return_value);
-
- object_init_ex(return_value, ce);
- HashTable *prop_table = zend_symtable_to_proptable(Z_ARR(dataset));
- zval_ptr_dtor(&dataset);
- if (!ce->default_properties_count && !ce->__set) {
- Z_OBJ_P(return_value)->properties = prop_table;
- } else {
- zend_merge_properties(return_value, prop_table);
- zend_array_release(prop_table);
- }
-
- if (ce->constructor) {
- zend_call_known_function(ce->constructor, Z_OBJ_P(return_value), Z_OBJCE_P(return_value),
- /* retval */ NULL, /* argc */ 0, /* params */ NULL, ctor_params);
- } else if (ctor_params && zend_hash_num_elements(ctor_params) > 0) {
- zend_argument_value_error(ERROR_ARG_POS(3),
- "must be empty when the specified class (%s) does not have a constructor",
- ZSTR_VAL(ce->name)
- );
- }
- }
}
/* }}} */
diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c
index 526fd10b262..e55083d940c 100644
--- a/ext/mysqli/mysqli_api.c
+++ b/ext/mysqli/mysqli_api.c
@@ -780,7 +780,7 @@ PHP_FUNCTION(mysqli_fetch_lengths)
/* {{{ Get a result row as an enumerated array */
PHP_FUNCTION(mysqli_fetch_row)
{
- php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_NUM, 0);
+ php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_NUM);
}
/* }}} */
diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c
index 1e46aeedd93..1b973f40549 100644
--- a/ext/mysqli/mysqli_nonapi.c
+++ b/ext/mysqli/mysqli_nonapi.c
@@ -363,14 +363,14 @@ PHP_FUNCTION(mysqli_connect_error)
/* {{{ Fetch a result row as an associative array, a numeric array, or both */
PHP_FUNCTION(mysqli_fetch_array)
{
- php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 0);
+ php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
}
/* }}} */
/* {{{ Fetch a result row as an associative array */
PHP_FUNCTION(mysqli_fetch_assoc)
{
- php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_ASSOC, 0);
+ php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_ASSOC);
}
/* }}} */
@@ -525,7 +525,52 @@ PHP_FUNCTION(mysqli_stmt_error_list)
/* {{{ Fetch a result row as an object */
PHP_FUNCTION(mysqli_fetch_object)
{
- php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_ASSOC, 1);
+ zval *mysql_result;
+ zend_class_entry *ce = NULL;
+ HashTable *ctor_params = NULL;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|Ch", &mysql_result, mysqli_result_class_entry, &ce, &ctor_params) == FAILURE) {
+ RETURN_THROWS();
+ }
+ if (ce == NULL) {
+ ce = zend_standard_class_def;
+ }
+ if (UNEXPECTED(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) {
+ zend_throw_error(NULL, "Class %s cannot be instantiated", ZSTR_VAL(ce->name));
+ RETURN_THROWS();
+ }
+ if (!ce->constructor && ctor_params && zend_hash_num_elements(ctor_params) > 0) {
+ zend_argument_value_error(ERROR_ARG_POS(3),
+ "must be empty when the specified class (%s) does not have a constructor",
+ ZSTR_VAL(ce->name)
+ );
+ RETURN_THROWS();
+ }
+
+ MYSQL_RES *result;
+ MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, MYSQLI_STATUS_VALID);
+
+ zval dataset;
+ php_mysqli_fetch_into_hash_aux(&dataset, result, MYSQLI_ASSOC);
+
+ if (Z_TYPE(dataset) == IS_ARRAY) {
+ object_init_ex(return_value, ce);
+ HashTable *prop_table = zend_symtable_to_proptable(Z_ARR(dataset));
+ zval_ptr_dtor(&dataset);
+ if (!ce->default_properties_count && !ce->__set) {
+ Z_OBJ_P(return_value)->properties = prop_table;
+ } else {
+ zend_merge_properties(return_value, prop_table);
+ zend_array_release(prop_table);
+ }
+
+ if (ce->constructor) {
+ zend_call_known_function(ce->constructor, Z_OBJ_P(return_value), Z_OBJCE_P(return_value),
+ /* retval */ NULL, /* argc */ 0, /* params */ NULL, ctor_params);
+ }
+ } else {
+ RETURN_COPY_VALUE(&dataset);
+ }
}
/* }}} */
diff --git a/ext/mysqli/mysqli_priv.h b/ext/mysqli/mysqli_priv.h
index 97d9300a2b7..32602ef9498 100644
--- a/ext/mysqli/mysqli_priv.h
+++ b/ext/mysqli/mysqli_priv.h
@@ -47,7 +47,7 @@ extern void php_mysqli_dtor_p_elements(void *data);
extern void php_mysqli_close(MY_MYSQL * mysql, int close_type, int resource_status);
-extern void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flag, int into_object);
+extern void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flag);
extern void php_clear_stmt_bind(MY_STMT *stmt);
extern void php_clear_mysql(MY_MYSQL *);
extern MYSQLI_WARNING *php_get_warnings(MYSQLND_CONN_DATA * mysql);