8000 feature #10457 [Serializer] Unify usage of normalizer cache (Berdir) · symfony/symfony@cb147ec · GitHub
[go: up one dir, main page]

Skip to content

Commit cb147ec

Browse files
committed
feature #10457 [Serializer] Unify usage of normalizer cache (Berdir)
This PR was squashed before being merged into the 2.5-dev branch (closes #10457). Discussion ---------- [Serializer] Unify usage of normalizer cache | Q | A | ------------- | --- | Bug fix? | no (unless performance problems are considered bugs) | New feature? | no | BC breaks? | no (unless the exception structure should be simplified) | Deprecations? | no | Tests pass? | yes ( I had some test fails locally when running the whole suite, but not related to Serializer) | Fixed tickets | | License | MIT | Doc PR | Some clean-up of the Serialization class, which has methods to get the Normalizer/Denormalizer but then repeats that logic in normalizeObject()/denormalizeObject(). Took great care to keep the exception behavior exactly like it is now as the tests depend on it, but it's strange (the methods use different exception classes if no normalizer is found and the "no normalizer" LogicException only exists in normalizeObject/denomalizeObject. That could easily be simplified further, to the point where those functions could easily be merged into the calling methods, as it would just be a single line of code. There is also a duplicate call to $this->normalizeObject() in normalize() that just exists to throw the LogicException for Symfony\Component\Serializer\Tests\SerializerTest::testSerializeNoNormalizer. Other tests do not except that to be thrown there, though. Also noticed that getNormalizer()/getDenormalizer() are documented as @inheritdocs, which is a lie as they are private. Added some basic docs there. This is performance relevant, as not having the cache in the getter methods means all normalizers are checked again to verify if a normalizer supports the data. Commits ------- e7389aa Move normalizer cache to getNormalier()/getDenormalizer(), use those in normalizeObject()/denormalizeObject()
2 parents 5a4885e + e7389aa commit cb147ec

File tree

1 file changed

+41
-50
lines changed

1 file changed

+41
-50
lines changed

src/Symfony/Component/Serializer/Serializer.php

Lines changed: 41 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
use Symfony\Component\Serializer\Encoder\DecoderInterface;
1818
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
1919
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
20-
use Symfony\Component\Serializer\Exception\RuntimeException;
2120
use Symfony\Component\Serializer\Exception\LogicException;
2221
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
2322

@@ -144,55 +143,68 @@ public function denormalize($data, $type, $format = null, array $context = array
144143
*/
145144
public function supportsNormalization($data, $format = null)
146145
{
147-
try {
148-
$this->getNormalizer($data, $format);
149-
} catch (RuntimeException $e) {
150-
return false;
151-
}
152-
153-
return true;
146+
return (bool) $this->getNormalizer($data, $format);
154147
}
155148

156149
/**
157150
* {@inheritdoc}
158151
*/
159152
public function supportsDenormalization($data, $type, $format = null)
160153
{
161-
try {
162-
$this->getDenormalizer($data, $type, $format = null);
163-
} catch (RuntimeException $e) {
164-
return false;
165-
}
166-
167-
return true;
154+
return (bool) $this->getDenormalizer($data, $type, $format);
168155
}
169156

170157
/**
171-
* {@inheritdoc}
158+
* Returns a matching normalizer.
159+
*
160+
* @param object $data The object to get the serializer for
161+
* @param string $format format name, present to give the option to normalizers to act differently based on formats
162+
*
163+
* @return NormalizerInterface|null
172164
*/
173-
private function getNormalizer($data, $format = null)
165+
private function getNormalizer($data, $format)
174166
{
167+
168+
$class = get_class($data);
169+
if (isset($this->normalizerCache[$class][$format])) {
170+
return $this->normalizerCache[$class][$format];
171+
}
172+
175173
foreach ($this->normalizers as $normalizer) {
176174
if ($normalizer instanceof NormalizerInterface && $normalizer->supportsNormalization($data, $format)) {
175+
$this->normalizerCache[$class][$format] = $normalizer;
176+
177177
return $normalizer;
178178
}
179179
}
180180

181-
throw new RuntimeException(sprintf('No normalizer found for format "%s".', $format));
181+
return null;
182182
}
183183

184184
/**
185-
* {@inheritdoc}
185+
* Returns a matching denormalizer.
186+
*
187+
* @param mixed $data data to restore
188+
* @param string $class the expected class to instantiate
189+
* @param string $format format name, present to give the option to normalizers to act differently based on formats
190+
*
191+
* @return DenormalizerInterface|null
186192
*/
187-
private function getDenormalizer($data, $type, $format = null)
193+
private function getDenormalizer($data, $class, $format)
188194
{
195+
if (isset($this->denormalizerCache[$class][$format])) {
196+
return $this->denormalizerCache[$class][$format];
197+
}
198+
189199
foreach ($this->normalizers as $normalizer) {
190-
if ($normalizer instanceof DenormalizerInterface && $normalizer->supportsDenormalization($data, $type, $format)) {
200+
if ($normalizer instanceof DenormalizerInterface && $normalizer->supportsDenormalization($data, $class, $format)) {
201+
$this->denormalizerCache[$class][$format] = $normalizer;
202+
191203
return $normalizer;
192204
}
193205
}
194206

195-
throw new RuntimeException(sprintf('No denormalizer found for format "%s".', $format));
207+
return null;
196208
}
197209

198210
/**
@@ -223,27 +235,16 @@ final public function decode($data, $format, array $context = array())
223235
* @throws LogicException
224236
* @throws UnexpectedValueException
225237
*/
226-
private function normalizeObject($object, $format = null, array $context = array())
238+
private function normalizeObject($object, $format, array $context = array())
227239
{
228240
if (!$this->normalizers) {
229241
throw new LogicException('You must register at least one normalizer to be able to normalize objects.');
230242
}
231243

232-
$class = get_class($object);
233-
if (isset($this->normalizerCache[$class][$format])) {
234-
return $this->normalizerCache[$class][$format]->normalize($object, $format, $context);
235-
}
236-
237-
foreach ($this->normalizers as $normalizer) {
238-
if ($normalizer instanceof NormalizerInterface
239-
&& $normalizer->supportsNormalization($object, $format)) {
240-
$this->normalizerCache[$class][$format] = $normalizer;
241-
242-
return $normalizer->normalize($object, $format, $context);
243-
}
244+
if ($normalizer = $this->getNormalizer($object, $format)) {
245+
return $normalizer->normalize($object, $format, $context);
244246
}
245-
246-
throw new UnexpectedValueException(sprintf('Could not normalize object of type %s, no supporting normalizer found.', $class));
247+
throw new UnexpectedValueException(sprintf('Could not normalize object of type %s, no supporting normalizer found.', get_class($object)));
247248
}
248249

249250
/**
@@ -259,25 +260,15 @@ private function normalizeObject($object, $format = null, array $context = array
259260
* @throws LogicException
260261
* @throws UnexpectedValueException
261262
*/
262-
private function denormalizeObject($data, $class, $format = null, array $context = array())
263+
private function denormalizeObject($data, $class, $format, array $context = array())
263264
{
264265
if (!$this->normalizers) {
265266
throw new LogicException('You must register at least one normalizer to be able to denormalize objects.');
266267
}
267268

268-
if (isset($this->denormalizerCache[$class][$format])) {
269-
return $this->denormalizerCache[$class][$format]->denormalize($data, $class, $format, $context);
270-
}
271-
272-
foreach ($this->normalizers as $normalizer) {
273-
if ($normalizer instanceof DenormalizerInterface
274-
&& $normalizer->supportsDenormalization($data, $class, $format)) {
275-
$this->denormalizerCache[$class][$format] = $normalizer;
276-
277-
return $normalizer->denormalize($data, $class, $format, $context);
278-
}
269+
if ($normalizer = $this->getDenormalizer($data, $class, $format)) {
270+
return $normalizer->denormalize($data, $class, $format, $context);
279271
}
280-
281272
throw new UnexpectedValueException(sprintf('Could not denormalize object of type %s, no supporting normalizer found.', $class));
282273
}
283274

0 commit comments

Comments
 (0)
0