Skip to content

Commit c46b2ed

Browse files
committed
Remove support for array_key_exists() with objects
1 parent 31f1254 commit c46b2ed

12 files changed

+65
-292
lines changed

UPGRADING

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ PHP 8.0 UPGRADE NOTES
4141
method, using Closure::fromCallable() or ReflectionMethod::getClosure().
4242
. Also removed ability to unbind $this from proper closures that contain uses
4343
of $this.
44+
. Removed ability to use array_key_exists() with objects. Use one of isset()
45+
or property_exists() instead.
4446
. Any array that has a number n as its first numeric key will use n+1 for
4547
its next implicit key. Even if n is negative.
4648
RFC: https://wiki.php.net/rfc/negative_array_index

Zend/zend_execute.c

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2458,7 +2458,7 @@ static zend_never_inline int ZEND_FASTCALL zend_isempty_dim_slow(zval *container
24582458
}
24592459
}
24602460

2461-
static zend_never_inline uint32_t ZEND_FASTCALL zend_array_key_exists_fast(HashTable *ht, zval *key OPLINE_DC EXECUTE_DATA_DC)
2461+
static zend_never_inline zend_bool ZEND_FASTCALL zend_array_key_exists_fast(HashTable *ht, zval *key OPLINE_DC EXECUTE_DATA_DC)
24622462
{
24632463
zend_string *str;
24642464
zend_ulong hval;
@@ -2470,11 +2470,11 @@ static zend_never_inline uint32_t ZEND_FASTCALL zend_array_key_exists_fast(HashT
24702470
goto num_key;
24712471
}
24722472
str_key:
2473-
return zend_hash_find_ind(ht, str) != NULL ? IS_TRUE : IS_FALSE;
2473+
return zend_hash_find_ind(ht, str) != NULL;
24742474
} else if (EXPECTED(Z_TYPE_P(key) == IS_LONG)) {
24752475
hval = Z_LVAL_P(key);
24762476
num_key:
2477-
return zend_hash_index_find(ht, hval) != NULL ? IS_TRUE : IS_FALSE;
2477+
return zend_hash_index_find(ht, hval) != NULL;
24782478
} else if (EXPECTED(Z_ISREF_P(key))) {
24792479
key = Z_REFVAL_P(key);
24802480
goto try_again;
@@ -2486,30 +2486,22 @@ static zend_never_inline uint32_t ZEND_FASTCALL zend_array_key_exists_fast(HashT
24862486
goto str_key;
24872487
} else {
24882488
zend_error(E_WARNING, "array_key_exists(): The first argument should be either a string or an integer");
2489-
return IS_FALSE;
2489+
return 0;
24902490
}
24912491
}
24922492

2493-
static zend_never_inline uint32_t ZEND_FASTCALL zend_array_key_exists_slow(zval *subject, zval *key OPLINE_DC EXECUTE_DATA_DC)
2493+
static ZEND_COLD void ZEND_FASTCALL zend_array_key_exists_error(
2494+
zval *subject, zval *key OPLINE_DC EXECUTE_DATA_DC)
24942495
{
2495-
if (EXPECTED(Z_TYPE_P(subject) == IS_OBJECT)) {
2496-
zend_error(E_DEPRECATED, "array_key_exists(): "
2497-
"Using array_key_exists() on objects is deprecated. "
2498-
"Use isset() or property_exists() instead");
2499-
2500-
HashTable *ht = zend_get_properties_for(subject, ZEND_PROP_PURPOSE_ARRAY_CAST);
2501-
uint32_t result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC);
2502-
zend_release_properties(ht);
2503-
return result;
2504-
} else {
2505-
if (UNEXPECTED(Z_TYPE_P(key) == IS_UNDEF)) {
2506-
ZVAL_UNDEFINED_OP1();
2507-
}
2508-
if (UNEXPECTED(Z_TYPE_INFO_P(subject) == IS_UNDEF)) {
2509-
ZVAL_UNDEFINED_OP2();
2510-
}
2511-
zend_type_error("array_key_exists() expects parameter 2 to be array, %s given", zend_get_type_by_const(Z_TYPE_P(subject)));
2512-
return IS_NULL;
2496+
if (Z_TYPE_P(key) == IS_UNDEF) {
2497+
ZVAL_UNDEFINED_OP1();
2498+
}
2499+
if (Z_TYPE_P(subject) == IS_UNDEF) {
2500+
ZVAL_UNDEFINED_OP2();
2501+
}
2502+
if (!EG(exception)) {
2503+
zend_type_error("array_key_exists() expects parameter 2 to be array, %s given",
2504+
zend_get_type_by_const(Z_TYPE_P(subject)));
25132505
}
25142506
}
25152507

