Skip to content

Commit 37674f1

Browse files
Drop more usages of Serializable
1 parent ccd4bbe commit 37674f1

File tree

26 files changed

+205
-98
lines changed

26 files changed

+205
-98
lines changed

UPGRADE-4.3.md

+6
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ HttpFoundation
4545
* The `FileinfoMimeTypeGuesser` class has been deprecated,
4646
use `Symfony\Component\Mime\FileinfoMimeTypeGuesser` instead.
4747

48+
Routing
49+
-------
50+
51+
* Implementing `Serializable` for `Route` and `CompiledRoute` is deprecated; if you serialize them, please
52+
ensure your unserialization logic can recover from a failure related to an updated serialization format
53+
4854
Security
4955
--------
5056

UPGRADE-5.0.md

+6
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,12 @@ Process
219219
$process = Process::fromShellCommandline('ls -l');
220220
```
221221

222+
Routing
223+
-------
224+
225+
* `Route` and `CompiledRoute` don't implement `Serializable` anymore; if you serialize them, please
226+
ensure your unserialization logic can recover from a failure related to an updated serialization format
227+
222228
Security
223229
--------
224230

src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AppKernel.php

+4-5
Original file line numberDiff line numberDiff line change
@@ -79,15 +79,14 @@ protected function build(ContainerBuilder $container)
7979
$container->register('logger', NullLogger::class);
8080
}
8181

82-
public function serialize()
82+
public function __sleep()
8383
{
84-
return serialize([$this->varDir, $this->testCase, $this->rootConfig, $this->getEnvironment(), $this->isDebug()]);
84+
return ['varDir', 'testCase', 'rootConfig', 'environment', 'debug'];
8585
}
8686

87-
public function unserialize($str)
87+
public function __wakeup()
8888
{
89-
$a = unserialize($str);
90-
$this->__construct($a[0], $a[1], $a[2], $a[3], $a[4]);
89+
$this->__construct($this->varDir, $this->testCase, $this->rootConfig, $this->environment, $this->debug);
9190
}
9291

9392
protected function getKernelParameters()

src/Symfony/Component/Cache/Tests/Adapter/AdapterTestCase.php

+2-7
Original file line numberDiff line numberDiff line change
@@ -215,14 +215,9 @@ public function testPrune()
215215
}
216216
}
217217

218-
class NotUnserializable implements \Serializable
218+
class NotUnserializable
219219
{
220-
public function serialize()
221-
{
222-
return serialize(123);
223-
}
224-
225-
public function unserialize($ser)
220+
public function __wakeup()
226221
{
227222
throw new \Exception(__CLASS__);
228223
}

src/Symfony/Component/Cache/Tests/Psr16CacheTest.php

+2-7
Original file line numberDiff line numberDiff line change
@@ -159,14 +159,9 @@ protected function isPruned($cache, $name)
159159
}
160160
}
161161

162-
class NotUnserializable implements \Serializable
162+
class NotUnserializable
163163
{
164-
public function serialize()
165-
{
166-
return serialize(123);
167-
}
168-
169-
public function unserialize($ser)
164+
public function __wakeup()
170165
{
171166
throw new \Exception(__CLASS__);
172167
}

src/Symfony/Component/Cache/Tests/Simple/CacheTestCase.php

+2-7
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,9 @@ public function testPrune()
132132
}
133133
}
134134

135-
class NotUnserializable implements \Serializable
135+
class NotUnserializable
136136
{
137-
public function serialize()
138-
{
139-
return serialize(123);
140-
}
141-
142-
public function unserialize($ser)
137+
public function __wakeup()
143138
{
144139
throw new \Exception(__CLASS__);
145140
}

src/Symfony/Component/Debug/Tests/phpt/fatal_with_nested_handlers.phpt

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ var_dump([
2424
$eHandler[0]->setExceptionHandler('print_r');
2525

2626
if (true) {
27-
class Broken implements \Serializable
27+
class Broken implements \JsonSerializable
2828
{
2929
}
3030
}
@@ -37,6 +37,6 @@ array(1) {
3737
}
3838
object(Symfony\Component\Debug\Exception\FatalErrorException)#%d (%d) {
3939
["message":protected]=>
40-
string(199) "Error: Class Symfony\Component\Debug\Broken contains 2 abstract methods and must therefore be declared abstract or implement the remaining methods (Serializable::serialize, Serializable::unserialize)"
40+
string(179) "Error: Class Symfony\Component\Debug\Broken contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (JsonSerializable::jsonSerialize)"
4141
%a
4242
}

src/Symfony/Component/Form/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ CHANGELOG
99
* added `block_prefix` option to `BaseType`.
1010
* added `help_html` option to display the `help` text as HTML.
1111
* `FormError` doesn't implement `Serializable` anymore
12+
* `FormDataCollector` has been marked as `final`
1213
* added `label_translation_parameters`, `attr_translation_parameters`, `help_translation_parameters` options
1314
to `FormType` to pass translation parameters to form labels, attributes (`placeholder` and `title`) and help text respectively.
1415
The passed parameters will replace placeholders in translation messages.

src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php

+9-2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
*
2828
* @author Robert Schönthal <robert.schoenthal@gmail.com>
2929
* @author Bernhard Schussek <bschussek@gmail.com>
30+
*
31+
* @final since Symfony 4.3
3032
*/
3133
class FormDataCollector extends DataCollector implements FormDataCollectorInterface
3234
{
@@ -229,15 +231,20 @@ public function getData()
229231
return $this->data;
230232
}
231233

232-
public function serialize()
234+
/**
235+
* @internal
236+
*/
237+
public function __sleep()
233238
{
234239
foreach ($this->data['forms_by_hash'] as &$form) {
235240
if (isset($form['type_class']) && !$form['type_class'] instanceof ClassStub) {
236241
$form['type_class'] = new ClassStub($form['type_class']);
237242
}
238243
}
239244

240-
return serialize($this->cloneVar($this->data));
245+
$this->data = $this->cloneVar($this->data);
246+
247+
return parent::__sleep();
241248
}
242249

243250
/**

src/Symfony/Component/Form/composer.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
"symfony/config": "~3.4|~4.0",
3232
"symfony/console": "~3.4|~4.0",
3333
"symfony/http-foundation": "~3.4|~4.0",
34-
"symfony/http-kernel": "~3.4|~4.0",
34+
"symfony/http-kernel": "~4.3",
3535
"symfony/security-csrf": "~3.4|~4.0",
3636
"symfony/translation": "~4.2",
3737
"symfony/var-dumper": "~3.4|~4.0"
@@ -41,7 +41,7 @@
4141
"symfony/dependency-injection": "<3.4",
4242
"symfony/doctrine-bridge": "<3.4",
4343
"symfony/framework-bundle": "<3.4",
44-
"symfony/http-kernel": "<3.4",
44+
"symfony/http-kernel": "<4.3",
4545
"symfony/translation": "<4.2",
4646
"symfony/twig-bridge": "<3.4.5|<4.0.5,>=4.0"
4747
},

src/Symfony/Component/HttpKernel/CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,14 @@ CHANGELOG
44
4.3.0
55
-----
66

7+
* `KernelInterface` doesn't extend `Serializable` anymore
8+
* deprecated the `Kernel::serialize()` and `unserialize()` methods
79
* increased the priority of `Symfony\Component\HttpKernel\EventListener\AddRequestFormatsListener`
810
* made `Symfony\Component\HttpKernel\EventListenerLocaleListener` set the default locale early
911
* made `FileLinkFormatter` final and not implement `Serializable` anymore
12+
* the base `DataCollector` doesn't implement `Serializable` anymore, you should
13+
store all the serialized state in the data property instead
14+
* `DumpDataCollector` has been marked as `final`
1015

1116
4.2.0
1217
-----

src/Symfony/Component/HttpKernel/DataCollector/DataCollector.php

+29-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
* @author Fabien Potencier <fabien@symfony.com>
2626
* @author Bernhard Schussek <bschussek@symfony.com>
2727
*/
28-
abstract class DataCollector implements DataCollectorInterface, \Serializable
28+
abstract class DataCollector implements DataCollectorInterface
2929
{
3030
protected $data = [];
3131

@@ -34,16 +34,26 @@ abstract class DataCollector implements DataCollectorInterface, \Serializable
3434
*/
3535
private $cloner;
3636

37+
/**
38+
* @deprecated since Symfony 4.3, store all the serialized state in the data property instead
39+
*/
3740
public function serialize()
3841
{
42+
@trigger_error(sprintf('The "%s" method is deprecated since Symfony 4.3, store all the serialized state in the data property instead.', __METHOD__), E_USER_DEPRECATED);
43+
3944
$trace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 2);
4045
$isCalledFromOverridingMethod = isset($trace[1]['function'], $trace[1]['object']) && 'serialize' === $trace[1]['function'] && $this === $trace[1]['object'];
4146

4247
return $isCalledFromOverridingMethod ? $this->data : serialize($this->data);
4348
}
4449

50+
/**
51+
* @deprecated since Symfony 4.3, store all the serialized state in the data property instead
52+
*/
4553
public function unserialize($data)
4654
{
55+
@trigger_error(sprintf('The "%s" method is deprecated since Symfony 4.3, store all the serialized state in the data property instead.', __METHOD__), E_USER_DEPRECATED);
56+
4757
$this->data = \is_array($data) ? $data : unserialize($data);
4858
}
4959

@@ -93,4 +103,22 @@ protected function getCasters()
93103
},
94104
];
95105
}
106+
107+
public function __sleep()
108+
{
109+
if (__CLASS__ !== $c = (new \ReflectionMethod($this, 'serialize'))->getDeclaringClass()->name) {
110+
@trigger_error(sprintf('Implementing the "%s::serialize()" method is deprecated since Symfony 4.3, store all the serialized state in the "data" property instead.', $c), E_USER_DEPRECATED);
111+
$this->data = $this->serialize();
112+
}
113+
114+
return ['data'];
115+
}
116+
117+
public function __wakeup()
118+
{
119+
if (__CLASS__ !== $c = (new \ReflectionMethod($this, 'unserialize'))->getDeclaringClass()->name) {
120+
@trigger_error(sprintf('Implementing the "%s::unserialize()" method is deprecated since Symfony 4.3, store all the serialized state in the "data" property instead.', $c), E_USER_DEPRECATED);
121+
$this->unserialize($this->data);
122+
}
123+
}
96124
}

src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php

+31-8
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525

2626
/**
2727
* @author Nicolas Grekas <p@tchwork.com>
28+
*
29+
* @final since Symfony 4.3
2830
*/
2931
class DumpDataCollector extends DataCollector implements DataDumperInterface
3032
{
@@ -85,6 +87,9 @@ public function dump(Data $data)
8587
$this->isCollected = false;
8688
}
8789

90+
if (!$this->dataCount) {
91+
$this->data = [];
92+
}
8893
$this->data[] = compact('data', 'name', 'file', 'line', 'fileExcerpt');
8994
++$this->dataCount;
9095

@@ -95,6 +100,10 @@ public function dump(Data $data)
95100

96101
public function collect(Request $request, Response $response, \Exception $exception = null)
97102
{
103+
if (!$this->dataCount) {
104+
$this->data = [];
105+
}
106+
98107
// Sub-requests and programmatic calls stay in the collected profile.
99108
if ($this->dumper || ($this->requestStack && $this->requestStack->getMasterRequest() !== $request) || $request->isXmlHttpRequest() || $request->headers->has('Origin')) {
100109
return;
@@ -136,28 +145,38 @@ public function reset()
136145
$this->clonesIndex = 0;
137146
}
138147

139-
public function serialize()
148+
/**
149+
* @internal
150+
*/
151+
public function __sleep()
140152
{
153+
if (!$this->dataCount) {
154+
$this->data = [];
155+
}
156+
141157
if ($this->clonesCount !== $this->clonesIndex) {
142-
return 'a:0:{}';
158+
return [];
143159
}
144160

145161
$this->data[] = $this->fileLinkFormat;
146162
$this->data[] = $this->charset;
147-
$ser = serialize($this->data);
148-
$this->data = [];
149163
$this->dataCount = 0;
150164
$this->isCollected = true;
151165

152-
return $ser;
166+
return parent::__sleep();
153167
}
154168

155-
public function unserialize($data)
169+
/**
170+
* @internal
171+
*/
172+
public function __wakeup()
156173
{
157-
$this->data = unserialize($data);
174+
parent::__wakeup();
175+
158176
$charset = array_pop($this->data);
159177
$fileLinkFormat = array_pop($this->data);
160178
$this->dataCount = \count($this->data);
179+
161180
self::__construct($this->stopwatch, $fileLinkFormat, $charset);
162181
}
163182

@@ -178,6 +197,10 @@ public function getDumps($format, $maxDepthLimit = -1, $maxItemsPerDepth = -1)
178197
}
179198
$dumps = [];
180199

200+
if (!$this->dataCount) {
201+
return $this->data = [];
202+
}
203+
181204
foreach ($this->data as $dump) {
182205
$dumper->dump($dump['data']->withMaxDepth($maxDepthLimit)->withMaxItemsPerDepth($maxItemsPerDepth));
183206
$dump['data'] = stream_get_contents($data, -1, 0);
@@ -196,7 +219,7 @@ public function getName()
196219

197220
public function __destruct()
198221
{
199-
if (0 === $this->clonesCount-- && !$this->isCollected && $this->data) {
222+
if (0 === $this->clonesCount-- && !$this->isCollected && $this->dataCount) {
200223
$this->clonesCount = 0;
201224
$this->isCollected = true;
202225

src/Symfony/Component/HttpKernel/Kernel.php

+34
Original file line numberDiff line numberDiff line change
@@ -833,15 +833,49 @@ public static function stripComments($source)
833833
return $output;
834834
}
835835

836+
/**
837+
* @deprecated since Symfony 4.3
838+
*/
836839
public function serialize()
837840
{
841+
@trigger_error(sprintf('The "%s" method is deprecated since Symfony 4.3.', __METHOD__), E_USER_DEPRECATED);
842+
838843
return serialize([$this->environment, $this->debug]);
839844
}
840845

846+
/**
847+
* @deprecated since Symfony 4.3
848+
*/
841849
public function unserialize($data)
842850
{
851+
@trigger_error(sprintf('The "%s" method is deprecated since Symfony 4.3.', __METHOD__), E_USER_DEPRECATED);
843852
list($environment, $debug) = unserialize($data, ['allowed_classes' => false]);
844853

845854
$this->__construct($environment, $debug);
846855
}
856+
857+
public function __sleep()
858+
{
859+
if (__CLASS__ !== $c = (new \ReflectionMethod($this, 'serialize'))->getDeclaringClass()->name) {
860+
@trigger_error(sprintf('Implementing the "%s::serialize()" method is deprecated since Symfony 4.3.', $c), E_USER_DEPRECATED);
861+
$this->serialized = $this->serialize();
862+
863+
return ['serialized'];
864+
}
865+
866+
return ['environment', 'debug'];
867+
}
868+
869+
public function __wakeup()
870+
{
871+
if (__CLASS__ !== $c = (new \ReflectionMethod($this, 'serialize'))->getDeclaringClass()->name) {
872+
@trigger_error(sprintf('Implementing the "%s::serialize()" method is deprecated since Symfony 4.3.', $c), E_USER_DEPRECATED);
873+
$this->unserialize($this->serialized);
874+
unset($this->serialized);
875+
876+
return;
877+
}
878+
879+
$this->__construct($this->environment, $this->debug);
880+
}
847881
}

0 commit comments

Comments
 (0)