Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 683f0f7

Browse files
dunglasfabpot
authored andcommitted
[Serializer] Improve ObjectNormalizer performance
1 parent 1abfecf commit 683f0f7

File tree

2 files changed

+76
-37
lines changed

2 files changed

+76
-37
lines changed

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

Lines 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

Lines 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)