8000 minor #31760 [Cache] remove deprecated PSR-16 implementations et al. … · symfony/symfony@4a437ab · GitHub
[go: up one dir, main page]

Skip to content

Commit 4a437ab

Browse files
minor #31760 [Cache] remove deprecated PSR-16 implementations et al. (nicolas-grekas)
This PR was merged into the 5.0-dev branch. Discussion ---------- [Cache] remove deprecated PSR-16 implementations et al. | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | no | BC breaks? | yes | Deprecations? | no | Tests pass? | yes | Fixed tickets | - | License | MIT | Doc PR | - \o/ (use `Psr16Cache` instead) Commits ------- 38a67f8 [Cache] remove deprecated PSR-16 implementations et al.
2 parents 090cf32 + 38a67f8 commit 4a437ab

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+1611
-4905
lines changed

src/Symfony/Component/Cache/Adapter/ApcuAdapter.php

Lines changed: 99 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,112 @@
1111

1212
namespace Symfony\Component\Cache\Adapter;
1313

14-
use Symfony\Component\Cache\Traits\ApcuTrait;
14+
use Symfony\Component\Cache\CacheItem;
15+
use Symfony\Component\Cache\Exception\CacheException;
1516

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

src/Symfony/Component/Cache/Adapter/ArrayAdapter.php

Lines changed: 143 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,21 @@
1313

1414
use Psr\Cache\CacheItemInterface;
1515
use Psr\Log\LoggerAwareInterface;
16+
use Psr\Log\LoggerAwareTrait;
1617
use Symfony\Component\Cache\CacheItem;
1718
use Symfony\Component\Cache\ResettableInterface;
18-
use Symfony\Component\Cache\Traits\ArrayTrait;
1919
use Symfony\Contracts\Cache\CacheInterface;
2020

2121
/**
2222
* @author Nicolas Grekas <p@tchwork.com>
2323
*/
2424
class ArrayAdapter implements AdapterInterface, CacheInterface, LoggerAwareInterface, ResettableInterface
2525
{
26-
use ArrayTrait;
26+
use LoggerAwareTrait;
2727

28+
private $storeSerialized;
29+
private $values = [];
30+
private $expiries = [];
2831
private $createCacheItem;
2932

3033
/**
@@ -65,6 +68,27 @@ public function get(string $key, callable $callback, float $beta = null, array &
6568
return $item->get();
6669
}
6770

71+
/**
72+
* {@inheritdoc}
73+
*/
74+
public function delete(string $key): bool
75+
{
76+
return $this->deleteItem($key);
77+
}
78+
79+
/**
80+
* {@inheritdoc}
81+
*/
82+
public function hasItem($key)
83+
{
84+
if (\is_string($key) && isset($this->expiries[$key]) && $this->expiries[$key] > microtime(true)) {
85+
return true;
86+
}
87+
CacheItem::validateKey($key);
88+
89+
return isset($this->expiries[$key]) && !$this->deleteItem($key);
90+
}
91+
6892
/**
6993
* {@inheritdoc}
7094
*/
@@ -94,6 +118,19 @@ public function getItems(array $keys = [])
94118
return $this->generateItems($keys, microtime(true), $this->createCacheItem);
95119
}
96120

