[Cache] deprecate all PSR-16 adapters, provide Psr16Cache instead

This commit is contained in:
Nicolas Grekas 2018-11-15 21:07:46 +01:00
parent cafbdb73e8
commit 5006be63c1
53 changed files with 788 additions and 385 deletions

View File

@ -8,6 +8,13 @@ BrowserKit
* Deprecated `Response::buildHeader()`
* Deprecated `Response::getStatus()`, use `Response::getStatusCode()` instead
Cache
-----
* The `psr/simple-cache` dependency has been removed - run `composer require psr/simple-cache` if you need it.
* Deprecated all PSR-16 adapters, use `Psr16Cache` or `Symfony\Contracts\Cache\CacheInterface` implementations instead.
* Deprecated `SimpleCacheAdapter`, use `Psr16Adapter instead.
Config
------
@ -18,6 +25,7 @@ FrameworkBundle
* Not passing the project directory to the constructor of the `AssetsInstallCommand` is deprecated. This argument will
be mandatory in 5.0.
* Deprecated the "Psr\SimpleCache\CacheInterface" / "cache.app.simple" service, use "Symfony\Contracts\Cache\CacheInterface" / "cache.app" instead.
HttpFoundation
--------------

View File

@ -13,6 +13,8 @@ Cache
-----
* Removed `CacheItem::getPreviousTags()`, use `CacheItem::getMetadata()` instead.
* Removed all PSR-16 adapters, use `Psr16Cache` or `Symfony\Contracts\Cache\CacheInterface` implementations instead.
* Removed `SimpleCacheAdapter`, use `Psr16Adapter instead.
Config
------
@ -163,6 +165,7 @@ FrameworkBundle
* The `Templating\Helper\TranslatorHelper::transChoice()` method has been removed, use the `trans()` one instead with a `%count%` parameter.
* Removed support for legacy translations directories `src/Resources/translations/` and `src/Resources/<BundleName>/translations/`, use `translations/` instead.
* Support for the legacy directory structure in `translation:update` and `debug:translation` commands has been removed.
* Removed the "Psr\SimpleCache\CacheInterface" / "cache.app.simple" service, use "Symfony\Contracts\Cache\CacheInterface" / "cache.app" instead.
HttpFoundation
--------------

View File

@ -8,6 +8,7 @@ CHANGELOG
be mandatory in 5.0.
* Added `ControllerTrait::isFormValid()`
* Added an `help_html` form option to display the `help` text as HTML
* Deprecated the "Psr\SimpleCache\CacheInterface" / "cache.app.simple" service, use "Symfony\Contracts\Cache\CacheInterface" / "cache.app" instead
* [BC Break] When using Messenger, the default transport changed from
using Symfony's serializer service to use `PhpSerializer`, which uses

View File

@ -11,7 +11,8 @@
<tag name="cache.pool" clearer="cache.app_clearer" reset="reset" />
</service>
<service id="cache.app.simple" class="Symfony\Component\Cache\Simple\Psr6Cache">
<service id="cache.app.simple" class="Symfony\Component\Cache\Psr16Cache">
<deprecated>The "Psr\SimpleCache\CacheInterface" / "%service_id%" service is deprecated since Symfony 4.3. Use "Symfony\Contracts\Cache\CacheInterface" / "cache.app" instead.</deprecated>
<argument type="service" id="cache.app" />
</service>

View File

