Skip to content

Commit b0c7ea4

Browse files
committed
Change the order of properties used in foreach(), var_dump(), serialize(), comparison, etc. Now properties are ordered according to their layout in zend_object structure.
2 parents 47a2e5c + c9a9362 commit b0c7ea4

36 files changed

+283
-286
lines changed

UPGRADING

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,15 @@ PHP 8.1 UPGRADE NOTES
211211
5. Changed Functions
212212
========================================
213213

214+
- Core:
215+
. Properties order used in foreach, var_dump(), serialize(), object comparison
216+
etc. was changed. Now properties are naturally ordered according to their
217+
declaration and inheritance. Prpoerties declared in a base class are going
218+
to be before the child properties. This order is consistent with internal
219+
layout of properies in zend_objct structure and repeats the order in
220+
default_properties_table[] and properties_info_table[]. The old order was
221+
not documented and was caused by class inheritance implementation details.
222+
214223
- Filter:
215224
. The FILTER_FLAG_ALLOW_OCTAL flag of the FILTER_VALIDATE_INT filter now accept
216225
octal string with the leading octal prefix ("0o"/"0O")

Zend/tests/bug27798.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ array(3) {
5757
}
5858
Child::__construct
5959
array(3) {
60-
["Baz"]=>
61-
int(4)
6260
["Foo"]=>
6361
int(1)
6462
["Bar"]=>
6563
int(2)
64+
["Baz"]=>
65+
int(4)
6666
}
6767
array(1) {
6868
["Foo"]=>

Zend/tests/bug60536_003.phpt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@ var_dump($b);
3232
?>
3333
--EXPECTF--
3434
object(SubclassA)#%d (2) {
35-
["hello":"SubclassA":private]=>
36-
int(0)
3735
["hello":"BaseWithPropA":private]=>
3836
int(0)
37+
["hello":"SubclassA":private]=>
38+
int(0)
3939
}
4040
object(SubclassB)#%d (2) {
41-
["hello":"SubclassB":private]=>
42-
int(0)
4341
["hello":"BaseWithTPropB":private]=>
4442
int(0)
43+
["hello":"SubclassB":private]=>
44+
int(0)
4545
}

Zend/tests/bug79862.phpt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,14 @@ NULL
4545
NULL
4646
NULL
4747
object(c)#1 (6) {
48-
["prop1"]=>
49-
int(1)
50-
["prop2":protected]=>
51-
int(2)
5248
["prop3":"a":private]=>
5349
int(3)
5450
["prop4":"a":private]=>
5551
int(4)
52+
["prop1"]=>
53+
int(1)
54+
["prop2":protected]=>
55+
int(2)
5656
["prop5"]=>
5757
int(5)
5858
["prop6"]=>

Zend/tests/get_mangled_object_vars.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ echo "\n";
3333
?>
3434
--EXPECT--
3535
array (
36-
'' . "\0" . 'B' . "\0" . 'priv' => 4,
3736
'pub' => 1,
3837
'' . "\0" . '*' . "\0" . 'prot' => 2,
3938
'' . "\0" . 'A' . "\0" . 'priv' => 3,
39+
'' . "\0" . 'B' . "\0" . 'priv' => 4,
4040
'dyn' => 5,
4141
6 => 6,
4242
)

Zend/tests/objects_033.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,5 @@ print_r($a, true);
2424
var_dump($a < $b);
2525
?>
2626
--EXPECT--
27-
bool(false)
28-
bool(false)
27+
bool(true)
28+
bool(true)

Zend/tests/traits/property008.phpt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,20 +42,20 @@ var_dump($b);
4242
?>
4343
--EXPECT--
4444
object(SubclassClassicInheritance)#1 (2) {
45-
["hello":"SubclassClassicInheritance":private]=>
46-
int(0)
4745
["hello":"BaseWithPropA":private]=>
4846
int(0)
47+
["hello":"SubclassClassicInheritance":private]=>
48+
int(0)
4949
}
5050
object(SubclassA)#2 (2) {
51-
["hello":"SubclassA":private]=>
52-
int(0)
5351
["hello":"BaseWithPropA":private]=>
5452
int(0)
53+
["hello":"SubclassA":private]=>
54+
int(0)
5555
}
5656
object(SubclassB)#3 (2) {
57-
["hello":"SubclassB":private]=>
58-
int(0)
5957
["hello":"BaseWithTPropB":private]=>
6058
int(0)
59+
["hello":"SubclassB":private]=>
60+
int(0)
6161
}

Zend/zend_object_handlers.c

