vendor/symfony/serializer/Debug/TraceableSerializer.php line 41

  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\Component\Serializer\Debug;
  11. use Symfony\Component\Serializer\DataCollector\SerializerDataCollector;
  12. use Symfony\Component\Serializer\Encoder\DecoderInterface;
  13. use Symfony\Component\Serializer\Encoder\EncoderInterface;
  14. use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
  15. use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
  16. use Symfony\Component\Serializer\SerializerInterface;
  17. /**
  18.  * Collects some data about serialization.
  19.  *
  20.  * @author Mathias Arlaud <mathias.arlaud@gmail.com>
  21.  *
  22.  * @internal
  23.  */
  24. class TraceableSerializer implements SerializerInterfaceNormalizerInterfaceDenormalizerInterfaceEncoderInterfaceDecoderInterface
  25. {
  26.     public const DEBUG_TRACE_ID 'debug_trace_id';
  27.     /**
  28.      * @param SerializerInterface&NormalizerInterface&DenormalizerInterface&EncoderInterface&DecoderInterface $serializer
  29.      */
  30.     public function __construct(
  31.         private SerializerInterface $serializer,
  32.         private SerializerDataCollector $dataCollector,
  33.     ) {
  34.     }
  35.     public function serialize(mixed $datastring $format, array $context = []): string
  36.     {
  37.         $context[self::DEBUG_TRACE_ID] = $traceId uniqid();
  38.         $startTime microtime(true);
  39.         $result $this->serializer->serialize($data$format$context);
  40.         $time microtime(true) - $startTime;
  41.         $caller $this->getCaller(__FUNCTION__SerializerInterface::class);
  42.         $this->dataCollector->collectSerialize($traceId$data$format$context$time$caller);
  43.         return $result;
  44.     }
  45.     public function deserialize(mixed $datastring $typestring $format, array $context = []): mixed
  46.     {
  47.         $context[self::DEBUG_TRACE_ID] = $traceId uniqid();
  48.         $startTime microtime(true);
  49.         $result $this->serializer->deserialize($data$type$format$context);
  50.         $time microtime(true) - $startTime;
  51.         $caller $this->getCaller(__FUNCTION__SerializerInterface::class);
  52.         $this->dataCollector->collectDeserialize($traceId$data$type$format$context$time$caller);
  53.         return $result;
  54.     }
  55.     public function normalize(mixed $objectstring $format null, array $context = []): array|string|int|float|bool|\ArrayObject|null
  56.     {
  57.         $context[self::DEBUG_TRACE_ID] = $traceId uniqid();
  58.         $startTime microtime(true);
  59.         $result $this->serializer->normalize($object$format$context);
  60.         $time microtime(true) - $startTime;
  61.         $caller $this->getCaller(__FUNCTION__NormalizerInterface::class);
  62.         $this->dataCollector->collectNormalize($traceId$object$format$context$time$caller);
  63.         return $result;
  64.     }
  65.     public function denormalize(mixed $datastring $typestring $format null, array $context = []): mixed
  66.     {
  67.         $context[self::DEBUG_TRACE_ID] = $traceId uniqid();
  68.         $startTime microtime(true);
  69.         $result $this->serializer->denormalize($data$type$format$context);
  70.         $time microtime(true) - $startTime;
  71.         $caller $this->getCaller(__FUNCTION__DenormalizerInterface::class);
  72.         $this->dataCollector->collectDenormalize($traceId$data$type$format$context$time$caller);
  73.         return $result;
  74.     }
  75.     public function encode(mixed $datastring $format, array $context = []): string
  76.     {
  77.         $context[self::DEBUG_TRACE_ID] = $traceId uniqid();
  78.         $startTime microtime(true);
  79.         $result $this->serializer->encode($data$format$context);
  80.         $time microtime(true) - $startTime;
  81.         $caller $this->getCaller(__FUNCTION__EncoderInterface::class);
  82.         $this->dataCollector->collectEncode($traceId$data$format$context$time$caller);
  83.         return $result;
  84.     }
  85.     public function decode(string $datastring $format, array $context = []): mixed
  86.     {
  87.         $context[self::DEBUG_TRACE_ID] = $traceId uniqid();
  88.         $startTime microtime(true);
  89.         $result $this->serializer->decode($data$format$context);
  90.         $time microtime(true) - $startTime;
  91.         $caller $this->getCaller(__FUNCTION__DecoderInterface::class);
  92.         $this->dataCollector->collectDecode($traceId$data$format$context$time$caller);
  93.         return $result;
  94.     }
  95.     public function supportsNormalization(mixed $datastring $format null, array $context = []): bool
  96.     {
  97.         return $this->serializer->supportsNormalization($data$format$context);
  98.     }
  99.     public function supportsDenormalization(mixed $datastring $typestring $format null, array $context = []): bool
  100.     {
  101.         return $this->serializer->supportsDenormalization($data$type$format$context);
  102.     }
  103.     public function supportsEncoding(string $format, array $context = []): bool
  104.     {
  105.         return $this->serializer->supportsEncoding($format$context);
  106.     }
  107.     public function supportsDecoding(string $format, array $context = []): bool
  108.     {
  109.         return $this->serializer->supportsDecoding($format$context);
  110.     }
  111.     /**
  112.      * Proxies all method calls to the original serializer.
  113.      */
  114.     public function __call(string $method, array $arguments): mixed
  115.     {
  116.         return $this->serializer->{$method}(...$arguments);
  117.     }
  118.     private function getCaller(string $methodstring $interface): array
  119.     {
  120.         $trace debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS8);
  121.         $file $trace[0]['file'];
  122.         $line $trace[0]['line'];
  123.         for ($i 1$i 8; ++$i) {
  124.             if (isset($trace[$i]['class'], $trace[$i]['function'])
  125.                 && $method === $trace[$i]['function']
  126.                 && is_a($trace[$i]['class'], $interfacetrue)
  127.             ) {
  128.                 $file $trace[$i]['file'];
  129.                 $line $trace[$i]['line'];
  130.                 break;
  131.             }
  132.         }
  133.         $name str_replace('\\''/'$file);
  134.         $name substr($namestrrpos($name'/') + 1);
  135.         return compact('name''file''line');
  136.     }
  137. }