121+
/**
122+
* {@inheritdoc}
123+
*/
124+
public function deleteItem($key)
125+
{
126+
if (!\is_string($key) || !isset($this->expiries[$key])) {
127+
CacheItem::validateKey($key);
128+
}
129+
unset($this->values[$key], $this->expiries[$key]);
130+
131+
return true;
132+
}
133+
97134
/**
98135
* {@inheritdoc}
99136
*/
@@ -156,8 +193,110 @@ public function commit()
156193
/**
157194
* {@inheritdoc}
158195
*/
159-
public function delete(string $key): bool
196+
public function clear()
160197
{
161-
return $this->deleteItem($key);
198+
$this->values = $this->expiries = [];
199+
200+
return true;
201+
}
202+
203+
/**
204+
* Returns all cached values, with cache miss as null.
205+
*
206+
* @return array
207+
*/
208+
public function getValues()
209+
{
210+
if (!$this->storeSerialized) {
211+
return $this->values;
212+
}
213+
214+
$values = $this->values;
215+
foreach ($values as $k => $v) {
216+
if (null === $v || 'N;' === $v) {
217+
continue;
218+
}
219+
if (!\is_string($v) || !isset($v[2]) || ':' !== $v[1]) {
220+
$values[$k] = serialize($v);
221+
}
222+
}
223+
224+
return $values;
225+
}
226+
227+
/**
228+
* {@inheritdoc}
229+
*/
230+
public function reset()
231+
{
232+
$this->clear();
233+
}
234+
235+
private function generateItems(array $keys, $now, $f)
236+
{
237+
foreach ($keys as $i => $key) {
238+
if (!$isHit = isset($this->expiries[$key]) && ($this->expiries[$key] > $now || !$this->deleteItem($key))) {
239+
$this->values[$key] = $value = null;
240+
} else {
241+
$value = $this->storeSerialized ? $this->unfreeze($key, $isHit) : $this->values[$key];
242+
}
243+
unset($keys[$i]);
244+
245+
yield $key => $f($key, $value, $isHit);
246+
}
247+
248+
foreach ($keys as $key) {
249+
yield $key => $f($key, null, false);
250+
}
251+
}
252+
253+
private function freeze($value, $key)
254+
{
255+
if (null === $value) {
256+
return 'N;';
257+
}
258+
if (\is_string($value)) {
259+
// Serialize strings if they could be confused with serialized objects or arrays
260+
if ('N;' === $value || (isset($value[2]) && ':' === $value[1])) {
261+
return serialize($value);
262+
}
263+
} elseif (!\is_scalar($value)) {
264+
try {
265+
$serialized = serialize($value);
266+
} catch (\Exception $e) {
267+
$type = \is_object($value) ? \get_class($value) : \gettype($value);
268+
$message = sprintf('Failed to save key "{key}" of type %s: %s', $type, $e->getMessage());
269+
CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e]);
270+
271+
return;
272+
}
273+
// Keep value serialized if it contains any objects or any internal references
274+
if ('C' === $serialized[0] || 'O' === $serialized[0] || preg_match('/;[OCRr]:[1-9]/', $serialized)) {
275+
return $serialized;
276+
}
277+
}
278+
279+
return $value;
280+
}
281+
282+
private function unfreeze(string $key, bool &$isHit)
283+
{
284+
if ('N;' === $value = $this->values[$key]) {
285+
return null;
286+
}
287+
if (\is_string($value) && isset($value[2]) && ':' === $value[1]) {
288+
try {
289+
$value = unserialize($value);
290+
} catch (\Exception $e) {
291+
CacheItem::log($this->logger, 'Failed to unserialize key "{key}": '.$e->getMessage(), ['key' => $key, 'exception' => $e]);
292+
$value = false;
293+
}
294+
if (false === $value) {
295+
$this->values[$key] = $value = null;
296+
$isHit = false;
297+
}
298+
}
299+
300+
return $value;
162301
}
163302
}

src/Symfony/Component/Cache/Adapter/DoctrineAdapter.php

Lines changed: 80 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,94 @@
1212
namespace Symfony\Component\Cache\Adapter;
1313

1414
use Doctrine\Common\Cache\CacheProvider;
15-
use Symfony\Component\Cache\Traits\DoctrineTrait;
1615

16+
/**
17+
* @author Nicolas Grekas <p@tchwork.com>
18+
*/
1719
class DoctrineAdapter extends AbstractAdapter
1820
{
19-
use DoctrineTrait;
21+
private $provider;
2022

2123
public function __construct(CacheProvider $provider, string $namespace = '', int $defaultLifetime = 0)
2224
{
2325
parent::__construct('', $defaultLifetime);
2426
$this->provider = $provider;
2527
$provider->setNamespace($namespace);
2628
}
29+
30+
/**
31+
* {@inheritdoc}
32+
*/
33+
public function reset()
34+
{
35+
parent::reset();
36+
$this->provider->setNamespace($this->provider->getNamespace());
37+
}
38+
39+
/**
40+
* {@inheritdoc}
41+
*/
42+
protected function doFetch(array $ids)
43+
{
44+
$unserializeCallbackHandler = ini_set('unserialize_callback_func', parent::class.'::handleUnserializeCallback');
45+
try {
46+
return $this->provider->fetchMultiple($ids);
47+
} catch (\Error $e) {
48+
$trace = $e->getTrace();
49+
50+
if (isset($trace[0]['function']) && !isset($trace[0]['class'])) {
51+
switch ($trace[0]['function']) {
52+
case 'unserialize':
53+
case 'apcu_fetch':
54+
case 'apc_fetch':
55+
throw new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine());
56+
}
57+
}
58+
59+
throw $e;
60+
} finally {
61+
ini_set('unserialize_callback_func', $unserializeCallbackHandler);
62+
}
63+
}
64+
65+
/**
66+
* {@inheritdoc}
67+
*/
68+
protected function doHave($id)
69+
{
70+
return $this->provider->contains($id);
71+
}
72+
73+
/**
74+
* {@inheritdoc}
75+
*/
76+
protected function doClear($namespace)
77+
{
78+
$namespace = $this->provider->getNamespace();
79+
80+
return isset($namespace[0])
81+
? $this->provider->deleteAll()
82+
: $this->provider->flushAll();
83+
}
84+
85+
/**
86+
* {@inheritdoc}
87+
*/
88+
protected function doDelete(array $ids)
89+
{
90+
$ok = true;
91+
foreach ($ids as $id) {
92+
$ok = $this->provider->delete($id) && $ok;
93+
}
94+
95+
return $ok;
96+
}
97+
98+
/**
99+
* {@inheritdoc}
100+
*/
101+
protected function doSave(array $values, $lifetime)
102+
{
103+
return $this->provider->saveMultiple($values, $lifetime);
104+
}
27105
}

0 commit comments

Comments
 (0)
0