@ -18,7 +18,7 @@
"require": {
"php": "^7.1.3",
"ext-xml": "*",
"symfony/cache": "~4.2",
"symfony/cache": "~4.3",
"symfony/config": "~4.2",
"symfony/contracts": "^1.0.2",
"symfony/dependency-injection": "^4.2",

View File

@ -0,0 +1,81 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Adapter;
use Psr\SimpleCache\CacheInterface;
use Symfony\Component\Cache\PruneableInterface;
use Symfony\Component\Cache\ResettableInterface;
use Symfony\Component\Cache\Traits\ProxyTrait;
/**
* Turns a PSR-16 cache into a PSR-6 one.
*
* @author Nicolas Grekas <p@tchwork.com>
*/
class Psr16Adapter extends AbstractAdapter implements PruneableInterface, ResettableInterface
{
use ProxyTrait;
private $miss;
public function __construct(CacheInterface $pool, string $namespace = '', int $defaultLifetime = 0)
{
parent::__construct($namespace, $defaultLifetime);
$this->pool = $pool;
$this->miss = new \stdClass();
}
/**
* {@inheritdoc}
*/
protected function doFetch(array $ids)
{
foreach ($this->pool->getMultiple($ids, $this->miss) as $key => $value) {
if ($this->miss !== $value) {
yield $key => $value;
}
}
}
/**
* {@inheritdoc}
*/
protected function doHave($id)
{
return $this->pool->has($id);
}
/**
* {@inheritdoc}
*/
protected function doClear($namespace)
{
return $this->pool->clear();
}
/**
* {@inheritdoc}
*/
protected function doDelete(array $ids)
{
return $this->pool->deleteMultiple($ids);
}
/**
* {@inheritdoc}
*/
protected function doSave(array $values, $lifetime)
{
return $this->pool->setMultiple($values, 0 === $lifetime ? null : $lifetime);
}
}

View File

@ -11,69 +11,11 @@
namespace Symfony\Component\Cache\Adapter;
use Psr\SimpleCache\CacheInterface;
use Symfony\Component\Cache\PruneableInterface;
use Symfony\Component\Cache\ResettableInterface;
use Symfony\Component\Cache\Traits\ProxyTrait;
@trigger_error(sprintf('The "%s" class is @deprecated since Symfony 4.3, use "Psr16Adapter" instead.', SimpleCacheAdapter::class), E_USER_DEPRECATED);
/**
* @author Nicolas Grekas <p@tchwork.com>
* @deprecated since Symfony 4.3, use Psr16Adapter instead.
*/
class SimpleCacheAdapter extends AbstractAdapter implements PruneableInterface, ResettableInterface
class SimpleCacheAdapter extends Psr16Adapter
{
use ProxyTrait;
private $miss;
public function __construct(CacheInterface $pool, string $namespace = '', int $defaultLifetime = 0)
{
parent::__construct($namespace, $defaultLifetime);
$this->pool = $pool;
$this->miss = new \stdClass();
}
/**
* {@inheritdoc}
*/
protected function doFetch(array $ids)
{
foreach ($this->pool->getMultiple($ids, $this->miss) as $key => $value) {
if ($this->miss !== $value) {
yield $key => $value;
}
}
}
/**
* {@inheritdoc}
*/
protected function doHave($id)
{
return $this->pool->has($id);
}
/**
* {@inheritdoc}
*/
protected function doClear($namespace)
{
return $this->pool->clear();
}
/**
* {@inheritdoc}
*/
protected function doDelete(array $ids)
{
return $this->pool->deleteMultiple($ids);
}
/**
* {@inheritdoc}
*/
protected function doSave(array $values, $lifetime)
{
return $this->pool->setMultiple($values, 0 === $lifetime ? null : $lifetime);
}
}

View File

@ -1,6 +1,13 @@
CHANGELOG
=========
4.3.0
-----
* removed `psr/simple-cache` dependency, run `composer require psr/simple-cache` if you need it
* deprecated all PSR-16 adapters, use `Psr16Cache` or `Symfony\Contracts\Cache\CacheInterface` implementations instead
* deprecated `SimpleCacheAdapter`, use `Psr16Adapter` instead
4.2.0
-----

View File

@ -14,6 +14,12 @@ namespace Symfony\Component\Cache\Exception;
use Psr\Cache\CacheException as Psr6CacheInterface;
use Psr\SimpleCache\CacheException as SimpleCacheInterface;
class CacheException extends \Exception implements Psr6CacheInterface, SimpleCacheInterface
{
if (interface_exists(SimpleCacheInterface::class)) {
class CacheException extends \Exception implements Psr6CacheInterface, SimpleCacheInterface
{
}
} else {
class CacheException extends \Exception implements Psr6CacheInterface
{
}
}

View File

@ -14,6 +14,12 @@ namespace Symfony\Component\Cache\Exception;
use Psr\Cache\InvalidArgumentException as Psr6CacheInterface;
use Psr\SimpleCache\InvalidArgumentException as SimpleCacheInterface;
class InvalidArgumentException extends \InvalidArgumentException implements Psr6CacheInterface, SimpleCacheInterface
{
if (interface_exists(SimpleCacheInterface::class)) {
class InvalidArgumentException extends \InvalidArgumentException implements Psr6CacheInterface, SimpleCacheInterface
{
}
} else {
class InvalidArgumentException extends \InvalidArgumentException implements Psr6CacheInterface
{
}
}

View File

@ -14,6 +14,12 @@ namespace Symfony\Component\Cache\Exception;
use Psr\Cache\CacheException as Psr6CacheInterface;
use Psr\SimpleCache\CacheException as SimpleCacheInterface;
class LogicException extends \LogicException implements Psr6CacheInterface, SimpleCacheInterface
{
if (interface_exists(SimpleCacheInterface::class)) {
class LogicException extends \LogicException implements Psr6CacheInterface, SimpleCacheInterface
{
}
} else {
class LogicException extends \LogicException implements Psr6CacheInterface
{
}
}

View File

@ -45,6 +45,7 @@ class LockRegistry
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'PhpArrayAdapter.php',
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'PhpFilesAdapter.php',
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'ProxyAdapter.php',
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'Psr16Adapter.php',
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'RedisAdapter.php',
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'SimpleCacheAdapter.php',
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'TagAwareAdapter.php',

View File

@ -0,0 +1,263 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache;
use Psr\Cache\CacheException as Psr6CacheException;
use Psr\Cache\CacheItemPoolInterface;
use Psr\SimpleCache\CacheException as SimpleCacheException;
use Psr\SimpleCache\CacheInterface;
use Symfony\Component\Cache\Adapter\AdapterInterface;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\Traits\ProxyTrait;
/**
* Turns a PSR-6 cache into a PSR-16 one.
*
* @author Nicolas Grekas <p@tchwork.com>
*/
class Psr16Cache implements CacheInterface, PruneableInterface, ResettableInterface
{
use ProxyTrait;
private const METADATA_EXPIRY_OFFSET = 1527506807;
private $createCacheItem;
private $cacheItemPrototype;
public function __construct(CacheItemPoolInterface $pool)
{
$this->pool = $pool;
if (!$pool instanceof AdapterInterface) {
return;
}
$cacheItemPrototype = &$this->cacheItemPrototype;
$createCacheItem = \Closure::bind(
function ($key, $value, $allowInt = false) use (&$cacheItemPrototype) {
$item = clone $cacheItemPrototype;
$item->key = $allowInt && \is_int($key) ? (string) $key : CacheItem::validateKey($key);
$item->value = $value;
$item->isHit = false;
return $item;
},
null,
CacheItem::class
);
$this->createCacheItem = function ($key, $value, $allowInt = false) use ($createCacheItem) {
if (null === $this->cacheItemPrototype) {
$this->get($allowInt && \is_int($key) ? (string) $key : $key);
}
$this->createCacheItem = $createCacheItem;
return $createCacheItem($key, null, $allowInt)->set($value);
};
}
/**
* {@inheritdoc}
*/
public function get($key, $default = null)
{
try {
$item = $this->pool->getItem($key);
} catch (SimpleCacheException $e) {
throw $e;
} catch (Psr6CacheException $e) {
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
}
if (null === $this->cacheItemPrototype) {
$this->cacheItemPrototype = clone $item;
$this->cacheItemPrototype->set(null);
}
return $item->isHit() ? $item->get() : $default;
}
/**
* {@inheritdoc}
*/
public function set($key, $value, $ttl = null)
{
try {
if (null !== $f = $this->createCacheItem) {
$item = $f($key, $value);
} else {
$item = $this->pool->getItem($key)->set($value);
}
} catch (SimpleCacheException $e) {
throw $e;
} catch (Psr6CacheException $e) {
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
}
if (null !== $ttl) {
$item->expiresAfter($ttl);
}
return $this->pool->save($item);
}
/**
* {@inheritdoc}
*/
public function delete($key)
{
try {
return $this->pool->deleteItem($key);
} catch (SimpleCacheException $e) {
throw $e;
} catch (Psr6CacheException $e) {
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* {@inheritdoc}
*/
public function clear()
{
return $this->pool->clear();
}
/**
* {@inheritdoc}
*/
public function getMultiple($keys, $default = null)
{
if ($keys instanceof \Traversable) {
$keys = iterator_to_array($keys, false);
} elseif (!\is_array($keys)) {
throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', \is_object($keys) ? \get_class($keys) : \gettype($keys)));
}
try {
$items = $this->pool->getItems($keys);
} catch (SimpleCacheException $e) {
throw $e;
} catch (Psr6CacheException $e) {
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
}
$values = [];
if (!$this->pool instanceof AdapterInterface) {
foreach ($items as $key => $item) {
$values[$key] = $item->isHit() ? $item->get() : $default;
}
return $values;
}
foreach ($items as $key => $item) {
if (!$item->isHit()) {
$values[$key] = $default;
continue;
}
$values[$key] = $item->get();
if (!$metadata = $item->getMetadata()) {
continue;
}
unset($metadata[CacheItem::METADATA_TAGS]);
if ($metadata) {
$values[$key] = ["\x9D".pack('VN', (int) $metadata[CacheItem::METADATA_EXPIRY] - self::METADATA_EXPIRY_OFFSET, $metadata[CacheItem::METADATA_CTIME])."\x5F" => $values[$key]];
}
}
return $values;
}
/**
* {@inheritdoc}
*/
public function setMultiple($values, $ttl = null)
{
$valuesIsArray = \is_array($values);
if (!$valuesIsArray && !$values instanceof \Traversable) {
throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given', \is_object($values) ? \get_class($values) : \gettype($values)));
}
$items = [];
try {
if (null !== $f = $this->createCacheItem) {
$valuesIsArray = false;
foreach ($values as $key => $value) {
$items[$key] = $f($key, $value, true);
}
} elseif ($valuesIsArray) {
$items = [];
foreach ($values as $key => $value) {
$items[] = (string) $key;
}
$items = $this->pool->getItems($items);
} else {
foreach ($values as $key => $value) {
if (\is_int($key)) {
$key = (string) $key;
}
$items[$key] = $this->pool->getItem($key)->set($value);
}
}
} catch (SimpleCacheException $e) {
throw $e;
} catch (Psr6CacheException $e) {
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
}
$ok = true;
foreach ($items as $key => $item) {
if ($valuesIsArray) {
$item->set($values[$key]);
}
if (null !== $ttl) {
$item->expiresAfter($ttl);
}
$ok = $this->pool->saveDeferred($item) && $ok;
}
return $this->pool->commit() && $ok;
}
/**
* {@inheritdoc}
*/
public function deleteMultiple($keys)
{
if ($keys instanceof \Traversable) {
$keys = iterator_to_array($keys, false);
} elseif (!\is_array($keys)) {
throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', \is_object($keys) ? \get_class($keys) : \gettype($keys)));
}
try {
return $this->pool->deleteItems($keys);
} catch (SimpleCacheException $e) {
throw $e;
} catch (Psr6CacheException $e) {
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* {@inheritdoc}
*/
public function has($key)
{
try {
return $this->pool->hasItem($key);
} catch (SimpleCacheException $e) {
throw $e;
} catch (Psr6CacheException $e) {
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
}
}
}

View File

@ -12,16 +12,20 @@
namespace Symfony\Component\Cache\Simple;
use Psr\Log\LoggerAwareInterface;
use Psr\SimpleCache\CacheInterface;
use Psr\SimpleCache\CacheInterface as Psr16CacheInterface;
use Symfony\Component\Cache\Adapter\AbstractAdapter;
use Symfony\Component\Cache\CacheItem;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\ResettableInterface;
use Symfony\Component\Cache\Traits\AbstractTrait;
use Symfony\Contracts\Cache\CacheInterface;
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', AbstractCache::class, AbstractAdapter::class, CacheInterface::class), E_USER_DEPRECATED);
/**
* @author Nicolas Grekas <p@tchwork.com>
* @deprecated since Symfony 4.3, use AbstractAdapter and type-hint for CacheInterface instead.
*/
abstract class AbstractCache implements CacheInterface, LoggerAwareInterface, ResettableInterface
abstract class AbstractCache implements Psr16CacheInterface, LoggerAwareInterface, ResettableInterface
{
use AbstractTrait {
deleteItems as private;

View File

@ -13,6 +13,11 @@ namespace Symfony\Component\Cache\Simple;
use Symfony\Component\Cache\Traits\ApcuTrait;
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', ApcuCache::class, ApcuAdapter::class, CacheInterface::class), E_USER_DEPRECATED);
/**
* @deprecated since Symfony 4.3, use ApcuAdapter and type-hint for CacheInterface instead.
*/
class ApcuCache extends AbstractCache
{
use ApcuTrait;

View File

@ -12,16 +12,20 @@
namespace Symfony\Component\Cache\Simple;
use Psr\Log\LoggerAwareInterface;
use Psr\SimpleCache\CacheInterface;
use Psr\SimpleCache\CacheInterface as Psr16CacheInterface;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\CacheItem;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\ResettableInterface;
use Symfony\Component\Cache\Traits\ArrayTrait;
use Symfony\Contracts\Cache\CacheInterface;
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', ArrayCache::class, ArrayAdapter::class, CacheInterface::class), E_USER_DEPRECATED);
/**
* @author Nicolas Grekas <p@tchwork.com>
* @deprecated since Symfony 4.3, use ArrayAdapter and type-hint for CacheInterface instead.
*/
class ArrayCache implements CacheInterface, LoggerAwareInterface, ResettableInterface
class ArrayCache implements Psr16CacheInterface, LoggerAwareInterface, ResettableInterface
{
use ArrayTrait {
ArrayTrait::deleteItem as delete;

View File

@ -11,21 +11,25 @@
namespace Symfony\Component\Cache\Simple;
use Psr\SimpleCache\CacheInterface;
use Psr\SimpleCache\CacheInterface as Psr16CacheInterface;
use Symfony\Component\Cache\Adapter\ChainAdapter;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\PruneableInterface;
use Symfony\Component\Cache\ResettableInterface;
use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Service\ResetInterface;
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', ChainCache::class, ChainAdapter::class, CacheInterface::class), E_USER_DEPRECATED);
/**
* Chains several caches together.
*
* Cached items are fetched from the first cache having them in its data store.
* They are saved and deleted in all caches at once.
*
* @author Nicolas Grekas <p@tchwork.com>
* @deprecated since Symfony 4.3, use ChainAdapter and type-hint for CacheInterface instead.
*/
class ChainCache implements CacheInterface, PruneableInterface, ResettableInterface
class ChainCache implements Psr16CacheInterface, PruneableInterface, ResettableInterface
{
private $miss;
private $caches = [];
@ -33,8 +37,8 @@ class ChainCache implements CacheInterface, PruneableInterface, ResettableInterf
private $cacheCount;
/**
* @param CacheInterface[] $caches The ordered list of caches used to fetch cached items
* @param int $defaultLifetime The lifetime of items propagated from lower caches to upper ones
* @param Psr16CacheInterface[] $caches The ordered list of caches used to fetch cached items
* @param int $defaultLifetime The lifetime of items propagated from lower caches to upper ones
*/
public function __construct(array $caches, int $defaultLifetime = 0)
{
@ -43,8 +47,8 @@ class ChainCache implements CacheInterface, PruneableInterface, ResettableInterf
}
foreach ($caches as $cache) {
if (!$cache instanceof CacheInterface) {
throw new InvalidArgumentException(sprintf('The class "%s" does not implement the "%s" interface.', \get_class($cache), CacheInterface::class));
if (!$cache instanceof Psr16CacheInterface) {
throw new InvalidArgumentException(sprintf('The class "%s" does not implement the "%s" interface.', \get_class($cache), Psr16CacheInterface::class));
}
}

View File

@ -12,8 +12,15 @@
namespace Symfony\Component\Cache\Simple;
use Doctrine\Common\Cache\CacheProvider;
use Symfony\Component\Cache\Adapter\DoctrineAdapter;
use Symfony\Component\Cache\Traits\DoctrineTrait;
use Symfony\Contracts\Cache\CacheInterface;
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', DoctrineCache::class, DoctrineAdapter::class, CacheInterface::class), E_USER_DEPRECATED);
/**
* @deprecated since Symfony 4.3, use DoctrineAdapter and type-hint for CacheInterface instead.
*/
class DoctrineCache extends AbstractCache
{
use DoctrineTrait;

View File

@ -11,11 +11,18 @@
namespace Symfony\Component\Cache\Simple;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Marshaller\DefaultMarshaller;
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
use Symfony\Component\Cache\PruneableInterface;
use Symfony\Component\Cache\Traits\FilesystemTrait;
use Symfony\Contracts\Cache\CacheInterface;
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', FilesystemCache::class, FilesystemAdapter::class, CacheInterface::class), E_USER_DEPRECATED);
/**
* @deprecated since Symfony 4.3, use FilesystemAdapter and type-hint for CacheInterface instead.
*/
class FilesystemCache extends AbstractCache implements PruneableInterface
{
use FilesystemTrait;

View File

@ -11,9 +11,16 @@
namespace Symfony\Component\Cache\Simple;
use Symfony\Component\Cache\Adapter\MemcachedAdapter;
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
use Symfony\Component\Cache\Traits\MemcachedTrait;
use Symfony\Contracts\Cache\CacheInterface;
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', MemcachedCache::class, MemcachedAdapter::class, CacheInterface::class), E_USER_DEPRECATED);
/**
* @deprecated since Symfony 4.3, use MemcachedAdapter and type-hint for CacheInterface instead.
*/
class MemcachedCache extends AbstractCache
{
use MemcachedTrait;

View File

@ -11,12 +11,16 @@
namespace Symfony\Component\Cache\Simple;
use Psr\SimpleCache\CacheInterface;
use Psr\SimpleCache\CacheInterface as Psr16CacheInterface;
use Symfony\Components\Cache\Adapter\NullAdapter;
use Symfony\Contracts\Cache\CacheInterface;
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', NullCache::class, NullAdapter::class, CacheInterface::class), E_USER_DEPRECATED);
/**
* @author Nicolas Grekas <p@tchwork.com>
* @deprecated since Symfony 4.3, use NullAdapter and type-hint for CacheInterface instead.
*/
class NullCache implements CacheInterface
class NullCache implements Psr16CacheInterface
{
/**
* {@inheritdoc}

View File

@ -11,10 +11,17 @@
namespace Symfony\Component\Cache\Simple;
use Symfony\Component\Cache\Adapter\PdoAdapter;
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
use Symfony\Component\Cache\PruneableInterface;
use Symfony\Component\Cache\Traits\PdoTrait;
use Symfony\Contracts\Cache\CacheInterface;
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', PdoCache::class, PdoAdapter::class, CacheInterface::class), E_USER_DEPRECATED);
/**
* @deprecated since Symfony 4.3, use PdoAdapter and type-hint for CacheInterface instead.
*/
class PdoCache extends AbstractCache implements PruneableInterface
{
use PdoTrait;

View File

@ -11,28 +11,28 @@
namespace Symfony\Component\Cache\Simple;
use Psr\SimpleCache\CacheInterface;
use Psr\SimpleCache\CacheInterface as Psr16CacheInterface;
use Symfony\Component\Cache\Adapter\PhpArrayAdapter;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\PruneableInterface;
use Symfony\Component\Cache\ResettableInterface;
use Symfony\Component\Cache\Traits\PhpArrayTrait;
use Symfony\Contracts\Cache\CacheInterface;
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', PhpArrayCache::class, PhpArrayAdapter::class, CacheInterface::class), E_USER_DEPRECATED);
/**
* Caches items at warm up time using a PHP array that is stored in shared memory by OPCache since PHP 7.0.
* Warmed up items are read-only and run-time discovered items are cached using a fallback adapter.
*
* @author Titouan Galopin <galopintitouan@gmail.com>
* @author Nicolas Grekas <p@tchwork.com>
* @deprecated since Symfony 4.3, use PhpArrayAdapter and type-hint for CacheInterface instead.
*/
class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInterface
class PhpArrayCache implements Psr16CacheInterface, PruneableInterface, ResettableInterface
{
use PhpArrayTrait;
/**
* @param string $file The PHP file were values are cached
* @param CacheInterface $fallbackPool A pool to fallback on when an item is not hit
* @param string $file The PHP file were values are cached
* @param Psr16CacheInterface $fallbackPool A pool to fallback on when an item is not hit
*/
public function __construct(string $file, CacheInterface $fallbackPool)
public function __construct(string $file, Psr16CacheInterface $fallbackPool)
{
$this->file = $file;
$this->pool = $fallbackPool;
@ -43,9 +43,9 @@ class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInt
*
* @param string $file The PHP file were values are cached
*
* @return CacheInterface
* @return Psr16CacheInterface
*/
public static function create($file, CacheInterface $fallbackPool)
public static function create($file, Psr16CacheInterface $fallbackPool)
{
// Shared memory is available in PHP 7.0+ with OPCache enabled
if (filter_var(ini_get('opcache.enable'), FILTER_VALIDATE_BOOLEAN)) {

View File

@ -11,10 +11,17 @@
namespace Symfony\Component\Cache\Simple;
use Symfony\Component\Cache\Adapter\PhpFilesAdapter;
use Symfony\Component\Cache\Exception\CacheException;
use Symfony\Component\Cache\PruneableInterface;
use Symfony\Component\Cache\Traits\PhpFilesTrait;
use Symfony\Contracts\Cache\CacheInterface;
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', PhpFilesCache::class, PhpFilesAdapter::class, CacheInterface::class), E_USER_DEPRECATED);
/**
* @deprecated since Symfony 4.3, use PhpFilesAdapter and type-hint for CacheInterface instead.
*/
class PhpFilesCache extends AbstractCache implements PruneableInterface
{
use PhpFilesTrait;

View File

@ -11,254 +11,13 @@
namespace Symfony\Component\Cache\Simple;
use Psr\Cache\CacheException as Psr6CacheException;
use Psr\Cache\CacheItemPoolInterface;
use Psr\SimpleCache\CacheException as SimpleCacheException;
use Psr\SimpleCache\CacheInterface;
use Symfony\Component\Cache\Adapter\AdapterInterface;
use Symfony\Component\Cache\CacheItem;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\PruneableInterface;
use Symfony\Component\Cache\ResettableInterface;
use Symfony\Component\Cache\Traits\ProxyTrait;
use Symfony\Component\Cache\Psr16Cache;
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" instead.', Psr6Cache::class, Psr16Cache::class), E_USER_DEPRECATED);
/**
* @author Nicolas Grekas <p@tchwork.com>
* @deprecated since Symfony 4.3, use Psr16Cache instead.
*/
class Psr6Cache implements CacheInterface, PruneableInterface, ResettableInterface
class Psr6Cache extends Psr16Cache
{
use ProxyTrait;
private const METADATA_EXPIRY_OFFSET = 1527506807;
private $createCacheItem;
private $cacheItemPrototype;
public function __construct(CacheItemPoolInterface $pool)
{
$this->pool = $pool;
if (!$pool instanceof AdapterInterface) {
return;
}
$cacheItemPrototype = &$this->cacheItemPrototype;
$createCacheItem = \Closure::bind(
function ($key, $value, $allowInt = false) use (&$cacheItemPrototype) {
$item = clone $cacheItemPrototype;
$item->key = $allowInt && \is_int($key) ? (string) $key : CacheItem::validateKey($key);
$item->value = $value;
$item->isHit = false;
return $item;
},
null,
CacheItem::class
);
$this->createCacheItem = function ($key, $value, $allowInt = false) use ($createCacheItem) {
if (null === $this->cacheItemPrototype) {
$this->get($allowInt && \is_int($key) ? (string) $key : $key);
}
$this->createCacheItem = $createCacheItem;
return $createCacheItem($key, null, $allowInt)->set($value);
};
}
/**
* {@inheritdoc}
*/
public function get($key, $default = null)
{
try {
$item = $this->pool->getItem($key);
} catch (SimpleCacheException $e) {
throw $e;
} catch (Psr6CacheException $e) {
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
}
if (null === $this->cacheItemPrototype) {
$this->cacheItemPrototype = clone $item;
$this->cacheItemPrototype->set(null);
}
return $item->isHit() ? $item->get() : $default;
}
/**
* {@inheritdoc}
*/
public function set($key, $value, $ttl = null)
{
try {
if (null !== $f = $this->createCacheItem) {
$item = $f($key, $value);
} else {
$item = $this->pool->getItem($key)->set($value);
}
} catch (SimpleCacheException $e) {
throw $e;
} catch (Psr6CacheException $e) {
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
}
if (null !== $ttl) {
$item->expiresAfter($ttl);
}
return $this->pool->save($item);
}
/**
* {@inheritdoc}
*/
public function delete($key)
{
try {
return $this->pool->deleteItem($key);
} catch (SimpleCacheException $e) {
throw $e;
} catch (Psr6CacheException $e) {
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* {@inheritdoc}
*/
public function clear()
{
return $this->pool->clear();
}
/**
* {@inheritdoc}
*/
public function getMultiple($keys, $default = null)
{
if ($keys instanceof \Traversable) {
$keys = iterator_to_array($keys, false);
} elseif (!\is_array($keys)) {
throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', \is_object($keys) ? \get_class($keys) : \gettype($keys)));
}
try {
$items = $this->pool->getItems($keys);
} catch (SimpleCacheException $e) {
throw $e;
} catch (Psr6CacheException $e) {
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
}
$values = [];
if (!$this->pool instanceof AdapterInterface) {
foreach ($items as $key => $item) {
$values[$key] = $item->isHit() ? $item->get() : $default;
}
return $values;
}
foreach ($items as $key => $item) {
if (!$item->isHit()) {
$values[$key] = $default;
continue;
}
$values[$key] = $item->get();
if (!$metadata = $item->getMetadata()) {
continue;
}
unset($metadata[CacheItem::METADATA_TAGS]);
if ($metadata) {
$values[$key] = ["\x9D".pack('VN', (int) $metadata[CacheItem::METADATA_EXPIRY] - self::METADATA_EXPIRY_OFFSET, $metadata[CacheItem::METADATA_CTIME])."\x5F" => $values[$key]];
}
}
return $values;
}
/**
* {@inheritdoc}
*/
public function setMultiple($values, $ttl = null)
{
$valuesIsArray = \is_array($values);
if (!$valuesIsArray && !$values instanceof \Traversable) {
throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given', \is_object($values) ? \get_class($values) : \gettype($values)));
}
$items = [];
try {
if (null !== $f = $this->createCacheItem) {
$valuesIsArray = false;
foreach ($values as $key => $value) {
$items[$key] = $f($key, $value, true);
}
} elseif ($valuesIsArray) {
$items = [];
foreach ($values as $key => $value) {
$items[] = (string) $key;
}
$items = $this->pool->getItems($items);
} else {
foreach ($values as $key => $value) {
if (\is_int($key)) {
$key = (string) $key;
}
$items[$key] = $this->pool->getItem($key)->set($value);
}
}
} catch (SimpleCacheException $e) {
throw $e;
} catch (Psr6CacheException $e) {
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
}
$ok = true;
foreach ($items as $key => $item) {
if ($valuesIsArray) {
$item->set($values[$key]);
}
if (null !== $ttl) {
$item->expiresAfter($ttl);
}
$ok = $this->pool->saveDeferred($item) && $ok;
}
return $this->pool->commit() && $ok;
}
/**
* {@inheritdoc}
*/
public function deleteMultiple($keys)
{
if ($keys instanceof \Traversable) {
$keys = iterator_to_array($keys, false);
} elseif (!\is_array($keys)) {
throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', \is_object($keys) ? \get_class($keys) : \gettype($keys)));
}
try {
return $this->pool->deleteItems($keys);
} catch (SimpleCacheException $e) {
throw $e;
} catch (Psr6CacheException $e) {
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* {@inheritdoc}
*/
public function has($key)
{
try {
return $this->pool->hasItem($key);
} catch (SimpleCacheException $e) {
throw $e;
} catch (Psr6CacheException $e) {
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
}
}
}

View File

@ -11,9 +11,16 @@
namespace Symfony\Component\Cache\Simple;
use Symfony\Component\Cache\Adapter\RedisAdapter;
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
use Symfony\Component\Cache\Traits\RedisTrait;
use Symfony\Contracts\Cache\CacheInterface;
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', RedisCache::class, RedisAdapter::class, CacheInterface::class), E_USER_DEPRECATED);
/**
* @deprecated since Symfony 4.3, use RedisAdapter and type-hint for CacheInterface instead.
*/
class RedisCache extends AbstractCache
{
use RedisTrait;

View File

@ -11,23 +11,24 @@
namespace Symfony\Component\Cache\Simple;
use Psr\SimpleCache\CacheInterface;
use Psr\SimpleCache\CacheInterface as Psr16CacheInterface;
use Symfony\Component\Cache\PruneableInterface;
use Symfony\Component\Cache\ResettableInterface;
use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Service\ResetInterface;
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', TraceableCache::class, TraceableAdapter::class, CacheInterface::class), E_USER_DEPRECATED);
/**
* An adapter that collects data about all cache calls.
*
* @author Nicolas Grekas <p@tchwork.com>
* @deprecated since Symfony 4.3, use TraceableAdapter and type-hint for CacheInterface instead.
*/
class TraceableCache implements CacheInterface, PruneableInterface, ResettableInterface
class TraceableCache implements Psr16CacheInterface, PruneableInterface, ResettableInterface
{
private $pool;
private $miss;
private $calls = [];
public function __construct(CacheInterface $pool)
public function __construct(Psr16CacheInterface $pool)
{
$this->pool = $pool;
$this->miss = new \stdClass();

View File

@ -0,0 +1,31 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Tests\Adapter;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Adapter\Psr16Adapter;
use Symfony\Component\Cache\Psr16Cache;
/**
* @group time-sensitive
*/
class Psr16AdapterTest extends AdapterTestCase
{
protected $skippedTests = [
'testPrune' => 'Psr16adapter just proxies',
];
public function createCachePool($defaultLifetime = 0)
{
return new Psr16Adapter(new Psr16Cache(new FilesystemAdapter()), '', $defaultLifetime);
}
}

View File

@ -11,12 +11,12 @@
namespace Symfony\Component\Cache\Tests\Adapter;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Adapter\SimpleCacheAdapter;
use Symfony\Component\Cache\Simple\Psr6Cache;
use Symfony\Component\Cache\Simple\FilesystemCache;
/**
* @group time-sensitive
* @group legacy
*/
class SimpleCacheAdapterTest extends AdapterTestCase
{
@ -26,6 +26,6 @@ class SimpleCacheAdapterTest extends AdapterTestCase
public function createCachePool($defaultLifetime = 0)
{
return new SimpleCacheAdapter(new Psr6Cache(new FilesystemAdapter()), '', $defaultLifetime);
return new SimpleCacheAdapter(new FilesystemCache(), '', $defaultLifetime);
}
}

View File

@ -0,0 +1,173 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Tests;
use Cache\IntegrationTests\SimpleCacheTest;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\PruneableInterface;
use Symfony\Component\Cache\Psr16Cache;
/**
* @group time-sensitive
*/
class Psr16CacheTest extends SimpleCacheTest
{
protected function setUp()
{
parent::setUp();
if (array_key_exists('testPrune', $this->skippedTests)) {
return;
}
$pool = $this->createSimpleCache();
if ($pool instanceof Psr16Cache) {
$pool = ((array) $pool)[sprintf("\0%s\0pool", Psr16Cache::class)];
}
if (!$pool instanceof PruneableInterface) {
$this->skippedTests['testPrune'] = 'Not a pruneable cache pool.';
}
}
public function createSimpleCache($defaultLifetime = 0)
{
return new Psr16Cache(new FilesystemAdapter('', $defaultLifetime));
}
public static function validKeys()
{
return array_merge(parent::validKeys(), [["a\0b"]]);
}
public function testDefaultLifeTime()
{
if (isset($this->skippedTests[__FUNCTION__])) {
$this->markTestSkipped($this->skippedTests[__FUNCTION__]);
}
$cache = $this->createSimpleCache(2);
$cache->clear();
$cache->set('key.dlt', 'value');
sleep(1);
$this->assertSame('value', $cache->get('key.dlt'));
sleep(2);
$this->assertNull($cache->get('key.dlt'));
$cache->clear();
}
public function testNotUnserializable()
{
if (isset($this->skippedTests[__FUNCTION__])) {
$this->markTestSkipped($this->skippedTests[__FUNCTION__]);
}
$cache = $this->createSimpleCache();
$cache->clear();
$cache->set('foo', new NotUnserializable());
$this->assertNull($cache->get('foo'));
$cache->setMultiple(['foo' => new NotUnserializable()]);
foreach ($cache->getMultiple(['foo']) as $value) {
}
$this->assertNull($value);
$cache->clear();
}
public function testPrune()
{
if (isset($this->skippedTests[__FUNCTION__])) {
$this->markTestSkipped($this->skippedTests[__FUNCTION__]);
}
/** @var PruneableInterface|CacheInterface $cache */
$cache = $this->createSimpleCache();
$cache->clear();
$cache->set('foo', 'foo-val', new \DateInterval('PT05S'));
$cache->set('bar', 'bar-val', new \DateInterval('PT10S'));
$cache->set('baz', 'baz-val', new \DateInterval('PT15S'));
$cache->set('qux', 'qux-val', new \DateInterval('PT20S'));
sleep(30);
$cache->prune();
$this->assertTrue($this->isPruned($cache, 'foo'));
$this->assertTrue($this->isPruned($cache, 'bar'));
$this->assertTrue($this->isPruned($cache, 'baz'));
$this->assertTrue($this->isPruned($cache, 'qux'));
$cache->set('foo', 'foo-val');
$cache->set('bar', 'bar-val', new \DateInterval('PT20S'));
$cache->set('baz', 'baz-val', new \DateInterval('PT40S'));
$cache->set('qux', 'qux-val', new \DateInterval('PT80S'));
$cache->prune();
$this->assertFalse($this->isPruned($cache, 'foo'));
$this->assertFalse($this->isPruned($cache, 'bar'));
$this->assertFalse($this->isPruned($cache, 'baz'));
$this->assertFalse($this->isPruned($cache, 'qux'));
sleep(30);
$cache->prune();
$this->assertFalse($this->isPruned($cache, 'foo'));
$this->assertTrue($this->isPruned($cache, 'bar'));
$this->assertFalse($this->isPruned($cache, 'baz'));
$this->assertFalse($this->isPruned($cache, 'qux'));
sleep(30);
$cache->prune();
$this->assertFalse($this->isPruned($cache, 'foo'));
$this->assertTrue($this->isPruned($cache, 'baz'));
$this->assertFalse($this->isPruned($cache, 'qux'));
sleep(30);
$cache->prune();
$this->assertFalse($this->isPruned($cache, 'foo'));
$this->assertTrue($this->isPruned($cache, 'qux'));
$cache->clear();
}
protected function isPruned($cache, $name)
{
if (Psr16Cache::class !== \get_class($cache)) {
$this->fail('Test classes for pruneable caches must implement `isPruned($cache, $name)` method.');
}
$pool = ((array) $cache)[sprintf("\0%s\0pool", Psr16Cache::class)];
$getFileMethod = (new \ReflectionObject($pool))->getMethod('getFile');
$getFileMethod->setAccessible(true);
return !file_exists($getFileMethod->invoke($pool, $name));
}
}
class NotUnserializable implements \Serializable
{
public function serialize()
{
return serialize(123);
}
public function unserialize($ser)
{
throw new \Exception(__CLASS__);
}
}

View File

@ -13,6 +13,9 @@ namespace Symfony\Component\Cache\Tests\Simple;
use Symfony\Component\Cache\Simple\RedisCache;
/**
* @group legacy
*/
abstract class AbstractRedisCacheTest extends CacheTestCase
{
protected $skippedTests = [

View File

@ -13,6 +13,9 @@ namespace Symfony\Component\Cache\Tests\Simple;
use Symfony\Component\Cache\Simple\ApcuCache;
/**
* @group legacy
*/
class ApcuCacheTest extends CacheTestCase
{
protected $skippedTests = [

View File

@ -15,6 +15,7 @@ use Symfony\Component\Cache\Simple\ArrayCache;
/**
* @group time-sensitive
* @group legacy
*/
class ArrayCacheTest extends CacheTestCase
{

View File

@ -19,6 +19,7 @@ use Symfony\Component\Cache\Simple\FilesystemCache;
/**
* @group time-sensitive
* @group legacy
*/
class ChainCacheTest extends CacheTestCase
{

View File

@ -16,6 +16,7 @@ use Symfony\Component\Cache\Tests\Fixtures\ArrayCache;
/**
* @group time-sensitive
* @group legacy
*/
class DoctrineCacheTest extends CacheTestCase
{

View File

@ -16,6 +16,7 @@ use Symfony\Component\Cache\Simple\FilesystemCache;
/**
* @group time-sensitive
* @group legacy
*/
class FilesystemCacheTest extends CacheTestCase
{

View File

@ -14,6 +14,9 @@ namespace Symfony\Component\Cache\Tests\Simple;
use Symfony\Component\Cache\Adapter\AbstractAdapter;
use Symfony\Component\Cache\Simple\MemcachedCache;
/**
* @group legacy
*/
class MemcachedCacheTest extends CacheTestCase
{
protected $skippedTests = [

View File

@ -14,6 +14,9 @@ namespace Symfony\Component\Cache\Tests\Simple;
use Symfony\Component\Cache\Adapter\AbstractAdapter;
use Symfony\Component\Cache\Simple\MemcachedCache;
/**
* @group legacy
*/
class MemcachedCacheTextModeTest extends MemcachedCacheTest
{
public function createSimpleCache($defaultLifetime = 0)

View File

@ -16,6 +16,7 @@ use Symfony\Component\Cache\Simple\NullCache;
/**
* @group time-sensitive
* @group legacy
*/
class NullCacheTest extends TestCase
{

View File

@ -16,6 +16,7 @@ use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait;
/**
* @group time-sensitive
* @group legacy
*/
class PdoCacheTest extends CacheTestCase
{

View File

@ -17,6 +17,7 @@ use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait;
/**
* @group time-sensitive
* @group legacy
*/
class PdoDbalCacheTest extends CacheTestCase
{

View File

@ -17,6 +17,7 @@ use Symfony\Component\Cache\Tests\Adapter\FilesystemAdapterTest;
/**
* @group time-sensitive
* @group legacy
*/
class PhpArrayCacheTest extends CacheTestCase
{
@ -127,35 +128,3 @@ class PhpArrayCacheTest extends CacheTestCase
$this->assertSame($expected, $values, 'Warm up should create a PHP file that OPCache can load in memory');
}
}
class PhpArrayCacheWrapper extends PhpArrayCache
{
protected $data = [];
public function set($key, $value, $ttl = null)
{
(\Closure::bind(function () use ($key, $value) {
$this->data[$key] = $value;
$this->warmUp($this->data);
list($this->keys, $this->values) = eval(substr(file_get_contents($this->file), 6));
}, $this, PhpArrayCache::class))();
return true;
}
public function setMultiple($values, $ttl = null)
{
if (!\is_array($values) && !$values instanceof \Traversable) {
return parent::setMultiple($values, $ttl);
}
(\Closure::bind(function () use ($values) {
foreach ($values as $key => $value) {
$this->data[$key] = $value;
}
$this->warmUp($this->data);
list($this->keys, $this->values) = eval(substr(file_get_contents($this->file), 6));
}, $this, PhpArrayCache::class))();
return true;
}
}

View File

@ -17,6 +17,7 @@ use Symfony\Component\Cache\Tests\Adapter\FilesystemAdapterTest;
/**
* @group time-sensitive
* @group legacy
*/
class PhpArrayCacheWithFallbackTest extends CacheTestCase
{

View File

@ -0,0 +1,46 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Tests\Simple;
use Symfony\Component\Cache\Simple\PhpArrayCache;
class PhpArrayCacheWrapper extends PhpArrayCache
{
protected $data = [];
public function set($key, $value, $ttl = null)
{
(\Closure::bind(function () use ($key, $value) {
$this->data[$key] = $value;
$this->warmUp($this->data);
list($this->keys, $this->values) = eval(substr(file_get_contents($this->file), 6));
}, $this, PhpArrayCache::class))();
return true;
}
public function setMultiple($values, $ttl = null)
{
if (!\is_array($values) && !$values instanceof \Traversable) {
return parent::setMultiple($values, $ttl);
}
(\Closure::bind(function () use ($values) {
foreach ($values as $key => $value) {
$this->data[$key] = $value;
}
$this->warmUp($this->data);
list($this->keys, $this->values) = eval(substr(file_get_contents($this->file), 6));
}, $this, PhpArrayCache::class))();
return true;
}
}

View File

@ -16,6 +16,7 @@ use Symfony\Component\Cache\Simple\PhpFilesCache;
/**
* @group time-sensitive
* @group legacy
*/
class PhpFilesCacheTest extends CacheTestCase
{

View File

@ -13,6 +13,9 @@ namespace Symfony\Component\Cache\Tests\Simple;
use Symfony\Component\Cache\Simple\Psr6Cache;
/**
* @group legacy
*/
abstract class Psr6CacheTest extends CacheTestCase
{
protected $skippedTests = [

View File

@ -15,6 +15,7 @@ use Symfony\Component\Cache\Adapter\FilesystemAdapter;
/**
* @group time-sensitive
* @group legacy
*/
class Psr6CacheWithAdapterTest extends Psr6CacheTest
{

View File

@ -15,6 +15,7 @@ use Symfony\Component\Cache\Tests\Fixtures\ExternalAdapter;
/**
* @group time-sensitive
* @group legacy
*/
class Psr6CacheWithoutAdapterTest extends Psr6CacheTest
{

View File

@ -11,6 +11,9 @@
namespace Symfony\Component\Cache\Tests\Simple;
/**
* @group legacy
*/
class RedisArrayCacheTest extends AbstractRedisCacheTest
{
public static function setupBeforeClass()

View File

@ -13,6 +13,9 @@ namespace Symfony\Component\Cache\Tests\Simple;
use Symfony\Component\Cache\Simple\RedisCache;
/**
* @group legacy
*/
class RedisCacheTest extends AbstractRedisCacheTest
{
public static function setupBeforeClass()

View File

@ -11,6 +11,9 @@
namespace Symfony\Component\Cache\Tests\Simple;
/**
* @group legacy
*/
class RedisClusterCacheTest extends AbstractRedisCacheTest
{
public static function setupBeforeClass()

View File

@ -16,6 +16,7 @@ use Symfony\Component\Cache\Simple\TraceableCache;
/**
* @group time-sensitive
* @group legacy
*/
class TraceableCacheTest extends CacheTestCase
{

View File

@ -24,7 +24,6 @@
"php": "^7.1.3",
"psr/cache": "~1.0",
"psr/log": "~1.0",
"psr/simple-cache": "^1.0",
"symfony/contracts": "^1.0",
"symfony/var-exporter": "^4.2"
},
@ -33,6 +32,7 @@
"doctrine/cache": "~1.6",
"doctrine/dbal": "~2.5",
"predis/predis": "~1.1",
"psr/simple-cache": "^1.0",
"symfony/config": "~4.2",
"symfony/dependency-injection": "~3.4|~4.1",
"symfony/var-dumper": "^4.1.1"