Skip to content

Commit 3e6b447

Browse files
committed
Partially deprecate Serializable
If Serializable is implemented, require that __serialize() and __unserialize() are implemented as well, else issue a deprecation warning. Also deprecate use of PDO::FETCH_SERIALIZE. RFC: https://wiki.php.net/rfc/phase_out_serializable Closes GH-6494.
1 parent 5295e36 commit 3e6b447

32 files changed

+136
-28
lines changed

UPGRADING

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,13 @@ PHP 8.1 UPGRADE NOTES
254254
4. Deprecated Functionality
255255
========================================
256256

257+
- Core:
258+
. Implementing the Serializable interface without also implementing
259+
__serialize() and __unserialize() has been deprecated. You should either
260+
implement the new methods (if you only support PHP 7.4 and higher) or
261+
implement both (if you support older PHP versions as well).
262+
RFC: https://wiki.php.net/rfc/phase_out_serializable
263+
257264
- MySQLi:
258265
. The mysqli_driver::$driver_version property has been deprecated. The driver
259266
version is meaningless as it hasn't been updated in more than a decade. Use
@@ -263,6 +270,10 @@ PHP 8.1 UPGRADE NOTES
263270
mysqli_get_client_info() without any arguments to obtain the client
264271
library version information.
265272

273+
- PDO:
274+
. The PDO::FETCH_SERIALIZE mode has been deprecated.
275+
RFC: https://wiki.php.net/rfc/phase_out_serializable
276+
266277
========================================
267278
5. Changed Functions
268279
========================================

Zend/tests/bug64354.phpt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,6 @@ try {
2020
var_dump($e->getMessage());
2121
}
2222
?>
23-
--EXPECT--
23+
--EXPECTF--
24+
Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
2425
string(9) "serialize"

Zend/tests/enum/no-implement-serializable-indirect.phpt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,6 @@ var_dump(unserialize(serialize(Foo::Bar)));
2121

2222
?>
2323
--EXPECTF--
24+
Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
25+
2426
Fatal error: Enums may not implement the Serializable interface in %s on line %d

Zend/tests/enum/no-implement-serializable.phpt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,6 @@ var_dump(unserialize(serialize(Foo::Bar)));
1919

2020
?>
2121
--EXPECTF--
22+
Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
23+
2224
Fatal error: Enums may not implement the Serializable interface in %s on line %d
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
Serializable deprecation
3+
--FILE--
4+
<?php
5+
6+
interface I extends Serializable {}
7+
abstract class A implements Serializable {}
8+
9+
class C extends A implements I {
10+
public function serialize(): string {}
11+
public function unserialize(string $data) {}
12+
}
13+
14+
class D extends A implements I {
15+
public function serialize(): string {}
16+
public function unserialize(string $data) {}
17+
public function __serialize(): array {}
18+
public function __unserialize(array $data) {}
19+
}
20+
21+
?>
22+
--EXPECTF--
23+
Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d

Zend/tests/traits/interface_003.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ var_dump(unserialize($o));
2121

2222
?>
2323
--EXPECTF--
24+
Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
2425
string(20) "C:3:"bar":6:{foobar}"
2526
string(6) "foobar"
2627
object(bar)#%d (0) {

Zend/zend_interfaces.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,10 @@ static int zend_implement_serializable(zend_class_entry *interface, zend_class_e
432432
if (!class_type->unserialize) {
433433
class_type->unserialize = zend_user_unserialize;
434434
}
435+
if (!(class_type->ce_flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)
436+
&& (!class_type->__serialize || !class_type->__unserialize)) {
437+
zend_error(E_DEPRECATED, "The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary)");
438+
}
435439
return SUCCESS;
436440
}
437441
/* }}}*/

ext/pdo/pdo_stmt.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,6 +1141,9 @@ static bool pdo_stmt_verify_mode(pdo_stmt_t *stmt, zend_long mode, uint32_t mode
11411141
ZEND_FALLTHROUGH;
11421142

11431143
case PDO_FETCH_CLASS:
1144+
if (flags & PDO_FETCH_SERIALIZE) {
1145+
php_error_docref(NULL, E_DEPRECATED, "The PDO::FETCH_SERIALIZE mode is deprecated");
1146+
}
11441147
return 1;
11451148
}
11461149
}

