Skip to content

Commit d7a16bf

Browse files
committed
Merge branch 'PHP-8.0'
* PHP-8.0: Fix default value handling of mysqli_fetch_object()
2 parents 11a2419 + d5f92ba commit d7a16bf

10 files changed

+32
-45
lines changed

ext/mysqli/mysqli.c

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,16 +1200,9 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags
12001200
fci.param_count = 0;
12011201
fci.named_params = NULL;
12021202

1203-
if (ctor_params && Z_TYPE_P(ctor_params) != IS_NULL) {
1203+
if (ctor_params) {
12041204
if (zend_fcall_info_args(&fci, ctor_params) == FAILURE) {
1205-
/* Two problems why we throw exceptions here: PHP is typeless
1206-
* and hence passing one argument that's not an array could be
1207-
* by mistake and the other way round is possible, too. The
1208-
* single value is an array. Also we'd have to make that one
1209-
* argument passed by reference.
1210-
*/
1211-
zend_argument_error(zend_ce_exception, 3, "must be of type array, %s given", zend_zval_type_name(ctor_params));
1212-
RETURN_THROWS();
1205+
ZEND_UNREACHABLE();
12131206
}
12141207
}
12151208

@@ -1223,8 +1216,11 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags
12231216
zval_ptr_dtor(&retval);
12241217
}
12251218
zend_fcall_info_args_clear(&fci, 1);
1226-
} else if (ctor_params) {
1227-
zend_throw_exception_ex(zend_ce_exception, 0, "Class %s does not have a constructor hence you cannot use ctor_params", ZSTR_VAL(ce->name));
1219+
} else if (ctor_params && zend_hash_num_elements(Z_ARRVAL_P(ctor_params)) > 0) {
1220+
zend_argument_error(zend_ce_exception, ERROR_ARG_POS(3),
1221+
"must be empty when the specified class (%s) does not have a constructor",
1222+
ZSTR_VAL(ce->name)
1223+
);
12281224
}
12291225
}
12301226
}

ext/mysqli/mysqli.stub.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ public function fetch_assoc() {}
364364
* @return object|null
365365
* @alias mysqli_fetch_object
366366
*/
367-
public function fetch_object(string $class = "stdClass", array $params = []) {}
367+
public function fetch_object(string $class = "stdClass", array $constructor_args = []) {}
368368

369369
/**
370370
* @return array|null
@@ -581,7 +581,7 @@ function mysqli_fetch_array(mysqli_result $result, int $mode = MYSQLI_BOTH): arr
581581

582582
function mysqli_fetch_assoc(mysqli_result $result): ?array {}
583583

584-
function mysqli_fetch_object(mysqli_result $result, string $class = "stdClass", array $params = []): ?object {}
584+
function mysqli_fetch_object(mysqli_result $result, string $class = "stdClass", array $constructor_args = []): ?object {}
585585

586586
function mysqli_fetch_row(mysqli_result $result): ?array {}
587587

ext/mysqli/mysqli_arginfo.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 88f90ff45ab8f9748968c39eae950d58e598b73f */
2+
* Stub hash: 480939b71e1dacbdbb4634dbabf375943e399b6f */
33

44
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mysqli_affected_rows, 0, 1, MAY_BE_LONG|MAY_BE_STRING)
55
ZEND_ARG_OBJ_INFO(0, mysql, mysqli, 0)
@@ -115,7 +115,7 @@ ZEND_END_ARG_INFO()
115115
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_mysqli_fetch_object, 0, 1, IS_OBJECT, 1)
116116
ZEND_ARG_OBJ_INFO(0, result, mysqli_result, 0)
117117
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, class, IS_STRING, 0, "\"stdClass\"")
118-
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, params, IS_ARRAY, 0, "[]")
118+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, constructor_args, IS_ARRAY, 0, "[]")
119119
ZEND_END_ARG_INFO()
120120

121121
#define arginfo_mysqli_fetch_row arginfo_mysqli_fetch_assoc
@@ -614,7 +614,7 @@ ZEND_END_ARG_INFO()
614614

615615
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_result_fetch_object, 0, 0, 0)
616616
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, class, IS_STRING, 0, "\"stdClass\"")
617-
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, params, IS_ARRAY, 0, "[]")
617+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, constructor_args, IS_ARRAY, 0, "[]")
618618
ZEND_END_ARG_INFO()
619619

620620
#define arginfo_class_mysqli_result_fetch_row arginfo_class_mysqli_character_set_name

ext/mysqli/tests/mysqli_fetch_object.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,6 @@ Exception: Too few arguments to function mysqli_fetch_object_construct::__constr
147147
NULL
148148
NULL
149149
mysqli_result object is already closed
150-
[0] mysqli_fetch_object(): Argument #3 ($params) must be of type array, string given in %s on line %d
150+
[0] mysqli_fetch_object(): Argument #3 ($constructor_args) must be of type array, string given in %s on line %d
151151
mysqli_fetch_object(): Argument #2 ($class) must be a valid class name, this_class_does_not_exist given
152152
done!

ext/mysqli/tests/mysqli_fetch_object_no_constructor.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ object(mysqli_fetch_object_test)#%d (%d) {
5757
}
5858

5959
Exception with mysqli. Note that at all other places we throws errors but no exceptions unless the error mode has been changed:
60-
Exception: Class mysqli_fetch_object_test does not have a constructor hence you cannot use ctor_params
60+
Exception: mysqli_fetch_object(): Argument #3 ($constructor_args) must be empty when the specified class (mysqli_fetch_object_test) does not have a constructor
6161

6262
Fatal error with PHP (but no exception!):
6363

ext/mysqli/tests/mysqli_fetch_object_oo.phpt

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,9 @@ require_once('skipifconnectfailure.inc');
7373
}
7474

7575
try {
76-
$obj = $res->fetch_object('mysqli_fetch_object_construct', null);
77-
78-
if (($obj->ID !== "3") || ($obj->label !== "c") || ($obj->a !== NULL) || ($obj->b !== NULL) || (get_class($obj) != 'mysqli_fetch_object_construct')) {
79-
printf("[009] Object seems wrong. [%d] %s\n", $mysqli->errno, $mysqli->error);
80-
var_dump($obj);
81-
}
82-
} catch (Error $e) {
83-
handle_catchable_fatal($e->getCode(), $e->getMessage(), $e->getFile(), $e->getLine());
76+
$res->fetch_object('mysqli_fetch_object_construct', null);
77+
} catch (TypeError $exception) {
78+
echo $exception->getMessage() . "\n";
8479
mysqli_fetch_object($res);
8580
}
8681

@@ -134,7 +129,7 @@ require_once('skipifconnectfailure.inc');
134129
mysqli object is not fully initialized
135130
[0] Object of class mysqli could not be converted to string in %s on line %d
136131
[0] mysqli_result::fetch_object() expects at most 2 arguments, 3 given in %s on line %d
137-
[0] mysqli_result::fetch_object(): Argument #2 ($params) must be of type array, null given in %s on line %d
132+
mysqli_result::fetch_object(): Argument #2 ($constructor_args) must be of type array, null given
138133
Exception: Too few arguments to function mysqli_fetch_object_construct::__construct(), 1 passed and exactly 2 expected
139134
NULL
140135
NULL