Zend/zend_object_handlers.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1841,7 +1841,6 @@ ZEND_API HashTable *zend_std_get_properties_for(zend_object *obj, zend_prop_purp
18411841
case ZEND_PROP_PURPOSE_SERIALIZE:
18421842
case ZEND_PROP_PURPOSE_VAR_EXPORT:
18431843
case ZEND_PROP_PURPOSE_JSON:
1844-
case _ZEND_PROP_PURPOSE_ARRAY_KEY_EXISTS:
18451844
ht = obj->handlers->get_properties(obj);
18461845
if (ht && !(GC_FLAGS(ht) & GC_IMMUTABLE)) {
18471846
GC_ADDREF(ht);

Zend/zend_object_handlers.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,6 @@ typedef enum _zend_prop_purpose {
9898
ZEND_PROP_PURPOSE_VAR_EXPORT,
9999
/* Used for json_encode(). */
100100
ZEND_PROP_PURPOSE_JSON,
101-
/* array_key_exists(). Not intended for general use! */
102-
_ZEND_PROP_PURPOSE_ARRAY_KEY_EXISTS,
103101
/* Dummy member to ensure that "default" is specified. */
104102
_ZEND_PROP_PURPOSE_NON_EXHAUSTIVE_ENUM
105103
} zend_prop_purpose;

Zend/zend_vm_def.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6771,7 +6771,7 @@ ZEND_VM_HANDLER(194, ZEND_ARRAY_KEY_EXISTS, CV|TMPVAR|CONST, CV|TMPVAR|CONST)
67716771

67726772
zval *key, *subject;
67736773
HashTable *ht;
6774-
uint32_t result;
6774+
zend_bool result;
67756775

67766776
SAVE_OPLINE();
67776777

@@ -6789,12 +6789,13 @@ ZEND_VM_C_LABEL(array_key_exists_array):
67896789
ZEND_VM_C_GOTO(array_key_exists_array);
67906790
}
67916791
}
6792-
result = zend_array_key_exists_slow(subject, key OPLINE_CC EXECUTE_DATA_CC);
6792+
zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC);
6793+
result = 0;
67936794
}
67946795

67956796
FREE_OP2();
67966797
FREE_OP1();
6797-
ZEND_VM_SMART_BRANCH(result == IS_TRUE, 1);
6798+
ZEND_VM_SMART_BRANCH(result, 1);
67986799
}
67996800

68006801
/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */

Zend/zend_vm_execute.h

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6180,7 +6180,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CO
61806180

61816181
zval *key, *subject;
61826182
HashTable *ht;
6183-
uint32_t result;
6183+
zend_bool result;
61846184

61856185
SAVE_OPLINE();
61866186

@@ -6198,11 +6198,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CO
61986198
goto array_key_exists_array;
61996199
}
62006200
}
6201-
result = zend_array_key_exists_slow(subject, key OPLINE_CC EXECUTE_DATA_CC);
6201+
zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC);
6202+
result = 0;
62026203
}
62036204

62046205

6205-
ZEND_VM_SMART_BRANCH(result == IS_TRUE, 1);
6206+
ZEND_VM_SMART_BRANCH(result, 1);
62066207
}
62076208

62086209
/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */
@@ -8281,7 +8282,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TM
82818282

82828283
zval *key, *subject;
82838284
HashTable *ht;
8284-
uint32_t result;
8285+
zend_bool result;
82858286

82868287
SAVE_OPLINE();
82878288

@@ -8299,12 +8300,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TM
82998300
goto array_key_exists_array;
83008301
}
83018302
}
8302-
result = zend_array_key_exists_slow(subject, key OPLINE_CC EXECUTE_DATA_CC);
8303+
zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC);
8304+
result = 0;
83038305
}
83048306

83058307
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
83068308

8307-
ZEND_VM_SMART_BRANCH(result == IS_TRUE, 1);
8309+
ZEND_VM_SMART_BRANCH(result, 1);
83088310
}
83098311

