From 0813e4da2b4d93038c40397c235ca5761e8c7f96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Thu, 14 Mar 2024 14:08:06 +0300 Subject: [PATCH] Custom serializer support --- src/DbCache.php | 13 ++++--- src/PhpSerializer.php | 27 ++++++++++++++ src/SerializerInterface.php | 12 ++++++ tests/PhpSerializerTest.php | 74 +++++++++++++++++++++++++++++++++++++ 4 files changed, 120 insertions(+), 6 deletions(-) create mode 100644 src/PhpSerializer.php create mode 100644 src/SerializerInterface.php create mode 100644 tests/PhpSerializerTest.php diff --git a/src/DbCache.php b/src/DbCache.php index 0170b17..51852cf 100644 --- a/src/DbCache.php +++ b/src/DbCache.php @@ -21,10 +21,8 @@ use function is_string; use function iterator_to_array; use function random_int; -use function serialize; use function strpbrk; use function time; -use function unserialize; /** * DbCache stores cache data in a database table. @@ -37,6 +35,7 @@ final class DbCache implements CacheInterface private string $loggerMessageDelete = 'Unable to delete cache data: '; private string $loggerMessageUpdate = 'Unable to update cache data: '; + private SerializerInterface $serializer; /** * @param ConnectionInterface $db The database connection instance. @@ -48,8 +47,10 @@ final class DbCache implements CacheInterface public function __construct( private ConnectionInterface $db, private string $table = '{{%yii_cache}}', - public int $gcProbability = 100 + public int $gcProbability = 100, + ?SerializerInterface $serializer = null ) { + $this->serializer = $serializer ?? new PhpSerializer(); } /** @@ -75,7 +76,7 @@ public function get(string $key, mixed $default = null): mixed /** @var bool|float|int|string|null $value */ $value = $this->getData($key, ['data'], 'scalar'); - return $value === false ? $default : unserialize((string) $value); + return $value === false ? $default : $this->serializer->unserialize((string) $value); } /** @@ -142,7 +143,7 @@ public function getMultiple(iterable $keys, mixed $default = null): iterable } /** @psalm-var string */ - $values[$value['id']] = unserialize((string) $value['data']); + $values[$value['id']] = $this->serializer->unserialize((string) $value['data']); } /** @psalm-var iterable */ @@ -289,7 +290,7 @@ private function deleteData(array|string|bool $id): bool private function buildDataRow(string $id, ?int $ttl, mixed $value, bool $associative): array { $expire = $this->isInfinityTtl($ttl) ? null : ((int) $ttl + time()); - $data = new Param(serialize($value), PDO::PARAM_LOB); + $data = new Param($this->serializer->serialize($value), PDO::PARAM_LOB); if ($associative) { return ['id' => $id, 'expire' => $expire, 'data' => $data]; diff --git a/src/PhpSerializer.php b/src/PhpSerializer.php new file mode 100644 index 0000000..de69ce1 --- /dev/null +++ b/src/PhpSerializer.php @@ -0,0 +1,27 @@ +foo = 'bar'; + $object->bar = 'foo'; + + return [ + [ + true, + ], + [ + false, + ], + [ + null, + ], + [ + PHP_INT_MAX, + ], + [ + pi(), + ], + [ + 'string', + ], + [ + [ + 'key' => 'value', + 'foo' => 'bar', + 'true' => true, + 'false' => false, + 'array' => (array) $object, + 'int' => 8_000, + ], + ], + [ + $object, + ], + ]; + } + + /** + * @dataProvider serializeDataProvider + * @param mixed $data + * @return void + */ + public function testSerialize(mixed $data): void + { + $serializer = new PhpSerializer(); + $result = $serializer->serialize($data); + + if (is_object($data)) { + self::assertEquals($data, $serializer->unserialize($result)); + } else { + self::assertSame($data, $serializer->unserialize($result)); + } + } +}