From 4f2f33cf249878968051ecc0749a4b09abc6ac8d Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Tue, 25 Aug 2026 13:07:46 +0100 Subject: [PATCH] mysqli: move behaviour existing only for mysqli_fetch_object() into it The shared function is effectively ignored for mysqli_fetch_object() so just move the relevant behaviour and simplify the common implementation --- ext/mysqli/mysqli.c | 64 +++++++------------------------------- ext/mysqli/mysqli_api.c | 2 +- ext/mysqli/mysqli_nonapi.c | 51 ++++++++++++++++++++++++++++-- ext/mysqli/mysqli_priv.h | 2 +- 4 files changed, 61 insertions(+), 58 deletions(-) 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);