83108312
/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */
@@ -10525,7 +10527,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CV
1052510527

1052610528
zval *key, *subject;
1052710529
HashTable *ht;
10528-
uint32_t result;
10530+
zend_bool result;
1052910531

1053010532
SAVE_OPLINE();
1053110533

@@ -10543,11 +10545,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CV
1054310545
goto array_key_exists_array;
1054410546
}
1054510547
}
10546-
result = zend_array_key_exists_slow(subject, key OPLINE_CC EXECUTE_DATA_CC);
10548+
zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC);
10549+
result = 0;
1054710550
}
1054810551

1054910552

10550-
ZEND_VM_SMART_BRANCH(result == IS_TRUE, 1);
10553+
ZEND_VM_SMART_BRANCH(result, 1);
1055110554
}
1055210555

1055310556
/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */
@@ -14483,7 +14486,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_C
1448314486

1448414487
zval *key, *subject;
1448514488
HashTable *ht;
14486-
uint32_t result;
14489+
zend_bool result;
1448714490

1448814491
SAVE_OPLINE();
1448914492

@@ -14501,11 +14504,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_C
1450114504
goto array_key_exists_array;
1450214505
}
1450314506
}
14504-
result = zend_array_key_exists_slow(subject, key OPLINE_CC EXECUTE_DATA_CC);
14507+
zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC);
14508+
result = 0;
1450514509
}
1450614510

1450714511
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
14508-
ZEND_VM_SMART_BRANCH(result == IS_TRUE, 1);
14512+
ZEND_VM_SMART_BRANCH(result, 1);
1450914513
}
1451014514

1451114515
/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */
@@ -15863,7 +15867,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_T
1586315867

1586415868
zval *key, *subject;
1586515869
HashTable *ht;
15866-
uint32_t result;
15870+
zend_bool result;
1586715871

1586815872
SAVE_OPLINE();
1586915873

@@ -15881,12 +15885,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_T
1588115885
goto array_key_exists_array;
1588215886
}
1588315887
}
15884-
result = zend_array_key_exists_slow(subject, key OPLINE_CC EXECUTE_DATA_CC);
15888+
zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC);
15889+
result = 0;
1588515890
}
1588615891

1588715892
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
1588815893
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
15889-
ZEND_VM_SMART_BRANCH(result == IS_TRUE, 1);
15894+
ZEND_VM_SMART_BRANCH(result, 1);
1589015895
}
1589115896

1589215897
/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */
@@ -17137,7 +17142,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_C
1713717142

1713817143
zval *key, *subject;
1713917144
HashTable *ht;
17140-
uint32_t result;
17145+
zend_bool result;
1714117146

1714217147
SAVE_OPLINE();
1714317148

@@ -17155,11 +17160,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_C
1715517160
goto array_key_exists_array;
1715617161
}
1715717162
}
17158-
result = zend_array_key_exists_slow(subject, key OPLINE_CC EXECUTE_DATA_CC);
17163+
zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC);
17164+
result = 0;
1715917165
}
1716017166

1716117167
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
17162-
ZEND_VM_SMART_BRANCH(result == IS_TRUE, 1);
17168+
ZEND_VM_SMART_BRANCH(result, 1);
1716317169
}
1716417170

1716517171
/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */
@@ -39657,7 +39663,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST
3965739663

3965839664
zval *key, *subject;
3965939665
HashTable *ht;
39660-
uint32_t result;
39666+
zend_bool result;
3966139667

3966239668
SAVE_OPLINE();
3966339669

@@ -39675,11 +39681,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST
3967539681
goto array_key_exists_array;
3967639682
}
3967739683
}
39678-
result = zend_array_key_exists_slow(subject, key OPLINE_CC EXECUTE_DATA_CC);
39684+
zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC);
39685+
result = 0;
3967939686
}
3968039687

3968139688

39682-
ZEND_VM_SMART_BRANCH(result == IS_TRUE, 1);
39689+
ZEND_VM_SMART_BRANCH(result, 1);
3968339690
}
3968439691

3968539692
/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */
@@ -43043,7 +43050,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVA
4304343050

4304443051
zval *key, *subject;
4304543052
HashTable *ht;
43046-
uint32_t result;
43053+
zend_bool result;
4304743054

4304843055
SAVE_OPLINE();
4304943056

