vendor/symfony/cache/Marshaller/TagAwareMarshaller.php line 84

Open in your IDE?
  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\Cache\Marshaller;
  11. /**
  12.  * A marshaller optimized for data structures generated by AbstractTagAwareAdapter.
  13.  *
  14.  * @author Nicolas Grekas <p@tchwork.com>
  15.  */
  16. class TagAwareMarshaller implements MarshallerInterface
  17. {
  18.     private $marshaller;
  19.     public function __construct(?MarshallerInterface $marshaller null)
  20.     {
  21.         $this->marshaller $marshaller ?? new DefaultMarshaller();
  22.     }
  23.     /**
  24.      * {@inheritdoc}
  25.      */
  26.     public function marshall(array $values, ?array &$failed): array
  27.     {
  28.         $failed $notSerialized $serialized = [];
  29.         foreach ($values as $id => $value) {
  30.             if (\is_array($value) && \is_array($value['tags'] ?? null) && \array_key_exists('value'$value) && \count($value) === + (\is_string($value['meta'] ?? null) && === \strlen($value['meta']))) {
  31.                 // if the value is an array with keys "tags", "value" and "meta", use a compact serialization format
  32.                 // magic numbers in the form 9D-..-..-..-..-00-..-..-..-5F allow detecting this format quickly in unmarshall()
  33.                 $v $this->marshaller->marshall($value$f);
  34.                 if ($f) {
  35.                     $f = [];
  36.                     $failed[] = $id;
  37.                 } else {
  38.                     if ([] === $value['tags']) {
  39.                         $v['tags'] = '';
  40.                     }
  41.                     $serialized[$id] = "\x9D".($value['meta'] ?? "\0\0\0\0\0\0\0\0").pack('N'\strlen($v['tags'])).$v['tags'].$v['value'];
  42.                     $serialized[$id][9] = "\x5F";
  43.                 }
  44.             } else {
  45.                 // other arbitrary values are serialized using the decorated marshaller below
  46.                 $notSerialized[$id] = $value;
  47.             }
  48.         }
  49.         if ($notSerialized) {
  50.             $serialized += $this->marshaller->marshall($notSerialized$f);
  51.             $failed array_merge($failed$f);
  52.         }
  53.         return $serialized;
  54.     }
  55.     /**
  56.      * {@inheritdoc}
  57.      */
  58.     public function unmarshall(string $value)
  59.     {
  60.         // detect the compact format used in marshall() using magic numbers in the form 9D-..-..-..-..-00-..-..-..-5F
  61.         if (13 >= \strlen($value) || "\x9D" !== $value[0] || "\0" !== $value[5] || "\x5F" !== $value[9]) {
  62.             return $this->marshaller->unmarshall($value);
  63.         }
  64.         // data consists of value, tags and metadata which we need to unpack
  65.         $meta substr($value112);
  66.         $meta[8] = "\0";
  67.         $tagLen unpack('Nlen'$meta8)['len'];
  68.         $meta substr($meta08);
  69.         return [
  70.             'value' => $this->marshaller->unmarshall(substr($value13 $tagLen)),
  71.             'tags' => $tagLen $this->marshaller->unmarshall(substr($value13$tagLen)) : [],
  72.             'meta' => "\0\0\0\0\0\0\0\0" === $meta null $meta,
  73.         ];
  74.     }
  75. }