File tree Expand file tree Collapse file tree 8 files changed +457
-41
lines changed Open diff view settings
Expand file tree Collapse file tree 8 files changed +457
-41
lines changed Open diff view settings
Original file line number Diff line number Diff line change @@ -107,6 +107,7 @@ PHP 7.4 UPGRADE NOTES
107107 This will enforce that $user->id can only be assigned integer and
108108 $user->name can only be assigned strings. For more information see the
109109 RFC: https://wiki.php.net/rfc/typed_properties_v2
110+
110111 . Added support for coalesce assign (??=) operator. For example:
111112
112113 $array['key'] ??= computeDefault();
@@ -156,6 +157,20 @@ PHP 7.4 UPGRADE NOTES
156157 . strip_tags() now also accepts an array of allowed tags: Instead of
157158 strip_tags($str, '<a><p>') you can now write strip_tags($str, ['a', 'p']).
158159
160+ . A new mechanism for custom object serialization has been added, which
161+ uses two new magic methods:
162+
163+ // Returns array containing all the necessary state of the object.
164+ public function __serialize(): array;
165+
166+ // Restores the object state from the given data array.
167+ public function __unserialize(array $data): void;
168+
169+ The new serialization mechanism supersedes the Serializable interface,
170+ which will be deprecated in the future.
171+
172+ RFC: https://wiki.php.net/rfc/custom_object_serialization
173+
159174========================================
1601753. Changes in SAPI modules
161176========================================
Original file line number Diff line number Diff line change 1+ --TEST--
2+ __serialize() mechanism (001): Basics
3+ --FILE--
4+ <?php
5+
6+ class Test {
7+ public $ prop ;
8+ public $ prop2 ;
9+ public function __serialize () {
10+ return ["value " => $ this ->prop , 42 => $ this ->prop2 ];
11+ }
12+ public function __unserialize (array $ data ) {
13+ $ this ->prop = $ data ["value " ];
14+ $ this ->prop2 = $ data [42 ];
15+ }
16+ }
17+
18+ $ test = new Test ;
19+ $ test ->prop = "foobar " ;
20+ $ test ->prop2 = "barfoo " ;
21+ var_dump ($ s = serialize ($ test ));
22+ var_dump (unserialize ($ s ));
23+
24+ ?>
25+ --EXPECT--
26+ string(58) "O:4:"Test":2:{s:5:"value";s:6:"foobar";i:42;s:6:"barfoo";}"
27+ object(Test)#2 (2) {
28+ ["prop"]=>
29+ string(6) "foobar"
30+ ["prop2"]=>
31+ string(6) "barfoo"
32+ }
Original file line number Diff line number Diff line change 1+ --TEST--
2+ __serialize() mechanism (002): TypeError on invalid return type
3+ --FILE--
4+ <?php
5+
6+ class Test {
7+ public function __serialize () {
8+ return $ this ;
9+ }
10+ }
11+
12+ try {
13+ serialize (new Test );
14+ } catch (TypeError $ e ) {
15+ echo $ e ->getMessage (), "\n" ;
16+ }
17+
18+ ?>
19+ --EXPECT--
20+ __serialize() must return an array
Original file line number Diff line number Diff line change 1+ --TEST--
2+ __serialize() mechanism (003): Interoperability of different serialization mechanisms
3+ --FILE--
4+ <?php
5+
6+ class Test implements Serializable {
7+ public function __sleep () {
8+ echo "__sleep() called \n" ;
9+ }
10+
11+ public function __wakeup () {
12+ echo "__wakeup() called \n" ;
13+ }
14+
15+ public function __serialize () {
16+ echo "__serialize() called \n" ;
17+ return ["key " => "value " ];
18+ }
19+
20+ public function __unserialize (array $ data ) {
21+ echo "__unserialize() called \n" ;
22+ var_dump ($ data );
23+ }
24+
25+ public function serialize () {
26+ echo "serialize() called \n" ;
27+ return "payload " ;
28+ }
29+
30+ public function unserialize ($ payload ) {
31+ echo "unserialize() called \n" ;
32+ var_dump ($ payload );
33+ }
34+ }
35+
36+ $ test = new Test ;
37+ var_dump ($ s = serialize ($ test ));
38+ var_dump (unserialize ($ s ));
39+
40+ var_dump (unserialize ('C:4:"Test":7:{payload} ' ));
41+
42+ ?>
43+ --EXPECT--
44+ __serialize() called
45+ string(37) "O:4:"Test":1:{s:3:"key";s:5:"value";}"
46+ __unserialize() called
47+ array(1) {
48+ ["key"]=>
49+ string(5) "value"
50+ }
51+ object(Test)#2 (0) {
52+ }
53+ unserialize() called
54+ string(7) "payload"
55+ object(Test)#2 (0) {
56+ }
Original file line number Diff line number Diff line change 1+ --TEST--
2+ __serialize() mechanism (004): Delayed __unserialize() calls
3+ --FILE--
4+ <?php
5+
6+ class Wakeup {
7+ public $ data ;
8+ public function __construct (array $ data ) {
9+ $ this ->data = $ data ;
10+ }
11+ public function __wakeup () {
12+ echo "__wakeup() called \n" ;
13+ var_dump ($ this ->data );
14+ $ this ->woken_up = true ;
15+ }
16+ }
17+
18+ class Unserialize {
19+ public $ data ;
20+ public function __construct (array $ data ) {
21+ $ this ->data = $ data ;
22+ }
23+ public function __serialize () {
24+ return $ this ->data ;
25+ }
26+ public function __unserialize (array $ data ) {
27+ $ this ->data = $ data ;
28+ echo "__unserialize() called \n" ;
29+ var_dump ($ this ->data );
30+ $ this ->unserialized = true ;
31+ }
32+ }
33+
34+ $ obj = new Wakeup ([new Unserialize ([new Wakeup ([new Unserialize ([])])])]);
35+ var_dump ($ s = serialize ($ obj ));
36+ var_dump (unserialize ($ s ));
37+
38+ ?>
39+ --EXPECT--
40+ string(126) "O:6:"Wakeup":1:{s:4:"data";a:1:{i:0;O:11:"Unserialize":1:{i:0;O:6:"Wakeup":1:{s:4:"data";a:1:{i:0;O:11:"Unserialize":0:{}}}}}}"
41+ __unserialize() called
42+ array(0) {
43+ }
44+ __wakeup() called
45+ array(1) {
46+ [0]=>
47+ object(Unserialize)#8 (2) {
48+ ["data"]=>
49+ array(0) {
50+ }
51+ ["unserialized"]=>
52+ bool(true)
53+ }
54+ }
55+ __unserialize() called
56+ array(1) {
57+ [0]=>
58+ object(Wakeup)#7 (2) {
59+ ["data"]=>
60+ array(1) {
61+ [0]=>
62+ object(Unserialize)#8 (2) {
63+ ["data"]=>
64+ array(0) {
65+ }
66+ ["unserialized"]=>
67+ bool(true)
68+ }
69+ }
70+ ["woken_up"]=>
71+ bool(true)
72+ }
73+ }
74+ __wakeup() called
75+ array(1) {
76+ [0]=>
77+ object(Unserialize)#6 (2) {
78+ ["data"]=>
79+ array(1) {
80+ [0]=>
81+ object(Wakeup)#7 (2) {
82+ ["data"]=>
83+ array(1) {
84+ [0]=>
85+ object(Unserialize)#8 (2) {
86+ ["data"]=>
87+ array(0) {
88+ }
89+ ["unserialized"]=>
90+ bool(true)
91+ }
92+ }
93+ ["woken_up"]=>
94+ bool(true)
95+ }
96+ }
97+ ["unserialized"]=>
98+ bool(true)
99+ }
100+ }
101+ object(Wakeup)#5 (2) {
102+ ["data"]=>
103+ array(1) {
104+ [0]=>
105+ object(Unserialize)#6 (2) {
106+ ["data"]=>
107+ array(1) {
108+ [0]=>
109+ object(Wakeup)#7 (2) {
110+ ["data"]=>
111+ array(1) {
112+ [0]=>
113+ object(Unserialize)#8 (2) {
114+ ["data"]=>
115+ array(0) {
116+ }
117+ ["unserialized"]=>
118+ bool(true)
119+ }
120+ }
121+ ["woken_up"]=>
122+ bool(true)
123+ }
124+ }
125+ ["unserialized"]=>
126+ bool(true)
127+ }
128+ }
129+ ["woken_up"]=>
130+ bool(true)
131+ }
Original file line number Diff line number Diff line change 1+ --TEST--
2+ __serialize() mechanism (005): parent::__unserialize() is safe
3+ --FILE--
4+ <?php
5+
6+ class A {
7+ private $ data ;
8+ public function __construct (array $ data ) {
9+ $ this ->data = $ data ;
10+ }
11+ public function __serialize () {
12+ return $ this ->data ;
13+ }
14+ public function __unserialize (array $ data ) {
15+ $ this ->data = $ data ;
16+ }
17+ }
18+
19+ class B extends A {
20+ private $ data2 ;
21+ public function __construct (array $ data , array $ data2 ) {
22+ parent ::__construct ($ data );
23+ $ this ->data2 = $ data2 ;
24+ }
25+ public function __serialize () {
26+ return [$ this ->data2 , parent ::__serialize ()];
27+ }
28+ public function __unserialize (array $ payload ) {
29+ [$ data2 , $ data ] = $ payload ;
30+ parent ::__unserialize ($ data );
31+ $ this ->data2 = $ data2 ;
32+ }
33+ }
34+
35+ $ common = new stdClass ;
36+ $ obj = new B ([$ common ], [$ common ]);
37+ var_dump ($ s = serialize ($ obj ));
38+ var_dump (unserialize ($ s ));
39+
40+ ?>
41+ --EXPECT--
42+ string(63) "O:1:"B":2:{i:0;a:1:{i:0;O:8:"stdClass":0:{}}i:1;a:1:{i:0;r:3;}}"
43+ object(B)#3 (2) {
44+ ["data2":"B":private]=>
45+ array(1) {
46+ [0]=>
47+ object(stdClass)#4 (0) {
48+ }
49+ }
50+ ["data":"A":private]=>
51+ array(1) {
52+ [0]=>
53+ object(stdClass)#4 (0) {
54+ }
55+ }
56+ }
You can’t perform that action at this time.
0 commit comments