Skip to content

Commit a5823af

Browse files
[Cache] Fix internal representation of non-static values
1 parent 2205b62 commit a5823af

File tree

3 files changed

+36
-14
lines changed

3 files changed

+36
-14
lines changed

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

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Symfony\Component\Cache\Exception\InvalidArgumentException;
1818
use Symfony\Component\Cache\PruneableInterface;
1919
use Symfony\Component\Cache\ResettableInterface;
20+
use Symfony\Component\Cache\Traits\CachedValueInterface;
2021
use Symfony\Component\Cache\Traits\ContractsTrait;
2122
use Symfony\Component\Cache\Traits\ProxyTrait;
2223
use Symfony\Component\VarExporter\VarExporter;
@@ -96,16 +97,15 @@ public function get(string $key, callable $callback, ?float $beta = null, ?array
9697
if ('N;' === $value) {
9798
return null;
9899
}
100+
if (!$value instanceof CachedValueInterface) {
101+
return $value;
102+
}
99103
try {
100-
if ($value instanceof \Closure) {
101-
return $value();
102-
}
104+
return $value->getValue();
103105
} catch (\Throwable) {
104106
unset($this->keys[$key]);
105107
goto get_from_pool;
106108
}
107-
108-
return $value;
109109
}
110110

111111
public function getItem(mixed $key): CacheItem
@@ -125,9 +125,9 @@ public function getItem(mixed $key): CacheItem
125125

126126
if ('N;' === $value) {
127127
$value = null;
128-
} elseif ($value instanceof \Closure) {
128+
} elseif ($value instanceof CachedValueInterface) {
129129
try {
130-
$value = $value();
130+
$value = $value->getValue();
131131
} catch (\Throwable) {
132132
$value = null;
133133
$isHit = false;
@@ -306,8 +306,7 @@ public function warmUp(array $values): array
306306
}
307307

308308
if (!$isStaticValue) {
309-
$value = str_replace("\n", "\n ", $value);
310-
$value = "static function () {\n return {$value};\n}";
309+
$value = 'new class() implements \\'.CachedValueInterface::class." { public function getValue(): mixed { return {$value}; } }";
311310
}
312311
$hash = hash('xxh128', $value);
313312

@@ -368,9 +367,9 @@ private function generateItems(array $keys): \Generator
368367

369368
if ('N;' === $value) {
370369
yield $key => $f($key, null, true);
371-
} elseif ($value instanceof \Closure) {
370+
} elseif ($value instanceof CachedValueInterface) {
372371
try {
373-
yield $key => $f($key, $value(), true);
372+
yield $key => $f($key, $value->getValue(), true);
374373
} catch (\Throwable) {
375374
yield $key => $f($key, null, false);
376375
}

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Symfony\Component\Cache\Exception\CacheException;
1515
use Symfony\Component\Cache\Exception\InvalidArgumentException;
1616
use Symfony\Component\Cache\PruneableInterface;
17+
use Symfony\Component\Cache\Traits\CachedValueInterface;
1718
use Symfony\Component\Cache\Traits\FilesystemCommonTrait;
1819
use Symfony\Component\VarExporter\VarExporter;
1920

@@ -114,8 +115,10 @@ protected function doFetch(array $ids): iterable
114115
$values[$id] = null;
115116
} elseif (!\is_object($value)) {
116117
$values[$id] = $value;
118+
} elseif ($value instanceof CachedValueInterface) {
119+
$values[$id] = $value->getValue();
117120
} elseif (!$value instanceof LazyValue) {
118-
$values[$id] = $value();
121+
$values[$id] = $value;
119122
} elseif (false === $values[$id] = include $value->file) {
120123
unset($values[$id], $this->values[$id]);
121124
$missingIds[] = $id;
@@ -152,7 +155,7 @@ protected function doFetch(array $ids): iterable
152155
if ($now >= $expiresAt) {
153156
unset($this->values[$id], $missingIds[$k], self::$valuesCache[$file]);
154157
}
155-
} catch (\ErrorException $e) {
158+
} catch (\ErrorException) {
156159
unset($missingIds[$k]);
157160
}
158161
}
@@ -236,7 +239,7 @@ protected function doSave(array $values, int $lifetime): array|bool
236239
if ($isStaticValue) {
237240
$value = "return [{$expiry}, {$value}];";
238241
} elseif ($this->appendOnly) {
239-
$value = "return [{$expiry}, static fn () => {$value}];";
242+
$value = "return [{$expiry}, new class() implements \\".CachedValueInterface::class." { public function getValue(): mixed { return {$value}; } }];";
240243
} else {
241244
// We cannot use a closure here because of https://bugs.php.net/76982
242245
$value = str_replace('\Symfony\Component\VarExporter\Internal\\', '', $value);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Cache\Traits;
13+
14+
/**
15+
* @internal
16+
*/
17+
interface CachedValueInterface
18+
{
19+
public function getValue(): mixed;
20+
}

0 commit comments

Comments
 (0)