Symfony\Component\Serializer\Exception\CircularReferenceException: A circular reference has been detected (configured limit: 1) in /var/www/app/src/Controller/ApiController.php:56
ID: php/symfony-serializer-circular-reference
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| Symfony 5.4 | active | — | — | — |
| Symfony 6.4 | active | — | — | — |
| Symfony 7.0 | active | — | — | — |
| PHP 8.0 | active | — | — | — |
| PHP 8.1 | active | — | — | — |
Root Cause
The Symfony Serializer component detected a circular reference in an object graph (e.g., a parent-child relationship where both sides reference each other) and the configured circular reference limit was exceeded.
generic中文
Symfony序列化组件在对象图中检测到循环引用(例如,父子关系中双方互相引用),且超出了配置的循环引用限制。
Official Documentation
https://symfony.com/doc/current/components/serializer.html#handling-circular-referencesWorkarounds
-
85% success Use the @Ignore annotation or the 'ignored_attributes' option to skip specific properties during serialization. Example in PHP: $context = ['ignored_attributes' => ['child', 'parent']]; $serializer->serialize($object, 'json', $context);
Use the @Ignore annotation or the 'ignored_attributes' option to skip specific properties during serialization. Example in PHP: $context = ['ignored_attributes' => ['child', 'parent']]; $serializer->serialize($object, 'json', $context);
-
90% success Implement a custom circular reference handler: $encoder = new JsonEncoder(); $normalizer = new ObjectNormalizer(); $normalizer->setCircularReferenceHandler(function ($object) { return $object->getId(); }); $serializer = new Serializer([$normalizer], [$encoder]);
Implement a custom circular reference handler: $encoder = new JsonEncoder(); $normalizer = new ObjectNormalizer(); $normalizer->setCircularReferenceHandler(function ($object) { return $object->getId(); }); $serializer = new Serializer([$normalizer], [$encoder]); -
80% success Use the MaxDepth annotation to limit serialization depth: #[MaxDepth(1)] on the property that causes the cycle. Then enable max depth handling: $context = [AbstractNormalizer::ENABLE_MAX_DEPTH => true];
Use the MaxDepth annotation to limit serialization depth: #[MaxDepth(1)] on the property that causes the cycle. Then enable max depth handling: $context = [AbstractNormalizer::ENABLE_MAX_DEPTH => true];
中文步骤
Use the @Ignore annotation or the 'ignored_attributes' option to skip specific properties during serialization. Example in PHP: $context = ['ignored_attributes' => ['child', 'parent']]; $serializer->serialize($object, 'json', $context);
Implement a custom circular reference handler: $encoder = new JsonEncoder(); $normalizer = new ObjectNormalizer(); $normalizer->setCircularReferenceHandler(function ($object) { return $object->getId(); }); $serializer = new Serializer([$normalizer], [$encoder]);Use the MaxDepth annotation to limit serialization depth: #[MaxDepth(1)] on the property that causes the cycle. Then enable max depth handling: $context = [AbstractNormalizer::ENABLE_MAX_DEPTH => true];
Dead Ends
Common approaches that don't work:
-
50% fail
This only postpones the issue; the serializer will still attempt to traverse the circular graph, potentially causing memory exhaustion or infinite loops.
-
80% fail
Removing getters breaks the application logic and may cause other features to fail; it is a drastic and unnecessary workaround.
-
90% fail
This flag only changes error handling behavior; it does not prevent the circular reference from being detected and thrown by the serializer.