8000 cache-serializer · symfony/symfony@9a2b820 · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 9a2b820

Browse files
author
Aleksey Prilipko
committed
cache-serializer
1 parent 2ae7ad9 commit 9a2b820

26 files changed

+583
-196
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Psr\Log\NullLogger;
1818
use Symfony\Component\Cache\CacheItem;
1919
use Symfony\Component\Cache\Exception\InvalidArgumentException;
20+
use Symfony\Component\Cache\Serializer\PhpSerializer;
2021
use Symfony\Component\Cache\ResettableInterface;
2122
use Symfony\Component\Cache\Traits\AbstractTrait;
2223

@@ -35,6 +36,7 @@ abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface
3536

3637
protected function __construct(string $namespace = '', int $defaultLifetime = 0)
3738
{
39+
$this->setSerializer(new PhpSerializer());
3840
$this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).':';
3941
if (null !== $this->maxIdLength && strlen($namespace) > $this->maxIdLength - 24) {
4042
throw new InvalidArgumentException(sprintf('Namespace must be %d chars max, %d given ("%s")', $this->maxIdLength - 24, strlen($namespace), $namespace));

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

Lines changed: 12 additions & 17 deleti 8000 ons
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
use Psr\Cache\CacheItemInterface;
1515
use Psr\Log\LoggerAwareInterface;
1616
use Symfony\Component\Cache\CacheItem;
17+
use Symfony\Component\Cache\Serializer\NullSerializer;
18+
use Symfony\Component\Cache\Serializer\PhpSerializer;
1719
use Symfony\Component\Cache\ResettableInterface;
1820
use Symfony\Component\Cache\Traits\ArrayTrait;
1921

@@ -32,7 +34,7 @@ class ArrayAdapter implements AdapterInterface, LoggerAwareInterface, Resettable
3234
*/
3335
public function __construct(int $defaultLifetime = 0, bool $storeSerialized = true)
3436
{
35-
$this->storeSerialized = $storeSerialized;
37+
$this->setSerializer($storeSerialized ? new PhpSerializer() : new NullSerializer());
3638
$this->createCacheItem = \Closure::bind(
3739
function ($key, $value, $isHit) use ($defaultLifetime) {
3840
$item = new CacheItem();
@@ -57,13 +59,8 @@ public function getItem($key)
5759
try {
5860
if (!$isHit) {
5961
$this->values[$key] = $value = null;
60-
} elseif (!$this->storeSerialized) {
61-
$value = $this->values[$key];
62-
} elseif ('b:0;' === $value = $this->values[$key]) {
63-
$value = false;
64-
} elseif (false === $value = unserialize($value)) {
65-
$this->values[$key] = $value = null;
66-
$isHit = false;
62+
} else {
63+
$value = $this->unserialize($this->values[$key]);
6764
}
6865
} catch (\Exception $e) {
6966
CacheItem::log($this->logger, 'Failed to unserialize key "{key}"', array('key' => $key, 'exception' => $e));
@@ -117,15 +114,13 @@ public function save(CacheItemInterface $item)
117114

118115
return true;
119116
}
120-
if ($this->storeSerialized) {
121-
try {
122-
$value = serialize($value);
123-
} catch (\Exception< 8000 /span> $e) {
124-
$type = is_object($value) ? get_class($value) : gettype($value);
125-
CacheItem::log($this->logger, 'Failed to save key "{key}" ({type})', array('key' => $key, 'type' => $type, 'exception' => $e));
126-
127-
return false;
128-
}
117+
try {
118+
$value = $this->serialize($value);
119+
} catch (\Exception $e) {
120+
$type = is_object($value) ? get_class($value) : gettype($value);
121+
CacheItem::log($this->logger, 'Failed to save key "{key}" ({type})', array('key' => $key, 'type' => $type, 'exception' => $e));
122+
123+
return false;
129124
}
130125
if (null === $expiry && 0 < $item["\0*\0defaultLifetime"]) {
131126
$expiry = time() + $item["\0*\0defaultLifetime"];

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

Lines changed: 18 additions & 29 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\Serializer\PhpSerializer;
2021
use Symfony\Component\Cache\Traits\PhpArrayTrait;
2122

2223
/**
@@ -53,6 +54,7 @@ function ($key, $value, $isHit) {
5354
null,
5455
CacheItem::class
5556
);
57+
$this->setSerializer(new PhpSerializer());
5658
}
5759

5860
/**
@@ -92,24 +94,18 @@ public function getItem($key)
9294
return $this->pool->getItem($key);
9395
}
9496

95-
$value = $this->values[$key];
96-
$isHit = true;
97-
98-
if ('N;' === $value) {
97+
try {
98+
$e = null;
99+
$value = $this->unwrapValue($this->values[$key]);
100+
$isHit = true;
101+
} catch (\Error $e) {
102+
} catch (\Exception $e) {
103+
}
104+
if (null !== $e) {
99105
$value = null;
100-
} elseif (\is_string($value) && isset($value[2]) && ':' === $value[1]) {
101-
try {
102-
$e = null;
103-
$value = unserialize($value);
104-
} catch (\Error $e) {
105-
} catch (\Exception $e) {
106-
}
107-
if (null !== $e) {
108-
$value = null;
109-
$isHit = false;
110-
}
106+
$isHit = false;
107+
unset($this->values[$key]);
111108
}
112-
113109
$f = $this->createCacheItem;
114110

115111
return $f($key, $value, $isHit);
@@ -231,20 +227,13 @@ private function generateItems(array $keys): \Generator
231227

232228
foreach ($keys as $key) {
233229
if (isset($this->values[$key])) {
234-
$value = $this->values[$key];
235-
236-
if ('N;' === $value) {
237-
yield $key => $f($key, null, true);
238-
} elseif (\is_string($value) && isset($value[2]) && ':' === $value[1]) {
239-
try {
240-
yield $key => $f($key, unserialize($value), true);
241-
} catch (\Error $e) {
242-
yield $key => $f($key, null, false);
243-
} catch (\Exception $e) {
244-
yield $key => $f($key, null, false);
245-
}
246-
} else {
230+
try {
231+
$value = $this->unwrapValue($this->values[$key]);
247232
yield $key => $f($key, $value, true);
233+
} catch (\Error $e) {
234+
yield $key => $f($key, null, false);
235+
} catch (\Exception $e) {
236+
yield $key => $f($key, null, false);
248237
}
249238
} else {
250239
$fallbackKeys[] = $key;
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and l 12A6 icense information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Cache\Serializer;
13+
14+
use Symfony\Component\Cache\Exception\CacheException;
15+
use Symfony\Component\Cache\SerializerInterface;
16+
17+
class IgbinarySerializer implements SerializerInterface
18+
{
19+
public function serialize($data)
20+
{
21+
return igbinary_serialize($data);
22+
}
23+
24+
public function unserialize($serialized)
25+
{
26+
$unserializeCallbackHandler = ini_set('unserialize_callback_func', __CLASS__.'::handleUnserializeCallback');
27+
try {
28+
$value = igbinary_unserialize($serialized);
29+
if (false === $value && igbinary_serialize(false) !== $serialized) {
30+
throw new CacheException('failed to unserialize value');
31+
}
32+
33+
return $value;
34+
} catch (\Error $e) {
35+
throw new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine());
36+
} finally {
37+
ini_set('unserialize_callback_func', $unserializeCallbackHandler);
38+
}
39+
}
40+
41+
/**
42+
* @internal
43+
*/
44+
public static function handleUnserializeCallback($class)
45+
{
46+
throw new \DomainException('Class not found: '.$class);
47+
}
48+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+ 12A6
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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\Serializer;
13+
14+
use Symfony\Component\Cache\SerializerInterface;
15+
16+
class NullSerializer implements SerializerInterface
17+
{
18+
public function serialize($data)
19+
{
20+
return $data;
21+
}
22+
23+
public function unserialize($serialized)
24+
{
25+
return $serialized;
26+
}
27+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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\Serializer;
13+
14+
use Symfony\Component\Cache\Exception\InvalidArgumentException;
15+
use Symfony\Component\Cache\SerializerInterface;
16+
17+
/**
18+
* Serializes values in php code.
19+
*/
20+
class PhpExportSerializer implements SerializerInterface
21+
{
22+
private static function isExportable($data)
23+
{
24+
if (is_object($data)) {
25+
return method_exists(get_class($data), '__set_state');
26+
}
27+
28+
if (is_array($data)) {
29+
$exportable = true;
30+
foreach ($data as $key => $value) {
31+
$exportable = $exportable && self::isExportable($key) && self::isExportable($value);
32+
}
33+
34+
return $exportable;
35+
}
36+
37+
return true;
38+
}
39+
40 8DF2 +
public function serialize($data)
41+
{
42+
if (!self::isExportable($data)) {
43+
throw new InvalidArgumentException('classes without __set_state method are not exportable');
44+
}
45+
46+
return var_export($data, true);
47+
}
48+
49+
public function unserialize($serialized)
50+
{
51+
return eval("return $serialized;");
52+
}
53+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
7DCE 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\Serializer;
13+
14+
use Symfony\Component\Cache\Exception\CacheException;
15+
use Symfony\Component\Cache\SerializerInterface;
16+
17+
class PhpSerializer implements SerializerInterface
18+
{
19+
public function serialize($data)
20+
{
21+
return serialize($data);
22+
}
23+
24+
public function unserialize($serialized)
25+
{
26+
$unserializeCallbackHandler = ini_set('unserialize_callback_func', __CLASS__.'::handleUnserializeCallback');
27+
try {
28+
$value = unserialize($serialized);
29+
if (false === $value && serialize(false) !== $serialized) {
30+
throw new CacheException('failed to unserialize value');
31+
}
32+
33+
return $value;
34+
} catch (\Error $e) {
35+
throw new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine());
36+
} finally {
37+
ini_set('unserialize_callback_func', $unserializeCallbackHandler);
38+
}
39+
}
40+
41+
/**
42+
* @internal
43+
*/
44+
public static function handleUnserializeCallback($class)
45+
{
46+
throw new \DomainException('Class not found: '.$class);
47+
}
48+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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;
13+
14+
use Symfony\Component\Cache\Exception\InvalidArgumentException;
15+
16+
/**
17+
* @author Alexei Prilipko <palex.fpt@gmail.com>
18+
*/
19+
interface SerializerInterface
20+
{
21+
/**
22+
* Generates a storable representation of a value.
23+
*
24+
* @param $data mixed
25+
*
26+
* @return string|mixed serialized value
27+
*
28+
* @throws InvalidArgumentException when $data can not be serialized
29+
*/
30+
public function serialize($data);
31+
32+
/**
33+
* Creates a PHP value from a stored representation.
34+
*
35+
* @param string|mixed $serialized the serialized string
36+
*
37+
* @return mixed Original value
38+
*/
39+
public function unserialize($serialized);
40+
}

src/Symfony/Component/Cache/Simple/AbstractCache.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Psr\SimpleCache\CacheInterface;
1616
use Symfony\Component\Cache\CacheItem;
1717
use Symfony\Component\Cache\Exception\InvalidArgumentException;
18+
use Symfony\Component\Cache\Serializer\PhpSerializer;
1819
use Symfony\Component\Cache\Traits\AbstractTrait;
1920
use Symfony\Component\Cache\ResettableInterface;
2021

@@ -33,6 +34,7 @@ abstract class AbstractCache implements CacheInterface, LoggerAwareInterface, Re
3334

3435
protected function __construct(string $namespace = '', int $defaultLifetime = 0)
3536
{
37+
$this->setSerializer(new PhpSerializer());
3638
$this->defaultLifetime = max(0, $defaultLifetime);
3739
$this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).':';
3840
if (null !== $this->maxIdLength && strlen($namespace) > $this->maxIdLength - 24) {

0 commit comments

Comments
 (0)
0