feature #29236 [Cache] deprecate all PSR-16 adapters, provide Psr16Cache instead (nicolas-grekas)
This PR was merged into the 4.3-dev branch.
Discussion
----------
[Cache] deprecate all PSR-16 adapters, provide Psr16Cache instead
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | no
| BC breaks? | no
| Deprecations? | yes
| Tests pass? | yes
| Fixed tickets | -
| License | MIT
| Doc PR | -
As discussed in https://github.com/symfony/symfony/issues/28918, PSR-16 implementations are now mostly useless: either PSR-6 or contracts' CacheInterface is always a better fit.
Let's deprecate them all but keep only a `Psr16Cache` to turn any PSR-6 implementation to a PSR-16 one.
From the changelog:
* 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
* deprecated the "Psr\SimpleCache\CacheInterface" / "cache.app.simple" service, use "Symfony\Contracts\Cache\CacheInterface" / "cache.app" instead
Commits
-------
5006be63c1
[Cache] deprecate all PSR-16 adapters, provide Psr16Cache instead
This commit is contained in:
commit
4fbb6e5fa4
@ -8,6 +8,13 @@ BrowserKit
|
|||||||
* Deprecated `Response::buildHeader()`
|
* Deprecated `Response::buildHeader()`
|
||||||
* Deprecated `Response::getStatus()`, use `Response::getStatusCode()` instead
|
* 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
|
Config
|
||||||
------
|
------
|
||||||
|
|
||||||
@ -18,6 +25,7 @@ FrameworkBundle
|
|||||||
|
|
||||||
* Not passing the project directory to the constructor of the `AssetsInstallCommand` is deprecated. This argument will
|
* Not passing the project directory to the constructor of the `AssetsInstallCommand` is deprecated. This argument will
|
||||||
be mandatory in 5.0.
|
be mandatory in 5.0.
|
||||||
|
* Deprecated the "Psr\SimpleCache\CacheInterface" / "cache.app.simple" service, use "Symfony\Contracts\Cache\CacheInterface" / "cache.app" instead.
|
||||||
|
|
||||||
HttpFoundation
|
HttpFoundation
|
||||||
--------------
|
--------------
|
||||||
|
@ -13,6 +13,8 @@ Cache
|
|||||||
-----
|
-----
|
||||||
|
|
||||||
* Removed `CacheItem::getPreviousTags()`, use `CacheItem::getMetadata()` instead.
|
* 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
|
Config
|
||||||
------
|
------
|
||||||
@ -163,6 +165,7 @@ FrameworkBundle
|
|||||||
* The `Templating\Helper\TranslatorHelper::transChoice()` method has been removed, use the `trans()` one instead with a `%count%` parameter.
|
* 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.
|
* 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.
|
* 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
|
HttpFoundation
|
||||||
--------------
|
--------------
|
||||||
|
@ -8,6 +8,7 @@ CHANGELOG
|
|||||||
be mandatory in 5.0.
|
be mandatory in 5.0.
|
||||||
* Added `ControllerTrait::isFormValid()`
|
* Added `ControllerTrait::isFormValid()`
|
||||||
* Added an `help_html` form option to display the `help` text as HTML
|
* 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
|
* [BC Break] When using Messenger, the default transport changed from
|
||||||
using Symfony's serializer service to use `PhpSerializer`, which uses
|
using Symfony's serializer service to use `PhpSerializer`, which uses
|
||||||
|
@ -11,7 +11,8 @@
|
|||||||
<tag name="cache.pool" clearer="cache.app_clearer" reset="reset" />
|
<tag name="cache.pool" clearer="cache.app_clearer" reset="reset" />
|
||||||
</service>
|
</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" />
|
<argument type="service" id="cache.app" />
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
"require": {
|
"require": {
|
||||||
"php": "^7.1.3",
|
"php": "^7.1.3",
|
||||||
"ext-xml": "*",
|
"ext-xml": "*",
|
||||||
"symfony/cache": "~4.2",
|
"symfony/cache": "~4.3",
|
||||||
"symfony/config": "~4.2",
|
"symfony/config": "~4.2",
|
||||||
"symfony/contracts": "^1.0.2",
|
"symfony/contracts": "^1.0.2",
|
||||||
"symfony/dependency-injection": "^4.2",
|
"symfony/dependency-injection": "^4.2",
|
||||||
|
81
src/Symfony/Component/Cache/Adapter/Psr16Adapter.php
Normal file
81
src/Symfony/Component/Cache/Adapter/Psr16Adapter.php
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
@ -11,69 +11,11 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Cache\Adapter;
|
namespace Symfony\Component\Cache\Adapter;
|
||||||
|
|
||||||
use Psr\SimpleCache\CacheInterface;
|
@trigger_error(sprintf('The "%s" class is @deprecated since Symfony 4.3, use "Psr16Adapter" instead.', SimpleCacheAdapter::class), E_USER_DEPRECATED);
|
||||||
use Symfony\Component\Cache\PruneableInterface;
|
|
||||||
use Symfony\Component\Cache\ResettableInterface;
|
|
||||||
use Symfony\Component\Cache\Traits\ProxyTrait;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
CHANGELOG
|
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
|
4.2.0
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
@ -14,6 +14,12 @@ namespace Symfony\Component\Cache\Exception;
|
|||||||
use Psr\Cache\CacheException as Psr6CacheInterface;
|
use Psr\Cache\CacheException as Psr6CacheInterface;
|
||||||
use Psr\SimpleCache\CacheException as SimpleCacheInterface;
|
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
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,12 @@ namespace Symfony\Component\Cache\Exception;
|
|||||||
use Psr\Cache\InvalidArgumentException as Psr6CacheInterface;
|
use Psr\Cache\InvalidArgumentException as Psr6CacheInterface;
|
||||||
use Psr\SimpleCache\InvalidArgumentException as SimpleCacheInterface;
|
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
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,12 @@ namespace Symfony\Component\Cache\Exception;
|
|||||||
use Psr\Cache\CacheException as Psr6CacheInterface;
|
use Psr\Cache\CacheException as Psr6CacheInterface;
|
||||||
use Psr\SimpleCache\CacheException as SimpleCacheInterface;
|
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
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,7 @@ class LockRegistry
|
|||||||
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'PhpArrayAdapter.php',
|
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'PhpArrayAdapter.php',
|
||||||
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'PhpFilesAdapter.php',
|
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'PhpFilesAdapter.php',
|
||||||
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'ProxyAdapter.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.'RedisAdapter.php',
|
||||||
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'SimpleCacheAdapter.php',
|
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'SimpleCacheAdapter.php',
|
||||||
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'TagAwareAdapter.php',
|
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'TagAwareAdapter.php',
|
||||||
|
263
src/Symfony/Component/Cache/Psr16Cache.php
Normal file
263
src/Symfony/Component/Cache/Psr16Cache.php
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -12,16 +12,20 @@
|
|||||||
namespace Symfony\Component\Cache\Simple;
|
namespace Symfony\Component\Cache\Simple;
|
||||||
|
|
||||||
use Psr\Log\LoggerAwareInterface;
|
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\CacheItem;
|
||||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||||
use Symfony\Component\Cache\ResettableInterface;
|
use Symfony\Component\Cache\ResettableInterface;
|
||||||
use Symfony\Component\Cache\Traits\AbstractTrait;
|
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 {
|
use AbstractTrait {
|
||||||
deleteItems as private;
|
deleteItems as private;
|
||||||
|
@ -13,6 +13,11 @@ namespace Symfony\Component\Cache\Simple;
|
|||||||
|
|
||||||
use Symfony\Component\Cache\Traits\ApcuTrait;
|
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
|
class ApcuCache extends AbstractCache
|
||||||
{
|
{
|
||||||
use ApcuTrait;
|
use ApcuTrait;
|
||||||
|
@ -12,16 +12,20 @@
|
|||||||
namespace Symfony\Component\Cache\Simple;
|
namespace Symfony\Component\Cache\Simple;
|
||||||
|
|
||||||
use Psr\Log\LoggerAwareInterface;
|
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\CacheItem;
|
||||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||||
use Symfony\Component\Cache\ResettableInterface;
|
use Symfony\Component\Cache\ResettableInterface;
|
||||||
use Symfony\Component\Cache\Traits\ArrayTrait;
|
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 {
|
use ArrayTrait {
|
||||||
ArrayTrait::deleteItem as delete;
|
ArrayTrait::deleteItem as delete;
|
||||||
|
@ -11,21 +11,25 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Cache\Simple;
|
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\Exception\InvalidArgumentException;
|
||||||
use Symfony\Component\Cache\PruneableInterface;
|
use Symfony\Component\Cache\PruneableInterface;
|
||||||
use Symfony\Component\Cache\ResettableInterface;
|
use Symfony\Component\Cache\ResettableInterface;
|
||||||
|
use Symfony\Contracts\Cache\CacheInterface;
|
||||||
use Symfony\Contracts\Service\ResetInterface;
|
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.
|
* Chains several caches together.
|
||||||
*
|
*
|
||||||
* Cached items are fetched from the first cache having them in its data store.
|
* Cached items are fetched from the first cache having them in its data store.
|
||||||
* They are saved and deleted in all caches at once.
|
* 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 $miss;
|
||||||
private $caches = [];
|
private $caches = [];
|
||||||
@ -33,8 +37,8 @@ class ChainCache implements CacheInterface, PruneableInterface, ResettableInterf
|
|||||||
private $cacheCount;
|
private $cacheCount;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param CacheInterface[] $caches The ordered list of caches used to fetch cached items
|
* @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
|
* @param int $defaultLifetime The lifetime of items propagated from lower caches to upper ones
|
||||||
*/
|
*/
|
||||||
public function __construct(array $caches, int $defaultLifetime = 0)
|
public function __construct(array $caches, int $defaultLifetime = 0)
|
||||||
{
|
{
|
||||||
@ -43,8 +47,8 @@ class ChainCache implements CacheInterface, PruneableInterface, ResettableInterf
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach ($caches as $cache) {
|
foreach ($caches as $cache) {
|
||||||
if (!$cache instanceof CacheInterface) {
|
if (!$cache instanceof Psr16CacheInterface) {
|
||||||
throw new InvalidArgumentException(sprintf('The class "%s" does not implement the "%s" interface.', \get_class($cache), CacheInterface::class));
|
throw new InvalidArgumentException(sprintf('The class "%s" does not implement the "%s" interface.', \get_class($cache), Psr16CacheInterface::class));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,8 +12,15 @@
|
|||||||
namespace Symfony\Component\Cache\Simple;
|
namespace Symfony\Component\Cache\Simple;
|
||||||
|
|
||||||
use Doctrine\Common\Cache\CacheProvider;
|
use Doctrine\Common\Cache\CacheProvider;
|
||||||
|
use Symfony\Component\Cache\Adapter\DoctrineAdapter;
|
||||||
use Symfony\Component\Cache\Traits\DoctrineTrait;
|
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
|
class DoctrineCache extends AbstractCache
|
||||||
{
|
{
|
||||||
use DoctrineTrait;
|
use DoctrineTrait;
|
||||||
|
@ -11,11 +11,18 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Cache\Simple;
|
namespace Symfony\Component\Cache\Simple;
|
||||||
|
|
||||||
|
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
||||||
use Symfony\Component\Cache\Marshaller\DefaultMarshaller;
|
use Symfony\Component\Cache\Marshaller\DefaultMarshaller;
|
||||||
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
|
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
|
||||||
use Symfony\Component\Cache\PruneableInterface;
|
use Symfony\Component\Cache\PruneableInterface;
|
||||||
use Symfony\Component\Cache\Traits\FilesystemTrait;
|
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
|
class FilesystemCache extends AbstractCache implements PruneableInterface
|
||||||
{
|
{
|
||||||
use FilesystemTrait;
|
use FilesystemTrait;
|
||||||
|
@ -11,9 +11,16 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Cache\Simple;
|
namespace Symfony\Component\Cache\Simple;
|
||||||
|
|
||||||
|
use Symfony\Component\Cache\Adapter\MemcachedAdapter;
|
||||||
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
|
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
|
||||||
use Symfony\Component\Cache\Traits\MemcachedTrait;
|
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
|
class MemcachedCache extends AbstractCache
|
||||||
{
|
{
|
||||||
use MemcachedTrait;
|
use MemcachedTrait;
|
||||||
|
@ -11,12 +11,16 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Cache\Simple;
|
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}
|
* {@inheritdoc}
|
||||||
|
@ -11,10 +11,17 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Cache\Simple;
|
namespace Symfony\Component\Cache\Simple;
|
||||||
|
|
||||||
|
use Symfony\Component\Cache\Adapter\PdoAdapter;
|
||||||
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
|
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
|
||||||
use Symfony\Component\Cache\PruneableInterface;
|
use Symfony\Component\Cache\PruneableInterface;
|
||||||
use Symfony\Component\Cache\Traits\PdoTrait;
|
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
|
class PdoCache extends AbstractCache implements PruneableInterface
|
||||||
{
|
{
|
||||||
use PdoTrait;
|
use PdoTrait;
|
||||||
|
@ -11,28 +11,28 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Cache\Simple;
|
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\Exception\InvalidArgumentException;
|
||||||
use Symfony\Component\Cache\PruneableInterface;
|
use Symfony\Component\Cache\PruneableInterface;
|
||||||
use Symfony\Component\Cache\ResettableInterface;
|
use Symfony\Component\Cache\ResettableInterface;
|
||||||
use Symfony\Component\Cache\Traits\PhpArrayTrait;
|
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.
|
* @deprecated since Symfony 4.3, use PhpArrayAdapter and type-hint for CacheInterface instead.
|
||||||
* 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>
|
|
||||||
*/
|
*/
|
||||||
class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInterface
|
class PhpArrayCache implements Psr16CacheInterface, PruneableInterface, ResettableInterface
|
||||||
{
|
{
|
||||||
use PhpArrayTrait;
|
use PhpArrayTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $file The PHP file were values are cached
|
* @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 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->file = $file;
|
||||||
$this->pool = $fallbackPool;
|
$this->pool = $fallbackPool;
|
||||||
@ -43,9 +43,9 @@ class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInt
|
|||||||
*
|
*
|
||||||
* @param string $file The PHP file were values are cached
|
* @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
|
// Shared memory is available in PHP 7.0+ with OPCache enabled
|
||||||
if (filter_var(ini_get('opcache.enable'), FILTER_VALIDATE_BOOLEAN)) {
|
if (filter_var(ini_get('opcache.enable'), FILTER_VALIDATE_BOOLEAN)) {
|
||||||
|
@ -11,10 +11,17 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Cache\Simple;
|
namespace Symfony\Component\Cache\Simple;
|
||||||
|
|
||||||
|
use Symfony\Component\Cache\Adapter\PhpFilesAdapter;
|
||||||
use Symfony\Component\Cache\Exception\CacheException;
|
use Symfony\Component\Cache\Exception\CacheException;
|
||||||
use Symfony\Component\Cache\PruneableInterface;
|
use Symfony\Component\Cache\PruneableInterface;
|
||||||
use Symfony\Component\Cache\Traits\PhpFilesTrait;
|
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
|
class PhpFilesCache extends AbstractCache implements PruneableInterface
|
||||||
{
|
{
|
||||||
use PhpFilesTrait;
|
use PhpFilesTrait;
|
||||||
|
@ -11,254 +11,13 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Cache\Simple;
|
namespace Symfony\Component\Cache\Simple;
|
||||||
|
|
||||||
use Psr\Cache\CacheException as Psr6CacheException;
|
use Symfony\Component\Cache\Psr16Cache;
|
||||||
use Psr\Cache\CacheItemPoolInterface;
|
|
||||||
use Psr\SimpleCache\CacheException as SimpleCacheException;
|
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" instead.', Psr6Cache::class, Psr16Cache::class), E_USER_DEPRECATED);
|
||||||
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;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,16 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Cache\Simple;
|
namespace Symfony\Component\Cache\Simple;
|
||||||
|
|
||||||
|
use Symfony\Component\Cache\Adapter\RedisAdapter;
|
||||||
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
|
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
|
||||||
use Symfony\Component\Cache\Traits\RedisTrait;
|
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
|
class RedisCache extends AbstractCache
|
||||||
{
|
{
|
||||||
use RedisTrait;
|
use RedisTrait;
|
||||||
|
@ -11,23 +11,24 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Cache\Simple;
|
namespace Symfony\Component\Cache\Simple;
|
||||||
|
|
||||||
use Psr\SimpleCache\CacheInterface;
|
use Psr\SimpleCache\CacheInterface as Psr16CacheInterface;
|
||||||
use Symfony\Component\Cache\PruneableInterface;
|
use Symfony\Component\Cache\PruneableInterface;
|
||||||
use Symfony\Component\Cache\ResettableInterface;
|
use Symfony\Component\Cache\ResettableInterface;
|
||||||
|
use Symfony\Contracts\Cache\CacheInterface;
|
||||||
use Symfony\Contracts\Service\ResetInterface;
|
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.
|
* @deprecated since Symfony 4.3, use TraceableAdapter and type-hint for CacheInterface instead.
|
||||||
*
|
|
||||||
* @author Nicolas Grekas <p@tchwork.com>
|
|
||||||
*/
|
*/
|
||||||
class TraceableCache implements CacheInterface, PruneableInterface, ResettableInterface
|
class TraceableCache implements Psr16CacheInterface, PruneableInterface, ResettableInterface
|
||||||
{
|
{
|
||||||
private $pool;
|
private $pool;
|
||||||
private $miss;
|
private $miss;
|
||||||
private $calls = [];
|
private $calls = [];
|
||||||
|
|
||||||
public function __construct(CacheInterface $pool)
|
public function __construct(Psr16CacheInterface $pool)
|
||||||
{
|
{
|
||||||
$this->pool = $pool;
|
$this->pool = $pool;
|
||||||
$this->miss = new \stdClass();
|
$this->miss = new \stdClass();
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -11,12 +11,12 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||||
|
|
||||||
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
|
||||||
use Symfony\Component\Cache\Adapter\SimpleCacheAdapter;
|
use Symfony\Component\Cache\Adapter\SimpleCacheAdapter;
|
||||||
use Symfony\Component\Cache\Simple\Psr6Cache;
|
use Symfony\Component\Cache\Simple\FilesystemCache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @group time-sensitive
|
* @group time-sensitive
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
class SimpleCacheAdapterTest extends AdapterTestCase
|
class SimpleCacheAdapterTest extends AdapterTestCase
|
||||||
{
|
{
|
||||||
@ -26,6 +26,6 @@ class SimpleCacheAdapterTest extends AdapterTestCase
|
|||||||
|
|
||||||
public function createCachePool($defaultLifetime = 0)
|
public function createCachePool($defaultLifetime = 0)
|
||||||
{
|
{
|
||||||
return new SimpleCacheAdapter(new Psr6Cache(new FilesystemAdapter()), '', $defaultLifetime);
|
return new SimpleCacheAdapter(new FilesystemCache(), '', $defaultLifetime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
173
src/Symfony/Component/Cache/Tests/Psr16CacheTest.php
Normal file
173
src/Symfony/Component/Cache/Tests/Psr16CacheTest.php
Normal 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__);
|
||||||
|
}
|
||||||
|
}
|
@ -13,6 +13,9 @@ namespace Symfony\Component\Cache\Tests\Simple;
|
|||||||
|
|
||||||
use Symfony\Component\Cache\Simple\RedisCache;
|
use Symfony\Component\Cache\Simple\RedisCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
abstract class AbstractRedisCacheTest extends CacheTestCase
|
abstract class AbstractRedisCacheTest extends CacheTestCase
|
||||||
{
|
{
|
||||||
protected $skippedTests = [
|
protected $skippedTests = [
|
||||||
|
@ -13,6 +13,9 @@ namespace Symfony\Component\Cache\Tests\Simple;
|
|||||||
|
|
||||||
use Symfony\Component\Cache\Simple\ApcuCache;
|
use Symfony\Component\Cache\Simple\ApcuCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
class ApcuCacheTest extends CacheTestCase
|
class ApcuCacheTest extends CacheTestCase
|
||||||
{
|
{
|
||||||
protected $skippedTests = [
|
protected $skippedTests = [
|
||||||
|
@ -15,6 +15,7 @@ use Symfony\Component\Cache\Simple\ArrayCache;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @group time-sensitive
|
* @group time-sensitive
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
class ArrayCacheTest extends CacheTestCase
|
class ArrayCacheTest extends CacheTestCase
|
||||||
{
|
{
|
||||||
|
@ -19,6 +19,7 @@ use Symfony\Component\Cache\Simple\FilesystemCache;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @group time-sensitive
|
* @group time-sensitive
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
class ChainCacheTest extends CacheTestCase
|
class ChainCacheTest extends CacheTestCase
|
||||||
{
|
{
|
||||||
|
@ -16,6 +16,7 @@ use Symfony\Component\Cache\Tests\Fixtures\ArrayCache;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @group time-sensitive
|
* @group time-sensitive
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
class DoctrineCacheTest extends CacheTestCase
|
class DoctrineCacheTest extends CacheTestCase
|
||||||
{
|
{
|
||||||
|
@ -16,6 +16,7 @@ use Symfony\Component\Cache\Simple\FilesystemCache;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @group time-sensitive
|
* @group time-sensitive
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
class FilesystemCacheTest extends CacheTestCase
|
class FilesystemCacheTest extends CacheTestCase
|
||||||
{
|
{
|
||||||
|
@ -14,6 +14,9 @@ namespace Symfony\Component\Cache\Tests\Simple;
|
|||||||
use Symfony\Component\Cache\Adapter\AbstractAdapter;
|
use Symfony\Component\Cache\Adapter\AbstractAdapter;
|
||||||
use Symfony\Component\Cache\Simple\MemcachedCache;
|
use Symfony\Component\Cache\Simple\MemcachedCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
class MemcachedCacheTest extends CacheTestCase
|
class MemcachedCacheTest extends CacheTestCase
|
||||||
{
|
{
|
||||||
protected $skippedTests = [
|
protected $skippedTests = [
|
||||||
|
@ -14,6 +14,9 @@ namespace Symfony\Component\Cache\Tests\Simple;
|
|||||||
use Symfony\Component\Cache\Adapter\AbstractAdapter;
|
use Symfony\Component\Cache\Adapter\AbstractAdapter;
|
||||||
use Symfony\Component\Cache\Simple\MemcachedCache;
|
use Symfony\Component\Cache\Simple\MemcachedCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
class MemcachedCacheTextModeTest extends MemcachedCacheTest
|
class MemcachedCacheTextModeTest extends MemcachedCacheTest
|
||||||
{
|
{
|
||||||
public function createSimpleCache($defaultLifetime = 0)
|
public function createSimpleCache($defaultLifetime = 0)
|
||||||
|
@ -16,6 +16,7 @@ use Symfony\Component\Cache\Simple\NullCache;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @group time-sensitive
|
* @group time-sensitive
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
class NullCacheTest extends TestCase
|
class NullCacheTest extends TestCase
|
||||||
{
|
{
|
||||||
|
@ -16,6 +16,7 @@ use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @group time-sensitive
|
* @group time-sensitive
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
class PdoCacheTest extends CacheTestCase
|
class PdoCacheTest extends CacheTestCase
|
||||||
{
|
{
|
||||||
|
@ -17,6 +17,7 @@ use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @group time-sensitive
|
* @group time-sensitive
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
class PdoDbalCacheTest extends CacheTestCase
|
class PdoDbalCacheTest extends CacheTestCase
|
||||||
{
|
{
|
||||||
|
@ -17,6 +17,7 @@ use Symfony\Component\Cache\Tests\Adapter\FilesystemAdapterTest;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @group time-sensitive
|
* @group time-sensitive
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
class PhpArrayCacheTest extends CacheTestCase
|
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');
|
$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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -17,6 +17,7 @@ use Symfony\Component\Cache\Tests\Adapter\FilesystemAdapterTest;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @group time-sensitive
|
* @group time-sensitive
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
class PhpArrayCacheWithFallbackTest extends CacheTestCase
|
class PhpArrayCacheWithFallbackTest extends CacheTestCase
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -16,6 +16,7 @@ use Symfony\Component\Cache\Simple\PhpFilesCache;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @group time-sensitive
|
* @group time-sensitive
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
class PhpFilesCacheTest extends CacheTestCase
|
class PhpFilesCacheTest extends CacheTestCase
|
||||||
{
|
{
|
||||||
|
@ -13,6 +13,9 @@ namespace Symfony\Component\Cache\Tests\Simple;
|
|||||||
|
|
||||||
use Symfony\Component\Cache\Simple\Psr6Cache;
|
use Symfony\Component\Cache\Simple\Psr6Cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
abstract class Psr6CacheTest extends CacheTestCase
|
abstract class Psr6CacheTest extends CacheTestCase
|
||||||
{
|
{
|
||||||
protected $skippedTests = [
|
protected $skippedTests = [
|
||||||
|
@ -15,6 +15,7 @@ use Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @group time-sensitive
|
* @group time-sensitive
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
class Psr6CacheWithAdapterTest extends Psr6CacheTest
|
class Psr6CacheWithAdapterTest extends Psr6CacheTest
|
||||||
{
|
{
|
||||||
|
@ -15,6 +15,7 @@ use Symfony\Component\Cache\Tests\Fixtures\ExternalAdapter;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @group time-sensitive
|
* @group time-sensitive
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
class Psr6CacheWithoutAdapterTest extends Psr6CacheTest
|
class Psr6CacheWithoutAdapterTest extends Psr6CacheTest
|
||||||
{
|
{
|
||||||
|
@ -11,6 +11,9 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Cache\Tests\Simple;
|
namespace Symfony\Component\Cache\Tests\Simple;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
class RedisArrayCacheTest extends AbstractRedisCacheTest
|
class RedisArrayCacheTest extends AbstractRedisCacheTest
|
||||||
{
|
{
|
||||||
public static function setupBeforeClass()
|
public static function setupBeforeClass()
|
||||||
|
@ -13,6 +13,9 @@ namespace Symfony\Component\Cache\Tests\Simple;
|
|||||||
|
|
||||||
use Symfony\Component\Cache\Simple\RedisCache;
|
use Symfony\Component\Cache\Simple\RedisCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
class RedisCacheTest extends AbstractRedisCacheTest
|
class RedisCacheTest extends AbstractRedisCacheTest
|
||||||
{
|
{
|
||||||
public static function setupBeforeClass()
|
public static function setupBeforeClass()
|
||||||
|
@ -11,6 +11,9 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Cache\Tests\Simple;
|
namespace Symfony\Component\Cache\Tests\Simple;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
class RedisClusterCacheTest extends AbstractRedisCacheTest
|
class RedisClusterCacheTest extends AbstractRedisCacheTest
|
||||||
{
|
{
|
||||||
public static function setupBeforeClass()
|
public static function setupBeforeClass()
|
||||||
|
@ -16,6 +16,7 @@ use Symfony\Component\Cache\Simple\TraceableCache;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @group time-sensitive
|
* @group time-sensitive
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
class TraceableCacheTest extends CacheTestCase
|
class TraceableCacheTest extends CacheTestCase
|
||||||
{
|
{
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
"php": "^7.1.3",
|
"php": "^7.1.3",
|
||||||
"psr/cache": "~1.0",
|
"psr/cache": "~1.0",
|
||||||
"psr/log": "~1.0",
|
"psr/log": "~1.0",
|
||||||
"psr/simple-cache": "^1.0",
|
|
||||||
"symfony/contracts": "^1.0",
|
"symfony/contracts": "^1.0",
|
||||||
"symfony/var-exporter": "^4.2"
|
"symfony/var-exporter": "^4.2"
|
||||||
},
|
},
|
||||||
@ -33,6 +32,7 @@
|
|||||||
"doctrine/cache": "~1.6",
|
"doctrine/cache": "~1.6",
|
||||||
"doctrine/dbal": "~2.5",
|
"doctrine/dbal": "~2.5",
|
||||||
"predis/predis": "~1.1",
|
"predis/predis": "~1.1",
|
||||||
|
"psr/simple-cache": "^1.0",
|
||||||
"symfony/config": "~4.2",
|
"symfony/config": "~4.2",
|
||||||
"symfony/dependency-injection": "~3.4|~4.1",
|
"symfony/dependency-injection": "~3.4|~4.1",
|
||||||
"symfony/var-dumper": "^4.1.1"
|
"symfony/var-dumper": "^4.1.1"
|
||||||
|
Reference in New Issue
Block a user