Skip to content
This repository has been archived by the owner on Jan 29, 2020. It is now read-only.

Provide a PSR-16 decorator for zend-cache storage adapters #152

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
9611c45
Provide a PSR-16 decorator for storage adapters
weierophinney Apr 18, 2018
aa52ee7
Udpates link to PSR-6 in documentation
weierophinney Apr 18, 2018
9d3f986
Adds documentation covering PSR-16 support
weierophinney Apr 18, 2018
f0ba8db
Mark package as both a PSR-6 and PSR-16 provider
weierophinney Apr 18, 2018
7c9f644
Do not allow setting keys that are reserved in the PSR-16 specification
weierophinney Apr 18, 2018
5e10ef6
Do not allow keys longer than 64 characters
weierophinney Apr 18, 2018
33b56c6
Extracts PSR-6 serialization support logic to a trait
weierophinney Apr 18, 2018
b10f802
Adds serialization capabilities to PSR-16 decorator
weierophinney Apr 18, 2018
04a3e0c
Fixes exception message when key contains invalid characters
weierophinney Apr 18, 2018
7f47a45
Invalidate values when setting if TTL is non-null and less than 1.
weierophinney Apr 19, 2018
fe48175
Return false from set operations when adapter does not support per-it…
weierophinney Apr 19, 2018
ac4d463
Provide integration tests
weierophinney Apr 19, 2018
0a33249
Adds PSR-16 integration test for Memory adapter
weierophinney Apr 19, 2018
44d5808
Creates PSR-16 integration test for Memcache adapter
weierophinney Apr 19, 2018
26557cd
Adds PSR-16 integration test for Memcached adapter
weierophinney Apr 19, 2018
67c2d4b
Adds PSR-16 integration test for MongoDb adapter
weierophinney Apr 19, 2018
7a2bcee
Adds PSR-6 integration tests for ExtMongoDb adapter
weierophinney Apr 19, 2018
dad5806
Adds PSR-16 integration test for Redis adapter
weierophinney Apr 19, 2018
fd46ff9
Adds PSR-16 integration test for WinCache adapter
weierophinney Apr 19, 2018
ce2c5f1
Adds PSR-16 integration test for ZendServerDisk adapter
weierophinney Apr 19, 2018
faaea7d
Adds PSR-16 integration test for ZendServerShm adapter
weierophinney Apr 19, 2018
5ddc3f5
Adds PSR-16 integration test for XCache adapter
weierophinney Apr 19, 2018
ce5843a
Adds PSR-16 integration test for zend-session adapter
weierophinney Apr 19, 2018
8c39032
Adds PSR-16 integration test for Filesystem adapter
weierophinney Apr 19, 2018
ff1fdb1
Vary PSR-16 adapter behavior based on adapter serialization requirements
weierophinney Apr 19, 2018
4044702
Adds finally block to set, setMultiple to reset options
weierophinney Apr 19, 2018
a56b35f
Adds CHANGELOG entry for #152
weierophinney Apr 19, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 21 additions & 11 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,48 @@ All notable changes to this project will be documented in this file, in reverse

### Added