Lines changed: 21 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -63,41 +63,24 @@ ZEND_API void rebuild_object_properties(zend_object *zobj) /* {{{ */
6363
if (!zobj->properties) {
6464
zend_property_info *prop_info;
6565
zend_class_entry *ce = zobj->ce;
66-
uint32_t flags = 0;
66+
int i;
6767

6868
zobj->properties = zend_new_array(ce->default_properties_count);
6969
if (ce->default_properties_count) {
7070
zend_hash_real_init_mixed(zobj->properties);
71-
ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop_info) {
72-
if (!(prop_info->flags & ZEND_ACC_STATIC)) {
73-
flags |= prop_info->flags;
71+
for (i = 0; i < ce->default_properties_count; i++) {
72+
prop_info = ce->properties_info_table[i];
7473

75-
if (UNEXPECTED(Z_TYPE_P(OBJ_PROP(zobj, prop_info->offset)) == IS_UNDEF)) {
76-
HT_FLAGS(zobj->properties) |= HASH_FLAG_HAS_EMPTY_IND;
77-
}
78-
79-
_zend_hash_append_ind(zobj->properties, prop_info->name,
80-
OBJ_PROP(zobj, prop_info->offset));
74+
if (!prop_info) {
75+
continue;
8176
}
82-
} ZEND_HASH_FOREACH_END();
83-
if (flags & ZEND_ACC_CHANGED) {
84-
while (ce->parent && ce->parent->default_properties_count) {
85-
ce = ce->parent;
86-
ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop_info) {
87-
if (prop_info->ce == ce &&
88-
!(prop_info->flags & ZEND_ACC_STATIC) &&
89-
(prop_info->flags & ZEND_ACC_PRIVATE)) {
90-
zval zv;
91-
92-
if (UNEXPECTED(Z_TYPE_P(OBJ_PROP(zobj, prop_info->offset)) == IS_UNDEF)) {
93-
HT_FLAGS(zobj->properties) |= HASH_FLAG_HAS_EMPTY_IND;
94-
}
95-
96-
ZVAL_INDIRECT(&zv, OBJ_PROP(zobj, prop_info->offset));
97-
zend_hash_add(zobj->properties, prop_info->name, &zv);
98-
}
99-
} ZEND_HASH_FOREACH_END();
77+
78+
if (UNEXPECTED(Z_TYPE_P(OBJ_PROP(zobj, prop_info->offset)) == IS_UNDEF)) {
79+
HT_FLAGS(zobj->properties) |= HASH_FLAG_HAS_EMPTY_IND;
10080
}
81+
82+
_zend_hash_append_ind(zobj->properties, prop_info->name,
83+
OBJ_PROP(zobj, prop_info->offset));
10184
}
10285
}
10386
}
@@ -1555,6 +1538,7 @@ ZEND_API int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */
15551538
}
15561539
if (!zobj1->properties && !zobj2->properties) {
15571540
zend_property_info *info;
1541+
int i;
15581542

15591543
if (!zobj1->ce->default_properties_count) {
15601544
return 0;
@@ -1570,14 +1554,18 @@ ZEND_API int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */
15701554
}
15711555
Z_PROTECT_RECURSION_P(o1);
15721556

1573-
ZEND_HASH_FOREACH_PTR(&zobj1->ce->properties_info, info) {
1574-
zval *p1 = OBJ_PROP(zobj1, info->offset);
1575-
zval *p2 = OBJ_PROP(zobj2, info->offset);
1557+
for (i = 0; i < zobj1->ce->default_properties_count; i++) {
1558+
zval *p1, *p2;
1559+
1560+
info = zobj1->ce->properties_info_table[i];
15761561

1577-
if (info->flags & ZEND_ACC_STATIC) {
1562+
if (!info) {
15781563
continue;
15791564
}
15801565

1566+
p1 = OBJ_PROP(zobj1, info->offset);
1567+
p2 = OBJ_PROP(zobj2, info->offset);
1568+
15811569
if (Z_TYPE_P(p1) != IS_UNDEF) {
15821570
if (Z_TYPE_P(p2) != IS_UNDEF) {
15831571
int ret;
@@ -1597,7 +1585,7 @@ ZEND_API int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */
15971585
return 1;
15981586
}
15991587
}
1600-
} ZEND_HASH_FOREACH_END();
1588+
}
16011589

16021590
Z_UNPROTECT_RECURSION_P(o1);
16031591
return 0;

ext/date/tests/DateTimeZone_clone_basic2.phpt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,28 +51,28 @@ object(DateTimeZoneExt1)#%d (4) {
5151
string(13) "Europe/London"
5252
}
5353
object(DateTimeZoneExt2)#%d (6) {
54-
["property3"]=>
55-
bool(true)
56-
["property4"]=>
57-
float(10.5)
5854
["property1"]=>
5955
int(99)
6056
["property2"]=>
6157
string(5) "Hello"
58+
["property3"]=>
59+
bool(true)
60+
["property4"]=>
61+
float(10.5)
6262
["timezone_type"]=>
6363
int(3)
6464
["timezone"]=>
6565
string(13) "Europe/London"
6666
}
6767
object(DateTimeZoneExt2)#%d (6) {
68-
["property3"]=>
69-
bool(true)
70-
["property4"]=>
71-
float(10.5)
7268
["property1"]=>
7369
int(99)
7470
["property2"]=>
7571
string(5) "Hello"
72+
["property3"]=>
73+
bool(true)
74+
["property4"]=>
75+
float(10.5)
7676
["timezone_type"]=>
7777
int(3)
7878
["timezone"]=>