ext/pdo/tests/bug_44409.phpt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,10 @@ $stmt = $db->query("SELECT * FROM test");
4040
print_r($stmt->fetchAll(PDO::FETCH_CLASS|PDO::FETCH_SERIALIZE, "bug44409"));
4141

4242
?>
43-
--EXPECT--
43+
--EXPECTF--
44+
Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
45+
46+
Deprecated: PDOStatement::fetchAll(): The PDO::FETCH_SERIALIZE mode is deprecated in %s on line %d
4447
Method called: bug44409::unserialize('Data from DB')
4548
Array
4649
(

ext/pdo/tests/pdo_018.phpt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,11 @@ var_dump($stmt->fetchAll(PDO::FETCH_CLASS|PDO::FETCH_CLASSTYPE|PDO::FETCH_SERIAL
183183

184184
?>
185185
--EXPECTF--
186+
Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
187+
188+
Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
189+
190+
Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
186191
string(1) "3"
187192
array(3) {
188193
[0]=>
@@ -221,6 +226,8 @@ array(4) {
221226
string(172) "a:5:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:7:"BasePri";s:7:"Private";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";}"
222227
}
223228
===FAILURE===
229+
230+
Deprecated: PDOStatement::fetchAll(): The PDO::FETCH_SERIALIZE mode is deprecated in %s on line %d
224231
Exception:SQLSTATE[HY000]: General error: cannot unserialize class
225232
===COUNT===
226233
string(1) "3"
@@ -249,6 +256,8 @@ array(3) {
249256
}
250257
}
251258
===FETCHCLASS===
259+
260+
Deprecated: PDOStatement::fetchAll(): The PDO::FETCH_SERIALIZE mode is deprecated in %s on line %d
252261
TestBase::unserialize(a:3:{s:7:"BasePub";s:6:"Public";s:7:"BasePro";s:9:"Protected";s:7:"BasePri";s:7:"Private";})
253262
TestDerived::unserialize()
254263
TestBase::unserialize(a:5:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:7:"BasePri";s:7:"Private";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";})

ext/pdo_mysql/tests/bug46292.phpt

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,10 @@ MySQLPDOTest::skip();
1313
$pdoDb = MySQLPDOTest::factory();
1414

1515

16-
class myclass implements Serializable {
16+
class myclass {
1717
public function __construct() {
1818
printf("%s()\n", __METHOD__);
1919
}
20-
21-
public function serialize() {
22-
printf("%s()\n", __METHOD__);
23-
return "any data from serialize()";
24-
}
25-
26-
public function unserialize($dat) {
27-
printf("%s(%s)\n", __METHOD__, var_export($dat, true));
28-
return $dat;
29-
}
3020
}
3121

3222
class myclass2 extends myclass { }

ext/pdo_mysql/tests/pdo_mysql_stmt_fetch_serialize.phpt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ $db = MySQLPDOTest::factory();
120120
$db->exec('DROP TABLE IF EXISTS test');
121121
?>
122122
--EXPECTF--
123+
Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
123124
Creating an object, serializing it and writing it to DB...
124125
myclass::singleton(Creating object)
125126
myclass::__construct(Creating object)
@@ -133,6 +134,10 @@ object(myclass)#4 (1) {
133134
}
134135

135136
Using PDO::FETCH_CLASS|PDO::FETCH_SERIALIZE to fetch the object from DB and unserialize it...
137+
138+
Deprecated: PDOStatement::setFetchMode(): The PDO::FETCH_SERIALIZE mode is deprecated in %s on line %d
139+
140+
Deprecated: PDOStatement::fetch(): The PDO::FETCH_SERIALIZE mode is deprecated in %s on line %d
136141
myclass::unserialize('C:7:"myclass":19:{Data from serialize}')
137142
object(myclass)#%d (1) {
138143
["myprotected":protected]=>

ext/pdo_mysql/tests/pdo_mysql_stmt_fetch_serialize_simple.phpt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ MySQLPDOTest::skip();
6969
print "done!\n";
7070
?>
7171
--EXPECTF--
72+
Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
7273
Lets see what the Serializeable interface makes our object behave like...
7374
myclass::__construct('Called by script') - note that it must not be called when unserializing
7475
myclass::serialize()
@@ -77,14 +78,22 @@ object(myclass)#%d (0) {
7778
}
7879

7980
And now magic PDO using fetchAll(PDO::FETCH_CLASS|PDO::FETCH_SERIALIZE)...
81+
82+
Deprecated: PDOStatement::fetchAll(): The PDO::FETCH_SERIALIZE mode is deprecated in %s on line %d
8083
myclass::unserialize('Data fetched from DB to be given to unserialize()')
8184
object(myclass)#%d (0) {
8285
}
86+
87+
Deprecated: PDOStatement::fetchAll(): The PDO::FETCH_SERIALIZE mode is deprecated in %s on line %d
8388
myclass::unserialize('Data fetched from DB to be given to unserialize()')
8489
object(myclass)#%d (0) {
8590
}
8691

