N°9319 increase php min. version to 8.2 (#887)

* Update minimum PHP version to 8.2
* Fix previous wrong resolution of merge conflict
This commit is contained in:
jf-cbd
2026-04-20 14:47:44 +02:00
committed by GitHub
parent f439490bfc
commit 805087a01b
171 changed files with 5629 additions and 1446 deletions

View File

@@ -192,8 +192,7 @@ abstract class AbstractTagAwareAdapter implements TagAwareAdapterInterface, TagA
if (\is_array($e) || 1 === \count($values)) {
foreach (\is_array($e) ? $e : array_keys($values) as $id) {
$ok = false;
$v = $values[$id];
$type = get_debug_type($v);
$type = \array_key_exists($id, $values) ? get_debug_type($values[$id]) : 'unknown';
$message = \sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.');
CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e instanceof \Exception ? $e : null, 'cache-adapter' => get_debug_type($this)]);
}

View File

@@ -34,6 +34,7 @@ class ArrayAdapter implements AdapterInterface, CacheInterface, LoggerAwareInter
private array $values = [];
private array $tags = [];
private array $expiries = [];
private array $explicitExpiries = [];
private int $defaultLifetime;
private float $maxLifetime;
private int $maxItems;
@@ -58,7 +59,7 @@ class ArrayAdapter implements AdapterInterface, CacheInterface, LoggerAwareInter
$this->maxLifetime = $maxLifetime;
$this->maxItems = $maxItems;
self::$createCacheItem ??= \Closure::bind(
static function ($key, $value, $isHit, $tags) {
static function ($key, $value, $isHit, $tags, $expiry = null) {
$item = new CacheItem();
$item->key = $key;
$item->value = $value;
@@ -66,6 +67,9 @@ class ArrayAdapter implements AdapterInterface, CacheInterface, LoggerAwareInter
if (null !== $tags) {
$item->metadata[CacheItem::METADATA_TAGS] = $tags;
}
if (null !== $expiry) {
$item->metadata[CacheItem::METADATA_EXPIRY] = $expiry;
}
return $item;
},
@@ -126,7 +130,7 @@ class ArrayAdapter implements AdapterInterface, CacheInterface, LoggerAwareInter
$value = $this->storeSerialized ? $this->unfreeze($key, $isHit) : $this->values[$key];
}
return (self::$createCacheItem)($key, $value, $isHit, $this->tags[$key] ?? null);
return (self::$createCacheItem)($key, $value, $isHit, $this->tags[$key] ?? null, $this->explicitExpiries[$key] ?? null);
}
public function getItems(array $keys = []): iterable
@@ -139,7 +143,7 @@ class ArrayAdapter implements AdapterInterface, CacheInterface, LoggerAwareInter
public function deleteItem(mixed $key): bool
{
\assert('' !== CacheItem::validateKey($key));
unset($this->values[$key], $this->tags[$key], $this->expiries[$key]);
unset($this->values[$key], $this->tags[$key], $this->expiries[$key], $this->explicitExpiries[$key]);
return true;
}
@@ -193,13 +197,19 @@ class ArrayAdapter implements AdapterInterface, CacheInterface, LoggerAwareInter
break;
}
unset($this->values[$k], $this->tags[$k], $this->expiries[$k]);
unset($this->values[$k], $this->tags[$k], $this->expiries[$k], $this->explicitExpiries[$k]);
}
}
$this->values[$key] = $value;
$this->expiries[$key] = $expiry ?? \PHP_INT_MAX;
if (null !== $item["\0*\0expiry"] && \PHP_INT_MAX !== $this->expiries[$key]) {
$this->explicitExpiries[$key] = $this->expiries[$key];
} else {
unset($this->explicitExpiries[$key]);
}
if (null === $this->tags[$key] = $item["\0*\0newMetadata"][CacheItem::METADATA_TAGS] ?? null) {
unset($this->tags[$key]);
}
@@ -224,7 +234,7 @@ class ArrayAdapter implements AdapterInterface, CacheInterface, LoggerAwareInter
foreach ($this->values as $key => $value) {
if (!isset($this->expiries[$key]) || $this->expiries[$key] <= $now || str_starts_with($key, $prefix)) {
unset($this->values[$key], $this->tags[$key], $this->expiries[$key]);
unset($this->values[$key], $this->tags[$key], $this->expiries[$key], $this->explicitExpiries[$key]);
}
}
@@ -233,7 +243,7 @@ class ArrayAdapter implements AdapterInterface, CacheInterface, LoggerAwareInter
}
}
$this->values = $this->tags = $this->expiries = [];
$this->values = $this->tags = $this->expiries = $this->explicitExpiries = [];
return true;
}
@@ -290,7 +300,7 @@ class ArrayAdapter implements AdapterInterface, CacheInterface, LoggerAwareInter
}
unset($keys[$i]);
yield $key => $f($key, $value, $isHit, $this->tags[$key] ?? null);
yield $key => $f($key, $value, $isHit, $this->tags[$key] ?? null, $this->explicitExpiries[$key] ?? null);
}
foreach ($keys as $key) {

View File

@@ -79,6 +79,7 @@ class ChainAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
$item->expiresAt(\DateTimeImmutable::createFromFormat('U.u', \sprintf('%.6F', $item->metadata[CacheItem::METADATA_EXPIRY])));
} elseif (0 < $defaultLifetime) {
$item->expiresAfter($defaultLifetime);
$item->newMetadata[CacheItem::METADATA_EXPIRY] = $item->expiry;
}
return $item;