ext/date/tests/DateTime_clone_basic2.phpt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,14 @@ object(DateTimeExt1)#%d (5) {
5555
string(3) "GMT"
5656
}
5757
object(DateTimeExt2)#%d (7) {
58-
["property3"]=>
59-
bool(true)
60-
["property4"]=>
61-
float(10.5)
6258
["property1"]=>
6359
int(99)
6460
["property2"]=>
6561
string(5) "Hello"
62+
["property3"]=>
63+
bool(true)
64+
["property4"]=>
65+
float(10.5)
6666
["date"]=>
6767
string(26) "2009-02-03 12:34:41.000000"
6868
["timezone_type"]=>
@@ -71,14 +71,14 @@ object(DateTimeExt2)#%d (7) {
7171
string(3) "GMT"
7272
}
7373
object(DateTimeExt2)#%d (7) {
74-
["property3"]=>
75-
bool(true)
76-
["property4"]=>
77-
float(10.5)
7874
["property1"]=>
7975
int(99)
8076
["property2"]=>
8177
string(5) "Hello"
78+
["property3"]=>
79+
bool(true)
80+
["property4"]=>
81+
float(10.5)
8282
["date"]=>
8383
string(26) "2009-02-03 12:34:41.000000"
8484
["timezone_type"]=>

ext/dom/tests/dom003.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ object(DOMException)#%d (%d) {
3030
string(23) "Hierarchy Request Error"
3131
["string":"Exception":private]=>
3232
string(0) ""
33+
["code"]=>
34+
int(3)
3335
["file":protected]=>
3436
string(%d) "%sdom003.php"
3537
["line":protected]=>
@@ -57,8 +59,6 @@ object(DOMException)#%d (%d) {
5759
}
5860
["previous":"Exception":private]=>
5961
NULL
60-
["code"]=>
61-
int(3)
6262
}
6363
--- Don't catch exception with try/catch
6464

ext/dom/tests/dom_set_attr_node.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ object(DOMException)#%d (7) {
4040
string(20) "Wrong Document Error"
4141
["string":"Exception":private]=>
4242
string(0) ""
43+
["code"]=>
44+
int(4)
4345
["file":protected]=>
4446
string(%d) "%sdom_set_attr_node.php"
4547
["line":protected]=>
@@ -67,6 +69,4 @@ object(DOMException)#%d (7) {
6769
}
6870
["previous":"Exception":private]=>
6971
NULL
70-
["code"]=>
71-
int(4)
7272
}

ext/mysqli/tests/mysqli_stmt_bind_result_references.phpt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -291,23 +291,23 @@ string(1) "a"
291291
reference, object, forward declaration...
292292
int(1)
293293
object(bar)#%d (2) {
294-
["bar"]=>
295-
&string(1) "a"
296294
["foo"]=>
297295
&string(1) "a"
296+
["bar"]=>
297+
&string(1) "a"
298298
}
299299
string(1) "a"
300300
references, object, private...
301301
int(1)
302302
string(1) "a"
303303
object(mega_bar)#5 (4) {
304+
["foo"]=>
305+
&string(1) "a"
306+
["bar"]=>
307+
&string(1) "a"
304308
[%s]=>
305309
&int(1)
306310
["id_ref"]=>
307311
&int(1)
308-
["bar"]=>
309-
&string(1) "a"
310-
["foo"]=>
311-
&string(1) "a"
312312
}
313313
done!

ext/pdo/tests/pdo_005.phpt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,40 +114,40 @@ TestDerived::__construct(2,3)
114114
array(3) {
115115
[0]=>
116116
object(TestDerived)#%d (5) {
117-
["row":protected]=>
118-
int(0)
119117
["id"]=>
120118
string(1) "1"
121119
["val":protected]=>
122120
string(1) "A"
123121
["val2":"TestBase":private]=>
124122
NULL
123+
["row":protected]=>
124+
int(0)
125125
["val2"]=>
126126
string(2) "AA"
127127
}
128128
[1]=>
129129
object(TestDerived)#%d (5) {
130-
["row":protected]=>
131-
int(1)
132130
["id"]=>
133131
string(1) "2"
134132
["val":protected]=>
135133
string(1) "B"
136134
["val2":"TestBase":private]=>
137135
NULL
136+
["row":protected]=>
137+
int(1)
138138
["val2"]=>
139139
string(2) "BB"
140140
}
141141
[2]=>
142142
object(TestDerived)#%d (5) {
143-
["row":protected]=>
144-
int(2)
145143
["id"]=>
146144
string(1) "3"
147145
["val":protected]=>
148146
string(1) "C"
149147
["val2":"TestBase":private]=>
150148
NULL
149+
["row":protected]=>
150+
int(2)
151151
["val2"]=>
152152
string(2) "CC"
153153
}

0 commit comments

Comments
 (0)