Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 683f0f7

Browse filesBrowse files
dunglasfabpot
authored andcommitted
[Serializer] Improve ObjectNormalizer performance
1 parent 1abfecf commit 683f0f7
Copy full SHA for 683f0f7

File tree

2 files changed

+76
-37
lines changed
Filter options

2 files changed

+76
-37
lines changed

‎src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php
+63-36Lines changed: 63 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
*/
2727
class ObjectNormalizer extends AbstractNormalizer
2828
{
29+
private static $attributesCache = array();
30+
2931
/**
3032
* @var PropertyAccessorInterface
3133
*/
@@ -58,42 +60,7 @@ public function normalize($object, $format = null, array $context = array())
5860
}
5961

6062
$data = array();
61-
$attributes = $this->getAllowedAttributes($object, $context, true);
62-
63-
// If not using groups, detect manually
64-
if (false === $attributes) {
65-
$attributes = array();
66-
67-
// methods
68-
$reflClass = new \ReflectionClass($object);
69-
foreach ($reflClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflMethod) {
70-
if (
71-
!$reflMethod->isStatic() &&
72-
!$reflMethod->isConstructor() &&
73-
!$reflMethod->isDestructor() &&
74-
0 === $reflMethod->getNumberOfRequiredParameters()
75-
) {
76-
$name = $reflMethod->getName();
77-
78-
if (strpos($name, 'get') === 0 || strpos($name, 'has') === 0) {
79-
// getters and hassers
80-
$attributes[lcfirst(substr($name, 3))] = true;
81-
} elseif (strpos($name, 'is') === 0) {
82-
// issers
83-
$attributes[lcfirst(substr($name, 2))] = true;
84-
}
85-
}
86-
}
87-
88-
// properties
89-
foreach ($reflClass->getProperties(\ReflectionProperty::IS_PUBLIC) as $reflProperty) {
90-
if (!$reflProperty->isStatic()) {
91-
$attributes[$reflProperty->getName()] = true;
92-
}
93-
}
94-
95-
$attributes = array_keys($attributes);
96-
}
63+
$attributes = $this->getAttributes($object, $context);
9764

9865
foreach ($attributes as $attribute) {
9966
if (in_array($attribute, $this->ignoredAttributes)) {
@@ -162,4 +129,64 @@ public function denormalize($data, $class, $format = null, array $context = arra
162129

163130
return $object;
164131
}
132+
133+
/**
134+
* Gets and caches attributes for this class and context.
135+
*
136+
* @param object $object
137+
* @param array $context
138+
*
139+
* @return array
140+
*/
141+
private function getAttributes($object, array $context)
142+
{
143+
$key = sprintf('%s-%s', get_class($object), serialize($context));
144+
145+
if (isset(self::$attributesCache[$key])) {
146+
return self::$attributesCache[$key];
147+
}
148+
149+
$allowedAttributes = $this->getAllowedAttributes($object, $context, true);
150+
151+
if (false !== $allowedAttributes) {
152+
return self::$attributesCache[$key] = $allowedAttributes;
153+
}
154+
155+
// If not using groups, detect manually
156+
$attributes = array();
157+
158+
// methods
159+
$reflClass = new \ReflectionClass($object);
160+
foreach ($reflClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflMethod) {
161+
if (
162+
$reflMethod->getNumberOfRequiredParameters() !== 0 ||
163+
$reflMethod->isStatic() ||
164+
$reflMethod->isConstructor() ||
165+
$reflMethod->isDestructor()
166+
) {
167+
continue;
168+
}
169+
170+
$name = $reflMethod->getName();
171+
172+
if (strpos($name, 'get') === 0 || strpos($name, 'has') === 0) {
173+
// getters and hassers
174+
$attributes[lcfirst(substr($name, 3))] = true;
175+
} elseif (strpos($name, 'is') === 0) {
176+
// issers
177+
$attributes[lcfirst(substr($name, 2))] = true;
178+
}
179+
}
180+
181+
// properties
182+
foreach ($reflClass->getProperties(\ReflectionProperty::IS_PUBLIC) as $reflProperty) {
183+
if ($reflProperty->isStatic()) {
184+
continue;
185+
}
186+
187+
$attributes[$reflProperty->getName()] = true;
188+
}
189+
190+
return self::$attributesCache[$key] = array_keys($attributes);
191+
}
165192
}

‎src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php
+13-1Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
class ObjectNormalizerTest extends \PHPUnit_Framework_TestCase
3030
{
3131
/**
32-
* @var ObjectNormalizerTest
32+
* @var ObjectNormalizer
3333
*/
3434
private $normalizer;
3535
/**
@@ -239,6 +239,18 @@ public function testGroupsDenormalize()
239239
$this->assertEquals($obj, $normalized);
240240
}
241241

242+
public function testNormalizeNoPropertyInGroup()
243+
{
244+
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
245+
$this->normalizer = new ObjectNormalizer($classMetadataFactory);
246+
$this->normalizer->setSerializer($this->serializer);
247+
248+
$obj = new GroupDummy();
249+
$obj->setFoo('foo');
250+
251+
$this->assertEquals(array(), $this->normalizer->normalize($obj, null, array('groups' => array('notExist'))));
252+
}
253+
242254
public function testGroupsNormalizeWithNameConverter()
243255
{
244256
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.