8792
And now PDO using setFetchMode(PDO::FETCH:CLASS|PDO::FETCH_SERIALIZE) + fetch()...
93+
94+
Deprecated: PDOStatement::setFetchMode(): The PDO::FETCH_SERIALIZE mode is deprecated in %s on line %d
95+
96+
Deprecated: PDOStatement::fetch(): The PDO::FETCH_SERIALIZE mode is deprecated in %s on line %d
8897
myclass::unserialize('Data fetched from DB to be given to unserialize()')
8998
object(myclass)#%d (0) {
9099
}

ext/session/tests/bug79031.phpt

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,22 +48,29 @@ echo "\n\n";
4848
var_dump($_SESSION);
4949

5050
?>
51-
--EXPECT--
52-
obj1|C:17:"SerializableClass":65:{a:1:{s:10:"sharedProp";O:8:"stdClass":1:{s:4:"name";s:4:"test";}}}obj2|C:17:"SerializableClass":28:{a:1:{s:10:"sharedProp";r:3;}}
51+
--EXPECTF--
52+
Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
53+
54+
Warning: session_start(): Session cannot be started after headers have already been sent in %s on line %d
55+
56+
Warning: session_encode(): Cannot encode non-existent session in %s on line %d
57+
58+
Warning: session_decode(): Session data cannot be decoded when there is no active session in %s on line %d
59+
5360

5461
array(2) {
5562
["obj1"]=>
56-
object(SerializableClass)#4 (1) {
63+
object(SerializableClass)#2 (1) {
5764
["sharedProp"]=>
58-
object(stdClass)#5 (1) {
65+
object(stdClass)#1 (1) {
5966
["name"]=>
6067
string(4) "test"
6168
}
6269
}
6370
["obj2"]=>
64-
object(SerializableClass)#6 (1) {
71+
object(SerializableClass)#3 (1) {
6572
["sharedProp"]=>
66-
object(stdClass)#5 (1) {
73+
object(stdClass)#1 (1) {
6774
["name"]=>
6875
string(4) "test"
6976
}

ext/standard/tests/serialize/005.phpt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ echo "===AutoNA===\n";
128128
var_dump(unserialize('O:22:"autoload_not_available":0:{}'));
129129
?>
130130
--EXPECTF--
131+
Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
131132
===O1===
132133
TestOld::__sleep()
133134
string(18) "O:7:"TestOld":0:{}"
@@ -152,12 +153,16 @@ object(TestNAOld)#%d (0) {
152153
===NANew===
153154
unserializer(TestNANew)
154155

156+
Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
157+
155158
Warning: Erroneous data format for unserializing 'TestNANew' in %s005.php on line %d
156159

157160
Notice: unserialize(): Error at offset 19 of 20 bytes in %s005.php on line %d
158161
bool(false)
159162
===NANew2===
160163
unserializer(TestNANew2)
164+
165+
Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
161166
TestNew::unserialize()
162167
object(TestNANew2)#%d (0) {
163168
}

