Skip to content

Commit dcc8463

Browse files
committed
Deprecate IAP functions on objects
Deprecate use of key(), current(), next(), prev(), reset() and end() on objects. Cast the object to array first. Part of https://wiki.php.net/rfc/deprecations_php_8_1.
1 parent 5bb83b3 commit dcc8463

File tree

4 files changed

+78
-13
lines changed

4 files changed

+78
-13
lines changed

UPGRADING

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,12 @@ PHP 8.1 UPGRADE NOTES
350350
. The PDO::FETCH_SERIALIZE mode has been deprecated.
351351
RFC: https://wiki.php.net/rfc/phase_out_serializable
352352

353+
- Standard:
354+
. Calling key(), current(), next(), prev(), reset(), or end() on objects
355+
is deprecated. Instead cast the object to array first, or make use of
356+
ArrayIterator.
357+
RFC: https://wiki.php.net/rfc/deprecations_php_8_1
358+
353359
========================================
354360
5. Changed Functions
355361
========================================

Zend/tests/bug71266.phpt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ $obj = (object) $arr;
1616
next($obj);
1717
var_dump(current($arr));
1818
?>
19-
--EXPECT--
19+
--EXPECTF--
2020
int(1)
2121
int(42)
22+
23+
Deprecated: next(): Calling next() on an object is deprecated in %s on line %d
2224
int(1)
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
--TEST--
2+
Using IAP functions on objects is deprecated
3+
--FILE--
4+
<?php
5+
6+
$obj = (object)['a' => 'b'];
7+
var_dump(reset($obj));
8+
var_dump(current($obj));
9+
var_dump(key($obj));
10+
var_dump(next($obj));
11+
var_dump(end($obj));
12+
var_dump(prev($obj));
13+
14+
?>
15+
--EXPECTF--
16+
Deprecated: reset(): Calling reset() on an object is deprecated in %s on line %d
17+
string(1) "b"
18+
19+
Deprecated: current(): Calling current() on an object is deprecated in %s on line %d
20+
string(1) "b"
21+
22+
Deprecated: key(): Calling key() on an object is deprecated in %s on line %d
23+
string(1) "a"
24+
25+
Deprecated: next(): Calling next() on an object is deprecated in %s on line %d
26+
bool(false)
27+
28+
Deprecated: end(): Calling end() on an object is deprecated in %s on line %d
29+
string(1) "b"
30+
31+
Deprecated: prev(): Calling prev() on an object is deprecated in %s on line %d
32+
bool(false)

ext/standard/array.c

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,16 +1041,36 @@ PHP_FUNCTION(uksort)
10411041
}
10421042
/* }}} */
10431043