ext/pdo/pdo_dbh.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ PHP_METHOD(PDO, prepare)
517517
}
518518
if ((item = zend_hash_index_find(Z_ARRVAL_P(value), 0)) == NULL) {
519519
zend_value_error("PDO::ATTR_STATEMENT_CLASS value must be an array with the format "
520-
"array(classname, array(ctor_args))");
520+
"array(classname, constructor_args)");
521521
RETURN_THROWS();
522522
}
523523
if (Z_TYPE_P(item) != IS_STRING || (pce = zend_lookup_class(Z_STR_P(item))) == NULL) {
@@ -535,7 +535,7 @@ PHP_METHOD(PDO, prepare)
535535
}
536536
if ((item = zend_hash_index_find(Z_ARRVAL_P(value), 1)) != NULL) {
537537
if (Z_TYPE_P(item) != IS_ARRAY) {
538-
zend_type_error("PDO::ATTR_STATEMENT_CLASS ctor_args must be of type ?array, %s given",
538+
zend_type_error("PDO::ATTR_STATEMENT_CLASS constructor_args must be of type ?array, %s given",
539539
zend_zval_type_name(value));
540540
RETURN_THROWS();
541541
}
@@ -765,7 +765,7 @@ static zend_result pdo_dbh_attribute_set(pdo_dbh_t *dbh, zend_long attr, zval *v
765765
}
766766
if ((item = zend_hash_index_find(Z_ARRVAL_P(value), 0)) == NULL) {
767767
zend_value_error("PDO::ATTR_STATEMENT_CLASS value must be an array with the format "
768-
"array(classname, array(ctor_args))");
768+
"array(classname, constructor_args)");
769769
return FAILURE;
770770
}
771771
if (Z_TYPE_P(item) != IS_STRING || (pce = zend_lookup_class(Z_STR_P(item))) == NULL) {
@@ -787,7 +787,7 @@ static zend_result pdo_dbh_attribute_set(pdo_dbh_t *dbh, zend_long attr, zval *v
787787
}
788788
if ((item = zend_hash_index_find(Z_ARRVAL_P(value), 1)) != NULL) {
789789
if (Z_TYPE_P(item) != IS_ARRAY) {
790-
zend_type_error("PDO::ATTR_STATEMENT_CLASS ctor_args must be of type ?array, %s given",
790+
zend_type_error("PDO::ATTR_STATEMENT_CLASS constructor_args must be of type ?array, %s given",
791791
zend_zval_type_name(value));
792792
return FAILURE;
793793
}

ext/pgsql/pgsql.c

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1836,7 +1836,7 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, zend_long result_
18361836
zend_class_entry *ce = NULL;
18371837

18381838
if (into_object) {
1839-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l!Ca!", &result, &row, &row_is_null, &ce, &ctor_params) == FAILURE) {
1839+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l!Ca", &result, &row, &row_is_null, &ce, &ctor_params) == FAILURE) {
18401840
RETURN_THROWS();
18411841
}
18421842
if (!ce) {
@@ -1935,14 +1935,7 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, zend_long result_
19351935

19361936
if (ctor_params) {
19371937
if (zend_fcall_info_args(&fci, ctor_params) == FAILURE) {
1938-
/* Two problems why we throw exceptions here: PHP is typeless
1939-
* and hence passing one argument that's not an array could be
1940-
* by mistake and the other way round is possible, too. The
1941-
* single value is an array. Also we'd have to make that one
1942-
* argument passed by reference.
1943-
*/
1944-
zend_throw_exception(zend_ce_exception, "Parameter ctor_params must be an array", 0);
1945-
RETURN_THROWS();
1938+
ZEND_UNREACHABLE();
19461939
}
19471940
}
19481941

@@ -1958,8 +1951,11 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, zend_long result_
19581951
if (fci.params) {
19591952
efree(fci.params);
19601953
}
1961-
} else if (ctor_params) {
1962-
zend_throw_exception_ex(zend_ce_exception, 0, "Class %s does not have a constructor hence you cannot use ctor_params", ZSTR_VAL(ce->name));
1954+
} else if (ctor_params && zend_hash_num_elements(Z_ARRVAL_P(ctor_params)) > 0) {
1955+
zend_argument_error(zend_ce_exception, 3,
1956+
"must be empty when the specified class (%s) does not have a constructor",
1957+
ZSTR_VAL(ce->name)
1958+
);
19631959
}
19641960
}
19651961
}

ext/pgsql/pgsql.stub.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ function pg_fetch_assoc($result, ?int $row = null): array|false {}
190190
function pg_fetch_array($result, ?int $row = null, int $mode = PGSQL_BOTH): array|false {}
191191

192192
/** @param resource $result */
193-
function pg_fetch_object($result, ?int $row = null, string $class = "stdClass", ?array $ctor_args = null): object|false {}
193+
function pg_fetch_object($result, ?int $row = null, string $class = "stdClass", array $constructor_args = []): object|false {}
194194

195195
/** @param resource $result */
196196
function pg_fetch_all($result, int $mode = PGSQL_ASSOC): array {}

ext/pgsql/pgsql_arginfo.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 26edbb4ade84f0faad592dd270756c17e396519b */
2+
* Stub hash: de1718d3e6e66dfade25462b8461983b914120ed */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_connect, 0, 0, 1)
55
ZEND_ARG_TYPE_INFO(0, connection_string, IS_STRING, 0)
@@ -152,7 +152,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_fetch_object, 0, 1, MAY_BE_OB
152152
ZEND_ARG_INFO(0, result)
153153
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, row, IS_LONG, 1, "null")
154154
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, class, IS_STRING, 0, "\"stdClass\"")
155-
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, ctor_args, IS_ARRAY, 1, "null")
155+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, constructor_args, IS_ARRAY, 0, "[]")
156156
ZEND_END_ARG_INFO()
157157

158158
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_fetch_all, 0, 1, IS_ARRAY, 0)

0 commit comments

Comments
 (0)