Skip to content

Commit 052af90

Browse files
kamil-tekielaTysonAndrenikic
committed
Deprecate autovivification on false
Deprecate automatically converting "false" into an empty array on write operands. Autovivification continues to be supported for "null" values, as well as undefined/uninitialized values. RFC: https://wiki.php.net/rfc/autovivification_false Closes GH-7131. Co-authored-by: Tyson Andre <tysonandre775@hotmail.com> Co-authored-by: Nikita Popov <nikita.ppv@gmail.com>
1 parent c2a58ab commit 052af90

15 files changed

+678
-92
lines changed

UPGRADING

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,9 @@ PHP 8.1 UPGRADE NOTES
356356
. Returning a non-array from __sleep will raise a warning
357357
. Returning by reference from a void function is deprecated.
358358
RFC: https://wiki.php.net/rfc/deprecations_php_8_1
359+
. Automatic conversion of "false" into an empty array on write operands is
360+
deprecated.
361+
RFC: https://wiki.php.net/rfc/autovivification_false
359362

360363
- Ctype:
361364
. Passing a non-string value to ctype_*() functions is deprecated. A future

Zend/Optimizer/zend_inference.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4753,7 +4753,7 @@ ZEND_API int zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op,
47534753
return 1;
47544754
}
47554755
}
4756-
return (t1 & (MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_TRUE|MAY_BE_STRING|MAY_BE_LONG|MAY_BE_DOUBLE)) || opline->op2_type == IS_UNUSED ||
4756+
return (t1 & (MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_TRUE|MAY_BE_FALSE|MAY_BE_STRING|MAY_BE_LONG|MAY_BE_DOUBLE)) || opline->op2_type == IS_UNUSED ||
47574757
(t2 & (MAY_BE_UNDEF|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE));
47584758
case ZEND_ASSIGN_OBJ:
47594759
if (t1 & (MAY_BE_ANY-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_OBJECT))) {
@@ -4869,7 +4869,7 @@ ZEND_API int zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op,
48694869
return 0;
48704870
case ZEND_FETCH_DIM_W:
48714871
case ZEND_FETCH_LIST_W:
4872-
if (t1 & (MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_STRING|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) {
4872+
if (t1 & (MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_STRING|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) {
48734873
return 1;
48744874
}
48754875
if (t2 & (MAY_BE_RESOURCE|MAY_BE_ARRAY|MAY_BE_OBJECT)) {

Zend/tests/falsetoarray.phpt

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
--TEST--
2+
Autovivification of false to array
3+
--FILE--
4+
<?php
5+
6+
// control
7+
$undef[] = 42;
8+
9+
// control
10+
$null = null;
11+
$null[] = 42;
12+
13+
// control
14+
$false = false;
15+
$false = [42];
16+
17+
print "[001]\n";
18+
$false = false;
19+
$false[] = 42;
20+
21+
print "[002]\n";
22+
$ref = false;
23+
$ref2 = &$ref;
24+
$ref2[] = 42;
25+
26+
echo "\nFunction\n";
27+
function ffalse(bool $a, ?bool $b, &$c, ...$d) {
28+
print "[003]\n";
29+
$a[] = 42;
30+
print "[004]\n";
31+
$b[] = 42;
32+
print "[005]\n";
33+
$c[] = 42;
34+
print "[006]\n";
35+
$d[0][] = 42;
36+
}
37+
$ref = false;
38+
ffalse(false, false, $ref, false);
39+
40+
echo "\nProperties\n";
41+
class Cfalse {
42+
public $def;
43+
private $untyped = false;
44+
static private $st = false;
45+
static private $st2 = false;
46+
static private $st3 = false;
47+
public function __construct(public $pu, private $pr = false) {
48+
print "[007]\n";
49+
$this->def = false;
50+
$this->def[] = 42;
51+
print "[008]\n";
52+
$this->untyped[] = 42;
53+
print "[009]\n";
54+
self::$st[] = 42;
55+
print "[010]\n";
56+
static::$st2[] = 42;
57+
print "[011]\n";
58+
$this::$st3[] = 42;
59+
print "[012]\n";
60+
$this->pu[] = 42;
61+
print "[013]\n";
62+
$this->pr[] = 42;
63+
}
64+
}
65+
new Cfalse(false, false);
66+
67+
echo "\nDestructuring\n";
68+
69+
print "[014]\n";
70+
$add = false;
71+
foreach ([42] as $add[]);
72+
73+
print "[015]\n";
74+
$arr = false;
75+
[$arr[]] = [42];
76+
77+
print "[016]\n";
78+
$arr = [ 0 => [ 0 => false ] ];
79+
$arr[0][0][0][] = 42;
80+
81+
print "[017]\n";
82+
$false = false;
83+
$r42 = 42;
84+
$false[] &= $r42;
85+
86+
$false = false;
87+
$false2 = false;
88+
$false3 = false;
89+
function &g(){
90+
print "[018]\n";
91+
global $false;
92+
$false[] = 42;
93+
94+
$var1 = false;
95+
$GLOBALS["false2"] =& $var1;
96+
97+
print "[019]\n";
98+
$GLOBALS["false3"][] = 42;
99+
100+
print "[020]\n";
101+
static $f2 = false;
102+
return $f2;
103+
}
104+
105+
$false = &g();
106+
$false[] = 42;
107+
print "[021]\n";
108+
$false2[] = 42;
109+
110+
print "[022]\n";
111+
$a = false;
112+
unset($a[0][0]);
113+
114+
print "[023]\n";
115+
$a = false;
116+
unset($a[0]);
117+
118+
?>
119+
--EXPECTF--
120+
[001]
121+
122+
Deprecated: Automatic conversion of false to array is deprecated in %s
123+
[002]
124+
125+
Deprecated: Automatic conversion of false to array is deprecated in %s
126+
127+
Function
128+
[003]
129+
130+
Deprecated: Automatic conversion of false to array is deprecated in %s
131+
[004]
132+
133+
Deprecated: Automatic conversion of false to array is deprecated in %s
134+
[005]
135+
136+
Deprecated: Automatic conversion of false to array is deprecated in %s
137+
[006]
138+
139+
Deprecated: Automatic conversion of false to array is deprecated in %s
140+
141+
Properties
142+
[007]
143+
144+
Deprecated: Automatic conversion of false to array is deprecated in %s
145+
[008]
146+
147+
Deprecated: Automatic conversion of false to array is deprecated in %s
148+
[009]
149+
150+
Deprecated: Automatic conversion of false to array is deprecated in %s
151+
[010]
152+
153+
Deprecated: Automatic conversion of false to array is deprecated in %s
154+
[011]
155+
156+
Deprecated: Automatic conversion of false to array is deprecated in %s
157+
[012]
158+
159+
Deprecated: Automatic conversion of false to array is deprecated in %s
160+
[013]
161+
162+
Deprecated: Automatic conversion of false to array is deprecated in %s
163+
164+
Destructuring
165+
[014]
166+
167+
Deprecated: Automatic conversion of false to array is deprecated in %s
168+
[015]
169+
170+
Deprecated: Automatic conversion of false to array is deprecated in %s
171+
[016]
172+
173+
Deprecated: Automatic conversion of false to array is deprecated in %s
174+
[017]
175+
176+
Deprecated: Automatic conversion of false to array is deprecated in %s
177+
[018]
178+
179+
Deprecated: Automatic conversion of false to array is deprecated in %s
180+
[019]
181+
182+
Deprecated: Automatic conversion of false to array is deprecated in %s
183+
[020]
184+
185+
Deprecated: Automatic conversion of false to array is deprecated in %s
186+
[021]
187+
188+
Deprecated: Automatic conversion of false to array is deprecated in %s
189+
[022]
190+
191+
Deprecated: Automatic conversion of false to array is deprecated in %s
192+
[023]
193+
194+
Deprecated: Automatic conversion of false to array is deprecated in %s

Zend/tests/indexing_001.phpt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ foreach ($testvalues as $testvalue) {
5252
}
5353

5454
?>
55-
--EXPECT--
55+
--EXPECTF--
5656
*** Indexing - Testing value assignment with key ***
5757
array(1) {
5858
["foo"]=>
@@ -67,6 +67,8 @@ Cannot use a scalar value as an array
6767
int(1)
6868
Cannot use a scalar value as an array
6969
bool(true)
70+
71+
Deprecated: Automatic conversion of false to array is deprecated in %s
7072
array(1) {
7173
["foo"]=>
7274
array(1) {
@@ -102,6 +104,8 @@ Cannot use a scalar value as an array
102104
int(1)
103105
Cannot use a scalar value as an array
104106
bool(true)
107+
108+
Deprecated: Automatic conversion of false to array is deprecated in %s
105109
array(1) {
106110
["foo"]=>
107111
&array(1) {
@@ -132,6 +136,8 @@ Cannot use a scalar value as an array
132136
int(1)
133137
Cannot use a scalar value as an array
134138
bool(true)
139+
140+
Deprecated: Automatic conversion of false to array is deprecated in %s
135141
array(1) {
136142
[0]=>
137143
array(1) {
@@ -163,6 +169,8 @@ Cannot use a scalar value as an array
163169
int(1)
164170
Cannot use a scalar value as an array
165171
bool(true)
172+
173+
Deprecated: Automatic conversion of false to array is deprecated in %s
166174
array(1) {
167175
[0]=>
168176
&array(1) {

Zend/tests/unset_non_array.phpt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,17 @@ try {
9595
?>
9696
--EXPECTF--
9797
Warning: Undefined variable $x in %s on line %d
98+
99+
Deprecated: Automatic conversion of false to array is deprecated in %s
98100
Cannot unset offset in a non-array variable
99101
Cannot unset offset in a non-array variable
100102
Cannot unset offset in a non-array variable
101103
Cannot unset string offsets
102104
Cannot use object of type stdClass as array
103105

104106
Warning: Undefined variable $x in %s on line %d
107+
108+
Deprecated: Automatic conversion of false to array is deprecated in %s
105109
Cannot unset offset in a non-array variable
106110
Cannot unset offset in a non-array variable
107111
Cannot unset offset in a non-array variable

Zend/zend_execute.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1583,6 +1583,11 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_deprecated_function(const zend_functi
15831583
}
15841584
}
15851585

1586+
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_false_to_array_deprecated(void)
1587+
{
1588+
zend_error(E_DEPRECATED, "Automatic conversion of false to array is deprecated");
1589+
}
1590+
15861591
static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim, zval *value OPLINE_DC EXECUTE_DATA_DC)
15871592
{
15881593
zend_uchar c;
@@ -2330,6 +2335,9 @@ static zend_always_inline void zend_fetch_dimension_address(zval *result, zval *
23302335
if (type != BP_VAR_W && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
23312336
ZVAL_UNDEFINED_OP1();
23322337
}
2338+
if (Z_TYPE_P(container) == IS_FALSE) {
2339+
zend_false_to_array_deprecated();
2340+
}
23332341
if (type != BP_VAR_UNSET) {
23342342
array_init(container);
23352343
goto fetch_from_array;

Zend/zend_execute.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ extern ZEND_API const zend_internal_function zend_pass_function;
5858

5959
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(zend_execute_data *execute_data);
6060
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_deprecated_function(const zend_function *fbc);
61+
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_false_to_array_deprecated(void);
6162
ZEND_COLD void ZEND_FASTCALL zend_param_must_be_ref(const zend_function *func, uint32_t arg_num);
6263

6364
ZEND_API bool ZEND_FASTCALL zend_verify_ref_assignable_zval(zend_reference *ref, zval *zv, bool strict);

Zend/zend_vm_def.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,6 +1210,9 @@ ZEND_VM_C_LABEL(assign_dim_op_new_array):
12101210
if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) {
12111211
ZVAL_UNDEFINED_OP1();
12121212
}
1213+
if (Z_TYPE_P(container) == IS_FALSE) {
1214+
zend_false_to_array_deprecated();
1215+
}
12131216
ZVAL_ARR(container, zend_new_array(8));
12141217
ZEND_VM_C_GOTO(assign_dim_op_new_array);
12151218
} else {
@@ -2590,6 +2593,10 @@ ZEND_VM_C_LABEL(try_assign_dim_array):
25902593
FREE_OP_DATA();
25912594
}
25922595
} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
2596+
if (Z_TYPE_P(object_ptr) == IS_FALSE) {
2597+
zend_false_to_array_deprecated();
2598+
}
2599+
25932600
if (Z_ISREF_P(orig_object_ptr)
25942601
&& ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
25952602
&& !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
@@ -6453,6 +6460,8 @@ ZEND_VM_C_LABEL(num_index_dim):
64536460
zend_throw_error(NULL, "Cannot unset string offsets");
64546461
} else if (UNEXPECTED(Z_TYPE_P(container) > IS_FALSE)) {
64556462
zend_throw_error(NULL, "Cannot unset offset in a non-array variable");
6463+
} else if (UNEXPECTED(Z_TYPE_P(container) == IS_FALSE)) {
6464+
zend_false_to_array_deprecated();
64566465
}
64576466
} while (0);
64586467

0 commit comments

Comments
 (0)