ext/standard/tests/serialize/bug36424.phpt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,13 @@ echo "Done\n";
4444

4545
?>
4646
--EXPECTF--
47-
%aTEST
47+
-TEST
48+
49+
Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
50+
51+
Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
52+
53+
Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
4854
C:1:"c":108:{a:1:{s:1:"a";C:1:"a":81:{a:3:{s:1:"b";C:1:"b":30:{a:2:{s:1:"c";r:1;s:1:"a";r:3;}}s:1:"c";r:1;s:1:"a";r:3;}}}}
4955
bool(true)
5056
bool(true)

ext/standard/tests/serialize/bug64146.phpt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,10 @@ print $a->a[1]->b->c . "\n";
5353

5454
?>
5555
Done
56-
--EXPECT--
56+
--EXPECTF--
5757
Test
58+
59+
Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
5860
1
5961
2
6062
Done

ext/standard/tests/serialize/bug64354_3.phpt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,6 @@ try {
2525
var_dump($e->getMessage());
2626
}
2727
?>
28-
--EXPECT--
28+
--EXPECTF--
29+
Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
2930
string(6) "Failed"

ext/standard/tests/serialize/bug65481.phpt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ $token = serialize($token);
3535

3636
?>
3737
Done
38-
--EXPECT--
38+
--EXPECTF--
3939
Test
40+
41+
Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
4042
Done

ext/standard/tests/serialize/bug70172.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ function ptr2str($ptr)
4141
}
4242
?>
4343
--EXPECTF--
44+
Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
4445
array(2) {
4546
[0]=>
4647
int(1)

ext/standard/tests/serialize/bug70172_2.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ function ptr2str($ptr)
4848
}
4949
?>
5050
--EXPECTF--
51+
Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
5152
array(2) {
5253
[0]=>
5354
object(obj2)#%d (1) {

ext/standard/tests/serialize/bug70219.phpt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,11 @@ for ($i = 0; $i < 5; $i++) {
2929
var_dump($data);
3030
?>
3131
--EXPECTF--
32-
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s on line %d
32+
Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
33+
34+
Warning: session_start(): Session cannot be started after headers have already been sent in %s on line %d
35+
36+
Warning: session_decode(): Session data cannot be decoded when there is no active session in %s on line %d
3337

3438
Notice: unserialize(): Error at offset 55 of 56 bytes in %s on line %d
3539
bool(false)

ext/standard/tests/serialize/bug70219_1.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ var_dump($data);
3434
var_dump($_SESSION);
3535
?>
3636
--EXPECTF--
37+
Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
3738
array(2) {
3839
[0]=>
3940
object(obj)#%d (1) {

ext/standard/tests/serialize/bug70436.phpt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ function ptr2str($ptr)
4646
?>
4747
DONE
4848
--EXPECTF--
49+
Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
50+
4951
Notice: unserialize(): Error at offset 0 of 3 bytes in %sbug70436.php on line %d
5052

5153
Notice: unserialize(): Error at offset 93 of 94 bytes in %sbug70436.php on line %d

ext/standard/tests/serialize/bug71940.phpt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ $serialized = serialize([$entry1, $entry2]);
4343
print_r(unserialize($serialized));
4444

4545
?>
46-
--EXPECT--
46+
--EXPECTF--
47+
Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
4748
Array
4849
(
4950
[0] => Entry Object

ext/standard/tests/serialize/bug72663_2.phpt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ var_dump(unserialize($exploit));
1919

2020
?>
2121
--EXPECTF--
22+
Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
23+
2224
Notice: unserialize(): Unexpected end of serialized data in %s on line %d
2325

2426
Notice: unserialize(): Error at offset 49 of 50 bytes in %s on line %d

ext/standard/tests/serialize/bug80411.phpt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ $recovered = unserialize($data);
2121
var_export($recovered);
2222

2323
?>
24-
--EXPECT--
24+
--EXPECTF--
25+
Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s on line %d
2526
a:4:{i:0;N;i:1;N;i:2;s:6:"endcap";i:3;R:4;}
2627
array (
2728
0 => NULL,

0 commit comments

Comments
 (0)