@@ -43061,12 +43068,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVA
4306143068
goto array_key_exists_array;
4306243069
}
4306343070
}
43064-
result = zend_array_key_exists_slow(subject, key OPLINE_CC EXECUTE_DATA_CC);
43071+
zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC);
43072+
result = 0;
4306543073
}
4306643074

4306743075
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
4306843076

43069-
ZEND_VM_SMART_BRANCH(result == IS_TRUE, 1);
43077+
ZEND_VM_SMART_BRANCH(result, 1);
4307043078
}
4307143079

4307243080
/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */
@@ -47888,7 +47896,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CV_HA
4788847896

4788947897
zval *key, *subject;
4789047898
HashTable *ht;
47891-
uint32_t result;
47899+
zend_bool result;
4789247900

4789347901
SAVE_OPLINE();
4789447902

@@ -47906,11 +47914,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CV_HA
4790647914
goto array_key_exists_array;
4790747915
}
4790847916
}
47909-
result = zend_array_key_exists_slow(subject, key OPLINE_CC EXECUTE_DATA_CC);
47917+
zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC);
47918+
result = 0;
4791047919
}
4791147920

4791247921

47913-
ZEND_VM_SMART_BRANCH(result == IS_TRUE, 1);
47922+
ZEND_VM_SMART_BRANCH(result, 1);
4791447923
}
4791547924

4791647925
/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */

ext/spl/spl_array.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -804,7 +804,6 @@ static HashTable *spl_array_get_properties_for(zend_object *object, zend_prop_pu
804804
break;
805805
case ZEND_PROP_PURPOSE_VAR_EXPORT:
806806
case ZEND_PROP_PURPOSE_JSON:
807-
case _ZEND_PROP_PURPOSE_ARRAY_KEY_EXISTS:
808807
dup = 0;
809808
break;
810809
default:

ext/spl/tests/bug61347.phpt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ var_dump(isset($b['no_exists'])); //false
1212
var_dump(empty($b['b'])); //true
1313
var_dump(empty($b[37])); //true
1414

15-
var_dump(array_key_exists('b', $b)); //true
1615
var_dump($b['b']);
1716

1817
$a = array('b' => '', 37 => false);
@@ -29,9 +28,6 @@ bool(false)
2928
bool(false)
3029
bool(true)
3130
bool(true)
32-
33-
Deprecated: array_key_exists(): Using array_key_exists() on objects is deprecated. Use isset() or property_exists() instead in %s on line %d
34-
bool(true)
3531
NULL
3632
bool(true)
3733
bool(true)

ext/standard/array.c

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6332,23 +6332,13 @@ PHP_FUNCTION(array_map)
63326332
PHP_FUNCTION(array_key_exists)
63336333
{
63346334
zval *key;
6335-
zval *array;
63366335
HashTable *ht;
63376336

63386337
ZEND_PARSE_PARAMETERS_START(2, 2)
63396338
Z_PARAM_ZVAL(key)
6340-
Z_PARAM_ARRAY_OR_OBJECT(array)
6339+
Z_PARAM_ARRAY_HT(ht)
63416340
ZEND_PARSE_PARAMETERS_END();
63426341

6343-
if (EXPECTED(Z_TYPE_P(array) == IS_ARRAY)) {
6344-
ht = Z_ARRVAL_P(array);
6345-
} else {
6346-
ht = zend_get_properties_for(array, ZEND_PROP_PURPOSE_ARRAY_CAST);
6347-
php_error_docref(NULL, E_DEPRECATED,
6348-
"Using array_key_exists() on objects is deprecated. "
6349-
"Use isset() or property_exists() instead");
6350-
}
6351-
63526342
switch (Z_TYPE_P(key)) {
63536343
case IS_STRING:
63546344
RETVAL_BOOL(zend_symtable_exists_ind(ht, Z_STR_P(key)));
@@ -6363,10 +6353,6 @@ PHP_FUNCTION(array_key_exists)
63636353
php_error_docref(NULL, E_WARNING, "The first argument should be either a string or an integer");
63646354
RETVAL_FALSE;
63656355
}
6366-
6367-
if (Z_TYPE_P(array) != IS_ARRAY) {
6368-
zend_release_properties(ht);
6369-
}
63706356
}
63716357
/* }}} */
63726358

0 commit comments

Comments
 (0)