View File

@@ -170,6 +170,10 @@ final class CacheItem implements ItemInterface
}
$valueWrapper = self::VALUE_WRAPPER;
if ($this->value instanceof $valueWrapper) {
return new $valueWrapper($this->value->value, $m + ['expiry' => $this->expiry] + $this->value->metadata);
}
return new $valueWrapper($this->value, $m + ['expiry' => $this->expiry]);
}

View File

@@ -65,12 +65,14 @@ final class LockRegistry
/**
* Defines a set of existing files that will be used as keys to acquire locks.
*
* @return array The previously defined set of files
* @param list<string> $files A list of existing files
*
* @return list<string> The previously defined set of files
*/
public static function setFiles(array $files): array
{
$previousFiles = self::$files;
self::$files = $files;
self::$files = array_values($files);
foreach (self::$openedFiles as $file) {
if ($file) {
@@ -97,7 +99,7 @@ final class LockRegistry
}
self::$signalingException ??= unserialize("O:9:\"Exception\":1:{s:16:\"\0Exception\0trace\";a:0:{}}");
self::$signalingCallback ??= fn () => throw self::$signalingException;
self::$signalingCallback ??= static fn () => throw self::$signalingException;
while (true) {
try {
@@ -123,14 +125,33 @@ final class LockRegistry
}
// if we failed the race, retry locking in blocking mode to wait for the winner
$logger?->info('Item "{key}" is locked, waiting for it to be released', ['key' => $item->getKey()]);
flock($lock, \LOCK_SH);
$deadline = microtime(true) + 30.0;
$acquired = false;
do {
if ($acquired = flock($lock, \LOCK_SH | \LOCK_NB)) {
break;
}
usleep(100_000);
} while (microtime(true) < $deadline);
if (!$acquired) {
$logger?->warning('Lock on item "{key}" timed out, evicting slot', ['key' => $item->getKey()]);
unset(self::$files[$key]);
self::setFiles(self::$files);
$lock = null;
return self::compute($callback, $item, $save, $pool, $setMetadata, $logger, $beta);
}
if (\INF === $beta) {
$logger?->info('Force-recomputing item "{key}"', ['key' => $item->getKey()]);
continue;
}
} finally {
flock($lock, \LOCK_UN);
if ($lock) {
flock($lock, \LOCK_UN);
}
unset(self::$lockedFiles[$key]);
}

View File

@@ -18,6 +18,7 @@ use Psr\SimpleCache\CacheInterface;
use Symfony\Component\Cache\Adapter\AdapterInterface;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\Traits\ProxyTrait;
use Symfony\Contracts\Cache\ItemInterface;
/**
* Turns a PSR-6 cache into a PSR-16 one.
@@ -68,6 +69,12 @@ class Psr16Cache implements CacheInterface, PruneableInterface, ResettableInterf
};
self::$packCacheItem ??= \Closure::bind(
static function (CacheItem $item) {
// Only re-pack if there's timing metadata (for Psr16Adapter compatibility)
// Don't re-pack if only tags metadata exists (TagAwareAdapter direct use case)
if (!isset($item->metadata[ItemInterface::METADATA_CTIME]) && !isset($item->metadata[ItemInterface::METADATA_EXPIRY])) {
return $item->value;
}
$item->newMetadata = $item->metadata;
return $item->pack();

View File

@@ -0,0 +1,37 @@
<?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\Traits\Relay;
if (version_compare(phpversion('relay'), '0.21.0', '>=')) {
/**
* @internal
*/
trait Relay21Trait
{
public function gcra($key, $maxBurst, $requestsPerPeriod, $period, $numRequests = 0): \Relay\Relay|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->gcra(...\func_get_args());
}
public function hotkeys($subcmd, $args = null): \Relay\Relay|array|bool
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hotkeys(...\func_get_args());
}
}
} else {
/**
* @internal
*/
trait Relay21Trait
{
}
}

View File

@@ -26,6 +26,7 @@ use Symfony\Component\Cache\Traits\Relay\Relay11Trait;
use Symfony\Component\Cache\Traits\Relay\Relay121Trait;
use Symfony\Component\Cache\Traits\Relay\Relay12Trait;
use Symfony\Component\Cache\Traits\Relay\Relay20Trait;
use Symfony\Component\Cache\Traits\Relay\Relay21Trait;
use Symfony\Component\Cache\Traits\Relay\SwapdbTrait;
use Symfony\Component\VarExporter\LazyObjectInterface;
use Symfony\Component\VarExporter\LazyProxyTrait;
@@ -60,6 +61,7 @@ class RelayProxy extends \Relay\Relay implements ResetInterface, LazyObjectInter
use Relay12Trait;
use Relay121Trait;
use Relay20Trait;
use Relay21Trait;
use SwapdbTrait;
private const LAZY_OBJECT_PROPERTY_SCOPES = [];