1044+
static inline HashTable *get_ht_for_iap(zval *zv, bool separate) {
1045+
if (EXPECTED(Z_TYPE_P(zv) == IS_ARRAY)) {
1046+
return Z_ARRVAL_P(zv);
1047+
}
1048+
1049+
ZEND_ASSERT(Z_TYPE_P(zv) == IS_OBJECT);
1050+
php_error_docref(NULL, E_DEPRECATED,
1051+
"Calling %s() on an object is deprecated", get_active_function_name());
1052+
1053+
zend_object *zobj = Z_OBJ_P(zv);
1054+
if (separate && zobj->properties && UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
1055+
if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
1056+
GC_DELREF(zobj->properties);
1057+
}
1058+
zobj->properties = zend_array_dup(zobj->properties);
1059+
}
1060+
return zobj->handlers->get_properties(zobj);
1061+
}
1062+
10441063
/* {{{ Advances array argument's internal pointer to the last element and return it */
10451064
PHP_FUNCTION(end)
10461065
{
1047-
HashTable *array;
1066+
zval *array_zv;
10481067
zval *entry;
10491068

10501069
ZEND_PARSE_PARAMETERS_START(1, 1)
1051-
Z_PARAM_ARRAY_OR_OBJECT_HT_EX(array, 0, 1)
1070+
Z_PARAM_ARRAY_OR_OBJECT_EX(array_zv, 0, 1)
10521071
ZEND_PARSE_PARAMETERS_END();
10531072

1073+
HashTable *array = get_ht_for_iap(array_zv, /* separate */ true);
10541074
zend_hash_internal_pointer_end(array);
10551075

10561076
if (USED_RET()) {
@@ -1070,13 +1090,14 @@ PHP_FUNCTION(end)
10701090
/* {{{ Move array argument's internal pointer to the previous element and return it */
10711091
PHP_FUNCTION(prev)
10721092
{
1073-
HashTable *array;
1093+
zval *array_zv;
10741094
zval *entry;
10751095

10761096
ZEND_PARSE_PARAMETERS_START(1, 1)
1077-
Z_PARAM_ARRAY_OR_OBJECT_HT_EX(array, 0, 1)
1097+
Z_PARAM_ARRAY_OR_OBJECT_EX(array_zv, 0, 1)
10781098
ZEND_PARSE_PARAMETERS_END();
10791099

1100+
HashTable *array = get_ht_for_iap(array_zv, /* separate */ true);
10801101
zend_hash_move_backwards(array);
10811102

10821103
if (USED_RET()) {
@@ -1096,13 +1117,14 @@ PHP_FUNCTION(prev)
10961117
/* {{{ Move array argument's internal pointer to the next element and return it */
10971118
PHP_FUNCTION(next)
10981119
{
1099-
HashTable *array;
1120+
zval *array_zv;
11001121
zval *entry;
11011122

11021123
ZEND_PARSE_PARAMETERS_START(1, 1)
1103-
Z_PARAM_ARRAY_OR_OBJECT_HT_EX(array, 0, 1)
1124+
Z_PARAM_ARRAY_OR_OBJECT_EX(array_zv, 0, 1)
11041125
ZEND_PARSE_PARAMETERS_END();
11051126

1127+
HashTable *array = get_ht_for_iap(array_zv, /* separate */ true);
11061128
zend_hash_move_forward(array);
11071129

11081130
if (USED_RET()) {
@@ -1122,13 +1144,14 @@ PHP_FUNCTION(next)
11221144
/* {{{ Set array argument's internal pointer to the first element and return it */
11231145
PHP_FUNCTION(reset)
11241146
{
1125-
HashTable *array;
1147+
zval *array_zv;
11261148
zval *entry;
11271149

11281150
ZEND_PARSE_PARAMETERS_START(1, 1)
1129-
Z_PARAM_ARRAY_OR_OBJECT_HT_EX(array, 0, 1)
1151+
Z_PARAM_ARRAY_OR_OBJECT_EX(array_zv, 0, 1)
11301152
ZEND_PARSE_PARAMETERS_END();
11311153

1154+
HashTable *array = get_ht_for_iap(array_zv, /* separate */ true);
11321155
zend_hash_internal_pointer_reset(array);
11331156

11341157
if (USED_RET()) {
@@ -1148,13 +1171,14 @@ PHP_FUNCTION(reset)
11481171
/* {{{ Return the element currently pointed to by the internal array pointer */
11491172
PHP_FUNCTION(current)
11501173
{
1151-
HashTable *array;
1174+
zval *array_zv;
11521175
zval *entry;
11531176

11541177
ZEND_PARSE_PARAMETERS_START(1, 1)
1155-
Z_PARAM_ARRAY_OR_OBJECT_HT(array)
1178+
Z_PARAM_ARRAY_OR_OBJECT(array_zv)
11561179
ZEND_PARSE_PARAMETERS_END();
11571180

1181+
HashTable *array = get_ht_for_iap(array_zv, /* separate */ false);
11581182
if ((entry = zend_hash_get_current_data(array)) == NULL) {
11591183
RETURN_FALSE;
11601184
}
@@ -1170,12 +1194,13 @@ PHP_FUNCTION(current)
11701194
/* {{{ Return the key of the element currently pointed to by the internal array pointer */
11711195
PHP_FUNCTION(key)
11721196
{
1173-
HashTable *array;
1197+
zval *array_zv;
11741198

11751199
ZEND_PARSE_PARAMETERS_START(1, 1)
1176-
Z_PARAM_ARRAY_OR_OBJECT_HT(array)
1200+
Z_PARAM_ARRAY_OR_OBJECT(array_zv)
11771201
ZEND_PARSE_PARAMETERS_END();
11781202

1203+
HashTable *array = get_ht_for_iap(array_zv, /* separate */ false);
11791204
zend_hash_get_current_key_zval(array, return_value);
11801205
}
11811206
/* }}} */

0 commit comments

Comments
 (0)