diff --git a/src/Symfony/Component/Cache/Adapter/ApcuAdapter.php b/src/Symfony/Component/Cache/Adapter/ApcuAdapter.php index dc6b5316c3c82..28ebce3e8fc48 100644 --- a/src/Symfony/Component/Cache/Adapter/ApcuAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/ApcuAdapter.php @@ -13,16 +13,19 @@ use Symfony\Component\Cache\CacheItem; use Symfony\Component\Cache\Exception\CacheException; +use Symfony\Component\Cache\Marshaller\MarshallerInterface; /** * @author Nicolas Grekas
*/ class ApcuAdapter extends AbstractAdapter { + private $marshaller; + /** * @throws CacheException if APCu is not enabled */ - public function __construct(string $namespace = '', int $defaultLifetime = 0, string $version = null) + public function __construct(string $namespace = '', int $defaultLifetime = 0, string $version = null, ?MarshallerInterface $marshaller = null) { if (!static::isSupported()) { throw new CacheException('APCu is not enabled.'); @@ -40,6 +43,8 @@ public function __construct(string $namespace = '', int $defaultLifetime = 0, st apcu_add($version.'@'.$namespace, null); } } + + $this->marshaller = $marshaller; } public static function isSupported() @@ -57,7 +62,7 @@ protected function doFetch(array $ids) $values = []; foreach (apcu_fetch($ids, $ok) ?: [] as $k => $v) { if (null !== $v || $ok) { - $values[$k] = $v; + $values[$k] = null !== $this->marshaller ? $this->marshaller->unmarshall($v) : $v; } } @@ -104,6 +109,10 @@ protected function doDelete(array $ids) */ protected function doSave(array $values, int $lifetime) { + if (null !== $this->marshaller && (!$values = $this->marshaller->marshall($values, $failed))) { + return $failed; + } + try { if (false === $failures = apcu_store($values, null, $lifetime)) { $failures = $values; diff --git a/src/Symfony/Component/Cache/CHANGELOG.md b/src/Symfony/Component/Cache/CHANGELOG.md index 5712ebf92a50b..89f3e884e37fe 100644 --- a/src/Symfony/Component/Cache/CHANGELOG.md +++ b/src/Symfony/Component/Cache/CHANGELOG.md @@ -5,6 +5,7 @@ CHANGELOG --- * added support for connecting to Redis Sentinel clusters when using the Redis PHP extension + * add support for a custom serializer to the `ApcuAdapter` class 5.2.0 ----- diff --git a/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php index 120a4e5a17a4b..c2973681c4267 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php @@ -14,6 +14,7 @@ use Psr\Cache\CacheItemPoolInterface; use Psr\Log\NullLogger; use Symfony\Component\Cache\Adapter\ApcuAdapter; +use Symfony\Component\Cache\Marshaller\MarshallerInterface; class ApcuAdapterTest extends AdapterTestCase { @@ -122,4 +123,30 @@ public function testWithCliSapi() restore_error_handler(); } } + + public function testCacheItemValueRunsThroughMarshaller() + { + $namespace = str_replace('\\', '.', static::class); + + $marshaller = $this->createMock(MarshallerInterface::class); + $marshaller->expects($this->once()) + ->method('marshall') + ->with([$namespace.':foo' => 'bar']) + ->willReturn([$namespace.':foo' => 'bar_serialized']); + + $marshaller->expects($this->once()) + ->method('unmarshall') + ->with('bar_serialized') + ->willReturn('bar'); + + $pool = new ApcuAdapter($namespace, 0, 'p1', $marshaller); + + $item = $pool->getItem('foo'); + $this->assertFalse($item->isHit()); + $this->assertTrue($pool->save($item->set('bar'))); + + $item = $pool->getItem('foo'); + $this->assertTrue($item->isHit()); + $this->assertSame('bar', $item->get()); + } }
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: