Serializer.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. <?php
  2. namespace Symfony\Component\Serializer;
  3. use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
  4. use Symfony\Component\Serializer\Encoder\EncoderInterface;
  5. /*
  6. * This file is part of the Symfony framework.
  7. *
  8. * (c) Fabien Potencier <fabien@symfony.com>
  9. *
  10. * This source file is subject to the MIT license that is bundled
  11. * with this source code in the file LICENSE.
  12. */
  13. /**
  14. * Serializer serializes and deserializes data
  15. *
  16. * objects are turned into arrays by normalizers
  17. * arrays are turned into various output formats by encoders
  18. *
  19. * $serializer->serialize($obj, 'xml')
  20. * $serializer->decode($data, 'xml')
  21. * $serializer->denormalizeObject($data, 'Class', 'xml')
  22. *
  23. * @author Jordi Boggiano <j.boggiano@seld.be>
  24. */
  25. class Serializer implements SerializerInterface
  26. {
  27. private $normalizers = array();
  28. private $encoders = array();
  29. protected $normalizerCache = array();
  30. /**
  31. * @param mixed $value value to test
  32. * @return Boolean whether the type is a structured type (array + objects)
  33. */
  34. public function isStructuredType($value)
  35. {
  36. return null !== $value && !is_scalar($value);
  37. }
  38. /**
  39. * {@inheritdoc}
  40. */
  41. public function serialize($data, $format)
  42. {
  43. return $this->encode($this->normalize($data, $format), $format);
  44. }
  45. /**
  46. * {@inheritDoc}
  47. */
  48. public function deserialize($data, $type, $format) {
  49. return $this->denormalize($this->decode($data, $format), $type, $format);
  50. }
  51. /**
  52. * {@inheritdoc}
  53. */
  54. public function normalizeObject($object, $format, $properties = null)
  55. {
  56. if (!$this->normalizers) {
  57. throw new \LogicException('You must register at least one normalizer to be able to normalize objects.');
  58. }
  59. $class = get_class($object);
  60. if (isset($this->normalizerCache[$class][$format])) {
  61. return $this->normalizerCache[$class][$format]->normalize($object, $format, $properties);
  62. }
  63. $reflClass = new \ReflectionClass($class);
  64. foreach ($this->normalizers as $normalizer) {
  65. if ($normalizer->supports($reflClass, $format)) {
  66. $this->normalizerCache[$class][$format] = $normalizer;
  67. return $normalizer->normalize($object, $format, $properties);
  68. }
  69. }
  70. throw new \UnexpectedValueException('Could not normalize object of type '.$class.', no supporting normalizer found.');
  71. }
  72. /**
  73. * {@inheritdoc}
  74. */
  75. public function denormalizeObject($data, $class, $format = null)
  76. {
  77. if (!$this->normalizers) {
  78. throw new \LogicException('You must register at least one normalizer to be able to denormalize objects.');
  79. }
  80. if (isset($this->normalizerCache[$class][$format])) {
  81. return $this->normalizerCache[$class][$format]->denormalize($data, $class, $format);
  82. }
  83. $reflClass = new \ReflectionClass($class);
  84. foreach ($this->normalizers as $normalizer) {
  85. if ($normalizer->supports($reflClass, $format)) {
  86. $this->normalizerCache[$class][$format] = $normalizer;
  87. return $normalizer->denormalize($data, $class, $format);
  88. }
  89. }
  90. throw new \UnexpectedValueException('Could not denormalize object of type '.$class.', no supporting normalizer found.');
  91. }
  92. /**
  93. * {@inheritdoc}
  94. */
  95. public function normalize($data, $format = null)
  96. {
  97. if (!$this->isStructuredType($data)) {
  98. return $data;
  99. }
  100. if (is_array($data)) {
  101. foreach ($data as $key => $val) {
  102. $data[$key] = $this->isStructuredType($val) ? $this->normalize($val, $format) : $val;
  103. }
  104. return $data;
  105. }
  106. if (is_object($data)) {
  107. return $this->normalizeObject($data, $format);
  108. }
  109. throw new \UnexpectedValueException('An unexpected value could not be normalized: '.var_export($data, true));
  110. }
  111. /**
  112. * {@inheritDoc}
  113. */
  114. public function denormalize($data, $type, $format = null)
  115. {
  116. return $this->denormalizeObject($data, $type, $format);
  117. }
  118. /**
  119. * {@inheritdoc}
  120. */
  121. public function encode($data, $format)
  122. {
  123. if (!$this->hasEncoder($format)) {
  124. throw new \UnexpectedValueException('No encoder registered for the '.$format.' format');
  125. }
  126. return $this->encoders[$format]->encode($data, $format);
  127. }
  128. /**
  129. * {@inheritdoc}
  130. */
  131. public function decode($data, $format)
  132. {
  133. if (!$this->hasEncoder($format)) {
  134. throw new \UnexpectedValueException('No encoder registered to decode the '.$format.' format');
  135. }
  136. return $this->encoders[$format]->decode($data, $format);
  137. }
  138. /**
  139. * {@inheritdoc}
  140. */
  141. public function addNormalizer(NormalizerInterface $normalizer)
  142. {
  143. $this->normalizers[] = $normalizer;
  144. $normalizer->setSerializer($this);
  145. }
  146. /**
  147. * {@inheritdoc}
  148. */
  149. public function getNormalizers()
  150. {
  151. return $this->normalizers;
  152. }
  153. /**
  154. * {@inheritdoc}
  155. */
  156. public function removeNormalizer(NormalizerInterface $normalizer)
  157. {
  158. unset($this->normalizers[array_search($normalizer, $this->normalizers, true)]);
  159. }
  160. /**
  161. * {@inheritdoc}
  162. */
  163. public function setEncoder($format, EncoderInterface $encoder)
  164. {
  165. $this->encoders[$format] = $encoder;
  166. $encoder->setSerializer($this);
  167. }
  168. /**
  169. * {@inheritdoc}
  170. */
  171. public function getEncoders()
  172. {
  173. return $this->encoders;
  174. }
  175. /**
  176. * {@inheritdoc}
  177. */
  178. public function getEncoder($format)
  179. {
  180. return $this->encoders[$format];
  181. }
  182. /**
  183. * {@inheritdoc}
  184. */
  185. public function hasEncoder($format)
  186. {
  187. return isset($this->encoders[$format]);
  188. }
  189. /**
  190. * {@inheritdoc}
  191. */
  192. public function removeEncoder($format)
  193. {
  194. unset($this->encoders[$format]);
  195. }
  196. }