vendor/symfony/cache/Adapter/ApcuAdapter.php line 64

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\Adapter;
  11. use Symfony\Component\Cache\CacheItem;
  12. use Symfony\Component\Cache\Exception\CacheException;
  13. use Symfony\Component\Cache\Marshaller\MarshallerInterface;
  14. /**
  15.  * @author Nicolas Grekas <p@tchwork.com>
  16.  */
  17. class ApcuAdapter extends AbstractAdapter
  18. {
  19.     private $marshaller;
  20.     /**
  21.      * @throws CacheException if APCu is not enabled
  22.      */
  23.     public function __construct(string $namespace ''int $defaultLifetime 0string $version nullMarshallerInterface $marshaller null)
  24.     {
  25.         if (!static::isSupported()) {
  26.             throw new CacheException('APCu is not enabled.');
  27.         }
  28.         if ('cli' === \PHP_SAPI) {
  29.             ini_set('apc.use_request_time'0);
  30.         }
  31.         parent::__construct($namespace$defaultLifetime);
  32.         if (null !== $version) {
  33.             CacheItem::validateKey($version);
  34.             if (!apcu_exists($version.'@'.$namespace)) {
  35.                 $this->doClear($namespace);
  36.                 apcu_add($version.'@'.$namespacenull);
  37.             }
  38.         }
  39.         $this->marshaller $marshaller;
  40.     }
  41.     public static function isSupported()
  42.     {
  43.         return \function_exists('apcu_fetch') && filter_var(\ini_get('apc.enabled'), \FILTER_VALIDATE_BOOLEAN);
  44.     }
  45.     /**
  46.      * {@inheritdoc}
  47.      */
  48.     protected function doFetch(array $ids)
  49.     {
  50.         $unserializeCallbackHandler ini_set('unserialize_callback_func'__CLASS__.'::handleUnserializeCallback');
  51.         try {
  52.             $values = [];
  53.             $ids array_flip($ids);
  54.             foreach (apcu_fetch(array_keys($ids), $ok) ?: [] as $k => $v) {
  55.                 if (!isset($ids[$k])) {
  56.                     // work around https://github.com/krakjoe/apcu/issues/247
  57.                     $k key($ids);
  58.                 }
  59.                 unset($ids[$k]);
  60.                 if (null !== $v || $ok) {
  61.                     $values[$k] = null !== $this->marshaller $this->marshaller->unmarshall($v) : $v;
  62.                 }
  63.             }
  64.             return $values;
  65.         } catch (\Error $e) {
  66.             throw new \ErrorException($e->getMessage(), $e->getCode(), \E_ERROR$e->getFile(), $e->getLine());
  67.         } finally {
  68.             ini_set('unserialize_callback_func'$unserializeCallbackHandler);
  69.         }
  70.     }
  71.     /**
  72.      * {@inheritdoc}
  73.      */
  74.     protected function doHave(string $id)
  75.     {
  76.         return apcu_exists($id);
  77.     }
  78.     /**
  79.      * {@inheritdoc}
  80.      */
  81.     protected function doClear(string $namespace)
  82.     {
  83.         return isset($namespace[0]) && class_exists(\APCUIterator::class, false) && ('cli' !== \PHP_SAPI || filter_var(\ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOLEAN))
  84.             ? apcu_delete(new \APCUIterator(sprintf('/^%s/'preg_quote($namespace'/')), \APC_ITER_KEY))
  85.             : apcu_clear_cache();
  86.     }
  87.     /**
  88.      * {@inheritdoc}
  89.      */
  90.     protected function doDelete(array $ids)
  91.     {
  92.         foreach ($ids as $id) {
  93.             apcu_delete($id);
  94.         }
  95.         return true;
  96.     }
  97.     /**
  98.      * {@inheritdoc}
  99.      */
  100.     protected function doSave(array $valuesint $lifetime)
  101.     {
  102.         if (null !== $this->marshaller && (!$values $this->marshaller->marshall($values$failed))) {
  103.             return $failed;
  104.         }
  105.         try {
  106.             if (false === $failures apcu_store($valuesnull$lifetime)) {
  107.                 $failures $values;
  108.             }
  109.             return array_keys($failures);
  110.         } catch (\Throwable $e) {
  111.             if (=== \count($values)) {
  112.                 // Workaround https://github.com/krakjoe/apcu/issues/170
  113.                 apcu_delete(array_key_first($values));
  114.             }
  115.             throw $e;
  116.         }
  117.     }
  118. }