Skip to content

Commit 902d643

Browse files
committed
Deprecate implicit dynamic properties
Writing to a proprety that hasn't been declared is deprecated, unless the class uses the #[AllowDynamicProperties] attribute or defines __get()/__set(). RFC: https://wiki.php.net/rfc/deprecate_dynamic_properties
1 parent 35a01f8 commit 902d643

File tree

201 files changed

+583
-177
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

201 files changed

+583
-177
lines changed

UPGRADING

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,16 @@ PHP 8.2 UPGRADE NOTES
4848
========================================
4949

5050
- Core:
51+
. Creation of dynamic properties is deprecated, unless the class opts in by
52+
using the #[AllowDynamicProperties] attribute. stdClass allows dynamic
53+
properties. Usage of __get()/__set() is not affected by this change. A
54+
dynamic properties deprecation warning can be addressed by:
55+
- Declaring the property (preferred).
56+
- Adding the #[AllowDynamicProperties] attribute to the class (which also
57+
applies to all child classes).
58+
- Using a WeakMap if you wish to associate additional data with an object
59+
you do not own.
60+
5161
. Callables that are not accepted by the $callable() syntax (but are accepted
5262
by call_user_func) are deprecated. In particular:
5363

Zend/Optimizer/sccp.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1101,7 +1101,9 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
11011101

11021102
/* Don't try to propagate assignments to (potentially) typed properties. We would
11031103
* need to deal with errors and type conversions first. */
1104-
if (!var_info->ce || (var_info->ce->ce_flags & ZEND_ACC_HAS_TYPE_HINTS)) {
1104+
// TODO: Distinguish dynamic and declared property assignments here?
1105+
if (!var_info->ce || (var_info->ce->ce_flags & ZEND_ACC_HAS_TYPE_HINTS) ||
1106+
!(var_info->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
11051107
SET_RESULT_BOT(result);
11061108
SET_RESULT_BOT(op1);
11071109
return;

Zend/Optimizer/zend_inference.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4842,15 +4842,17 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op
48424842
return 1;
48434843
}
48444844

4845-
if (op_array->scope != ce && ce->default_properties_count) {
4846-
zend_property_info *prop_info =
4847-
zend_hash_find_ptr(&ce->properties_info, prop_name);
4848-
if (prop_info && (!(prop_info->flags & ZEND_ACC_PUBLIC)
4849-
|| ZEND_TYPE_IS_SET(prop_info->type))) {
4845+
zend_property_info *prop_info =
4846+
zend_hash_find_ptr(&ce->properties_info, prop_name);
4847+
if (prop_info) {
4848+
if (ZEND_TYPE_IS_SET(prop_info->type)) {
48504849
return 1;
48514850
}
4851+
return !(prop_info->flags & ZEND_ACC_PUBLIC)
4852+
&& prop_info->ce != op_array->scope;
4853+
} else {
4854+
return !(ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES);
48524855
}
4853-
return 0;
48544856
}
48554857
return 1;
48564858
case ZEND_ROPE_INIT:
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--TEST--
2+
#[AllowDynamicProperties] cannot be applied to interface
3+
--FILE--
4+
<?php
5+
6+
#[AllowDynamicProperties]
7+
interface Test {}
8+
9+
?>
10+
--EXPECTF--
11+
Fatal error: Cannot apply #[AllowDynamicProperties] to interface in %s on line %d
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--TEST--
2+
#[AllowDynamicProperties] cannot be applied to trait
3+
--FILE--
4+
<?php
5+
6+
#[AllowDynamicProperties]
7+
trait Test {}
8+
9+
?>
10+
--EXPECTF--
11+
Fatal error: Cannot apply #[AllowDynamicProperties] to trait in %s on line %d

Zend/tests/anon/003.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ reusing anonymous classes
44
<?php
55
while (@$i++<10) {
66
var_dump(new class($i) {
7-
7+
public $i;
88
public function __construct($i) {
99
$this->i = $i;
1010
}

Zend/tests/assign_to_obj_001.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ function &a($i) {
88
}
99

1010
class A {
11+
public $a;
1112
public function test() {
1213
$this->a = a(1);
1314
unset($this->a);

Zend/tests/bug27268.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
Bug #27268 (Bad references accentuated by clone)
33
--FILE--
44
<?php
5+
#[AllowDynamicProperties]
56
class A
67
{
78
public function &getA()

Zend/tests/bug30162.phpt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
Bug #30162 (Catching exception in constructor couses lose of $this)
33
--FILE--
44
<?php
5+
#[AllowDynamicProperties]
56
class FIIFO {
67

78
public function __construct() {
@@ -11,6 +12,7 @@ class FIIFO {
1112

1213
}
1314

15+
#[AllowDynamicProperties]
1416
class hariCow extends FIIFO {
1517

1618
public function __construct() {

Zend/tests/bug38779_1.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Bug #38779 (engine crashes when require()'ing file with syntax error through use
44
<?php
55

66
class Loader {
7+
public $context;
78
private $position;
89
private $data;
910
public function stream_open($path, $mode, $options, &$opened_path) {

0 commit comments

Comments
 (0)