Migration Guide

Migration to Version 3.0

Upgrading to laminas-cache will require a few code-changes, depending on how the storage adapters were used. Please note that the migration guide assumes that laminas-cache is installed via Composer.

Please check out the checklist to see what changes need to be done.

The biggest change with laminas-cache v3.0 is that this component will be shipped without a specific cache adapter. The idea behind this is, that projects can freely choose those cache adapters they really use.

In the past, most of the adapters Laminas does officially support were not properly tested, blocked PHP version upgrades (due to extensions lacking compatibility) and had to be maintained due to backwards compatibility. Starting with v3.0, all adapters can be maintained and evolve independently.

Checklist

  1. laminas-cache is updated to the latest version from within 2.x (currently 2.13.2)
  2. laminas-cli is installed to verify the configuration integrity (vendor/bin/laminas laminas-cache:deprecation:check-storage-factory-config); in case you don't want to use laminas-cli, please check out the normalized array configuration example in the release notes of 2.12.0
  3. laminas-cache is required with ^3.0 within composer.json
  4. Cache adapters which are used within the project needs to be required in at least ^2.0; in case you don't know which adapters are in use, either check your project configuration or search for the Laminas\Cache\Storage\Adapter namespace in your projects source code. Every adapter has to be listed in either your module.config.php (laminas-mvc) or config.php (mezzio) configuration.
  5. Project does not use any of the removed classes and traits
  6. Storage adapters are not extended in any way as all adapters are final starting with v2.0 of the individual adapter component
  7. PSR-6 CacheItemPoolDecorator does now validate the maximum key length the same way as PSR-6 SimpleCacheDecorator and therefore fulfills the requirements by the underlying PSR.

New Features

  • Each cache adapter has its own package.
  • Support for PHP 8.1
  • PSR-6 CacheItemPoolDecorator validates the maximum key length.

Removed Classes and Traits

With laminas-cache v3, some classes/traits were removed as well:

  • Due to the switch to satellite packages, the StorageFactory was replaced with the StorageAdapterFactoryInterface. Due to the same reason, the PatternFactory was removed. Cache patterns mostly need an underlying adapter which have to be created with the new StorageAdapterFactoryInterface
  • ClassCache cache pattern was removed. For more details, please read the related issue.
  • PatternCacheFactory and StoragePatternCacheFactory which were introduced in v2.12.0 to provide forward compatibility.
  • PatternPluginManager and PatternPluginManagerFactory which were removed due to the fact that most cache patterns require underlying cache adapter and thus are not instantiable from their name and options.
  • PluginManagerLookupTrait which was used to provide forward compatibility for the StorageAdapterFactoryInterface.
  • PatternOptions are not capable of the storage option anymore

Breaking Changes

  • CallbackCache, OutputCache and ObjectCache now require the underlying cache adapter (StorageInterface) as 1st __construct dependency. The options can be passed via 2nd __construct)[https://github.com/CallbackCache, OutputCache and ObjectCache now require the underlying cache adapter (StorageInterface arguments but are optional.
    Please note that it is not possible to inject the pattern configuration as an array anymore
  • Storage configurations must be in a specific shape. For more details, head to the release notes of 2.12.0
  • All cache adapters are now marked as final and are not extensible anymore. In case that you are extending one of the cache adapters, please change your code as composition should be preferred over inheritance. For an example, please check out the composition over inheritance section.
  • Due to the enhancement of CacheItemPoolDecorator, the maximum key length for the underlying cache adapter is validated before it is passed to the adapter.
  • The SerializationTrait which was meant to be used by both PSR-6 and PSR-16 decorators is now marked as internal.
  • The PCRE_MAXIMUM_QUANTIFIER_LENGTH constant of the SimpleCacheDecorator (which was marked as internal) has now been moved to the new (also internal) MaximumKeyLengthTrait and thus had to become a public static property (as traits do not support constants).

Satellite Packages

Starting with laminas-cache v3, we are introducing satellite packages for each cache backend.

In order to make this package work, you have to specify at least one satellite package.

A list of available cache adapters can be found here (starting with their v2 release):

Composition Over Inheritance

In case you are extending one of the cache implementations, your code might look as follows:

use Laminas\Cache\Storage\Adapter\Filesystem;

class MyFileystemStorage extends Filesystem
{
    protected function internalSetItem(&$normalizedKey,&$value)
    {
        $value = doSomethingWithValue($value);
        $normalizedKey = doSOmethingWithKey($normalizedKey);
        return parent::internalSetItem($normalizedKey,$value);
    }
} 

If this looks familiar, using composition would look like this:

use Laminas\Cache\Exception;
use Laminas\Cache\Storage\Adapter\AbstractAdapter;
use Laminas\Cache\Storage\Adapter\Filesystem;
use Laminas\Cache\Storage\Adapter\FilesystemOptions;

final class MyFilesytemStorage extends AbstractAdapter
{
    /**
    * @var \Laminas\Cache\Storage\Adapter\Filesystem
    */
    private $filesystem;

    public function __construct(Filesystem $filesystem) 
    {
        $this->filesystem = $filesystem;
        parent::__construct();
    }

    protected function internalGetItem(&$normalizedKey,&$success = null,&$casToken = null)
    {
        return $this->filesystem->getItem(
            $normalizedKey, 
            $success,
            $casToken
        );
    }

    protected function internalSetItem(&$normalizedKey,&$value)
    {
        $value = doSomethingWithValue($value);
        $normalizedKey = doSomethingWithValue($normalizedKey);
        return $this->filesystem->setItem(
            $normalizedKey, 
            $value
        );
    }

    protected function internalRemoveItem(&$normalizedKey)
    {
        return $this->filesystem->removeItem(
            $normalizedKey
        );
    }   
}

Even tho, that this is more code to add/change than the previous solution, this gives the maintainers of the cache adapters more freedom to provide more stable adapter implementations.

If this does not fit your requirements, please let us know via the laminas-cache repository on GitHub and tell us more about your implementations. Maybe your addition should be part of our official adapter or could be provided as a dedicated Plugin instead.

StorageFactory Dependency

In case your code heavily depends on StorageFactory (or if you are using not yet compatible laminas components (e.g. laminas-i18n, ...), Laminas got your back. With laminas/laminas-cache-storage-deprecated-factory, the StorageFactory is retained to create a temporary backwards compatibility layer.