[php-src] master: mysqli: move behaviour existing only for mysqli_fetch_object() into it (#23451)

Gina Peter Banyard via GitHub <[email protected]>
Newsgroups gmane.comp.php.cvs.general
Message-ID <[email protected]>
Author: Gina Peter Banyard (Girgias)
Committer: GitHub (web-flow)
Pusher: kamil-tekiela
Date: 2026-08-25T22:51:37+01:00

Commit: https://github.com/php/php-src/commit/045d005f80934d4a122145d1afef767f7b5039e5
Raw diff: https://github.com/php/php-src/commit/045d005f80934d4a122145d1afef767f7b5039e5.diff

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

Changed paths:
  M  ext/mysqli/mysqli.c
  M  ext/mysqli/mysqli_api.c
  M  ext/mysqli/mysqli_nonapi.c
  M  ext/mysqli/mysqli_priv.h


Diff:

diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c
index 2f1fa1c21c55..e6f876433571 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 526fd10b2623..e55083d940cf 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 1e46aeedd93b..1b973f405497 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 97d9300a2b79..32602ef94989 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);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.