- [#148](https://github.com/zendframework/zend-cache/pull/148) adds support for PHP 7.1 and 7.2.

- [#152](https://github.com/zendframework/zend-cache/pull/152) adds an adapter providing [PSR-16](https://www.php-fig.org/psr/psr-16/) (Caching Library Interface) support.
The new class, `Zend\Cache\Psr\SimpleCacheDecorator`, accepts a
`Zend\Cache\Storage\StorageInterface` instance to its constructor, and proxies
the various PSR-16 methods to it.

- [#46](https://github.com/zendframework/zend-cache/issues/46) adds support for [PSR-6](https://www.php-fig.org/psr/psr-6/) (Caching Interface).
It provides an implementation of `Psr\Cache\CacheItemPoolInterface` via
`Zend\Cache\Psr\CacheItemPoolAdapter`, which accepts a
`Zend\Cache\Storage\StorageInterface` instance to its constructor, and proxies
the various PSR-6 methods to it. It also provides a
`Psr\Cache\CacheItemInterface` implementation via `Zend\Cache\Psr\CacheItem`,
which provides a value object for both introspecting cache fetch results, as
well as providing values to cache.

- [#154](https://github.com/zendframework/zend-cache/pull/154) adds an ext-mongodb adapter, `Zend\Cache\Storage\Adapter\ExtMongoDb`.
You may use the `StorageFactory` to create an instance using either the fully qualified class
name as the adapter name, or the strings `ext_mongo_db` or `ExtMongoDB` (or most variations
on case of the latter string). The options it accepts are the same as for the existing
`Zend\Cache\Storage\Adapter\MongoDb`, and it provides the same capabilities. The adapter
requires the mongodb/mongodb package to operate.

- [#148](https://github.com/zendframework/zend-cache/pull/148) adds support for PHP 7.1 and 7.2.

- [#120](https://github.com/zendframework/zend-cache/pull/120) adds the ability to configure alternate file suffixes for both
cache and tag cache files within the Filesystem adapter. Use the `suffix` and `tag_suffix`
options to set them; they will default to `dat` and `tag`, respectively.

- [#116](https://github.com/zendframework/zend-cache/pull/116)
docblock method chaining consistency
- [#46](https://github.com/zendframework/zend-cache/issues/46)
Add wrapper for PSR-6
- [#79](https://github.com/zendframework/zend-cache/issues/79)
Add capability for the "lock-on-expire" feature (úsed by Zend Data Cache)

### Changed

- Nothing.
- [#116](https://github.com/zendframework/zend-cache/pull/116) adds docblock method chaining consistency.

### Deprecated

- [#101](https://github.com/zendframework/zend-cache/pull/101)
bump minimum php version to 5.6, as 5.5 goes EOL
- Nothing.

### Removed

- [#101](https://github.com/zendframework/zend-cache/pull/101) removes support for PHP 5.5.

- [#148](https://github.com/zendframework/zend-cache/pull/148) removes support for HHVM.

### Fixed
Expand All @@ -49,8 +60,7 @@ All notable changes to this project will be documented in this file, in reverse

- [#150](https://github.com/zendframework/zend-cache/pull/150) fixes an issue with how CAS tokens are handled when using the memcached adapter.

- [#61](https://github.com/zendframework/zend-cache/pull/61)
Zend Data Cache: minTtl => 1
- [#61](https://github.com/zendframework/zend-cache/pull/61) sets the Zend Data Cache minTtl value to 1.

## 2.7.3 - TBD

Expand Down
5 changes: 5 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"require": {
"php": "^5.6 || ^7.0",
"psr/cache": "^1.0",
"psr/simple-cache": "^1.0",
"zendframework/zend-eventmanager": "^2.6.3 || ^3.2",
"zendframework/zend-servicemanager": "^2.7.8 || ^3.3",
"zendframework/zend-stdlib": "^2.7.7 || ^3.1"
Expand Down Expand Up @@ -66,6 +67,10 @@
"config": {
"sort-packages": true
},
"provide": {
"psr/cache-implementation": "1.0",
"psr/simple-cache-implementation": "1.0"
},
"extra": {
"branch-alias": {
"dev-master": "2.7.x-dev",
Expand Down
50 changes: 49 additions & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

66 changes: 66 additions & 0 deletions docs/book/psr16.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# PSR-16 Support

- Since 2.8.0

[PSR-16](https://www.php-fig.org/psr/psr-16/) provides a simplified approach to
cache access that does not involve cache pools, tags, deferment, etc.; it
can be thought of as a key/value storage approach to caching.

zend-cache provides PSR-16 support via the class
`Zend\Cache\Psr\SimpleCacheDecorator`. This class implements PSR-16's
`Psr\SimpleCache\CacheInterface`, and composes a
`Zend\Cache\Storage\StorageInterface` instance to which it proxies all
operations.

Instantiation is as follows:

```php
use Zend\Cache\StorageFactory;
use Zend\Cache\Psr\SimpleCacheDecorator;

$storage = StorageFactory::factory([
'adapter' => [
'name' => 'apc',
'options' => [],
],
]);

$cache = new SimpleCacheDecorator($storage);
```

Once you have a `SimpleCacheDecorator` instance, you can perform operations per
that specification:

```php
// Use has() to determine whether to fetch the value or calculate it:
$value = $cache->has('someKey') ? $cache->get('someKey') : calculateValue();
if (! $cache->has('someKey')) {
$cache->set('someKey', $value);
}

// Or use a default value:
$value = $cache->get('someKey', $defaultValue);
```

When setting values, whether single values or multiple, you can also optionally
provide a Time To Live (TTL) value. This proxies to the underlying storage
instance's options, temporarily resetting its TTL value for the duration of the
operation. TTL values may be expressed as integers (in which case they represent
seconds) or `DateInterval` instances. As examples:

```php
$cache->set('someKey', $value, 30); // set TTL to 30s
$cache->set('someKey', $value, new DateInterval('P1D'); // set TTL to 1 day

$cache->setMultiple([
'key1' => $value1,
'key2' => $value2,
], 3600); // set TTL to 1 hour
$cache->setMultiple([
'key1' => $value1,
'key2' => $value2,
], new DateInterval('P6H'); // set TTL to 6 hours
```

For more details on what methods are exposed, consult the [CacheInterface
specification](https://www.php-fig.org/psr/psr-16/#21-cacheinterface).
2 changes: 1 addition & 1 deletion docs/book/psr6.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Overview

The `Zend\Cache\Psr\CacheItemPoolAdapter` provides a [PSR-6](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-6-cache.md)
The `Zend\Cache\Psr\CacheItemPoolAdapter` provides a [PSR-6](https://www.php-fig.org/psr/psr-6/)
compliant wrapper for supported storage adapters.

PSR-6 specifies a common interface to cache storage, enabling developers to switch between implementations without
Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pages:
- OutputCache: pattern/output-cache.md
- CaptureCache: pattern/capture-cache.md
- PSR-6: psr6.md
- PSR-16: psr16.md
site_name: zend-cache
site_description: Zend\Cache
repo_url: 'https://github.com/zendframework/zend-cache'
Expand Down
40 changes: 3 additions & 37 deletions src/Psr/CacheItemPoolAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
*/
class CacheItemPoolAdapter implements CacheItemPoolInterface
{
use SerializationTrait;

/**
* @var StorageInterface
*/
Expand All @@ -33,16 +35,6 @@ class CacheItemPoolAdapter implements CacheItemPoolInterface
*/
private $deferred = [];

/**
* @var bool
*/
private $serializeValues = false;

/**
* @var string
*/
private static $serializedFalse;

/**
* Constructor.
*
Expand All @@ -57,12 +49,7 @@ class CacheItemPoolAdapter implements CacheItemPoolInterface
public function __construct(StorageInterface $storage)
{
$this->validateStorage($storage);

$this->serializeValues = $this->shouldSerialize($storage);
if ($this->serializeValues) {
static::$serializedFalse = serialize(false);
}

$this->memoizeSerializationCapabilities($storage);
$this->storage = $storage;
}

Expand Down Expand Up @@ -350,27 +337,6 @@ private function validateStorage(StorageInterface $storage)
}
}

/**
* Returns true if capabilities indicate values should be serialized before saving to preserve data types
* @param StorageInterface $storage
* @return bool
*/
private function shouldSerialize(StorageInterface $storage)
{
$capabilities = $storage->getCapabilities();
$requiredTypes = ['string', 'integer', 'double', 'boolean', 'NULL', 'array', 'object'];
$types = $capabilities->getSupportedDatatypes();
foreach ($requiredTypes as $type) {
// 'object' => 'object' is OK
// 'integer' => 'string' is not (redis)
// 'integer' => 'integer' is not (memcache)
if (! (isset($types[$type]) && in_array($types[$type], [true, 'array', 'object'], true))) {
return true;
}
}
return false;
}

/**
* Unserializes value, marking isHit false if it fails
* @param $value
Expand Down
69 changes: 69 additions & 0 deletions src/Psr/SerializationTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php
/**
* @see https://github.com/zendframework/zend-cache for the canonical source repository
* @copyright Copyright (c) 2018 Zend Technologies USA Inc. (https://www.zend.com)
* @license https://github.com/zendframework/zend-cache/blob/master/LICENSE.md New BSD License
*/

namespace Zend\Cache\Psr;

use Zend\Cache\Storage\StorageInterface;

/**
* Provides common functionality surrounding value de/serialization as required
* by both PSR-6 and PSR-16
*/
trait SerializationTrait
{
/**
* @var bool
*/
private $serializeValues = false;

/**
* @var string
*/
private static $serializedFalse;

/**
* Determine if the given storage adapter requires serialization.
*
* Determines if the given storage adapter requires serialization. If so,
* set $serializeValues to true, and serialize a boolean false for later
* comparisons.
*
* @param StorageInterface $storage
* @return void
*/
private function memoizeSerializationCapabilities(StorageInterface $storage)
{
$capabilities = $storage->getCapabilities();
$requiredTypes = ['string', 'integer', 'double', 'boolean', 'NULL', 'array', 'object'];
$types = $capabilities->getSupportedDatatypes();
$shouldSerialize = false;

foreach ($requiredTypes as $type) {
// 'object' => 'object' is OK
// 'integer' => 'string' is not (redis)
// 'integer' => 'integer' is not (memcache)
if (! (isset($types[$type]) && in_array($types[$type], [true, 'array', 'object'], true))) {
$shouldSerialize = true;
break;
}
}

if ($shouldSerialize) {
static::$serializedFalse = serialize(false);
}

$this->serializeValues = $shouldSerialize;
}

/**
* Unserialize a value retrieved from the cache.
*
* @param string $value
* @return mixed
*/
abstract public function unserialize($value);
}
Loading