Laminas-cache example not working

Hi how to properly use laminas-cache 3.x

I’m using Laminas ServiceManager but not MVC

When doing this

$storageFactory = $container->get(\Laminas\Cache\Service\StorageAdapterFactoryInterface::class);
$storageFactory->create("filesystem");

It complains that filesystem is not found

Unable to resolve service "filesystem" to a factory; are you certain you provided it during configuration?

laminas package installed

laminas/laminas-cache                            3.6.0            Caching implementation with a variety of storage options, as well as codified caching strategies fo...
laminas/laminas-cache-storage-adapter-filesystem 2.3.0            Laminas cache adapter for filesystem
laminas/laminas-config-aggregator                1.11.0           Lightweight library for collecting and merging configuration from different sources
laminas/laminas-escaper                          2.12.0           Securely and safely escape HTML, HTML attributes, JavaScript, CSS, and URLs
laminas/laminas-eventmanager                     3.6.0            Trigger and listen to events within a PHP application
laminas/laminas-filter                           2.23.0           Programmatically filter and normalize data and files
laminas/laminas-form                             3.5.0            Validate and display simple and complex forms, casting forms to business objects and vice versa
laminas/laminas-hydrator                         4.8.0            Serialize objects to arrays, and vice versa
laminas/laminas-i18n                             2.19.0           Provide translations for your application, and filter and validate internationalized values
laminas/laminas-inputfilter                      2.22.0           Normalize and validate input sets from the web, APIs, the CLI, and more, including files
laminas/laminas-json                             3.5.0            provides convenience methods for serializing native PHP to JSON and decoding JSON to native PHP
laminas/laminas-log                              2.15.2           Robust, composite logger with filtering, formatting, and PSR-3 support
laminas/laminas-navigation                       2.16.0           Manage trees of pointers to web pages in order to build navigation systems
laminas/laminas-serializer                       2.14.0           Serialize and deserialize PHP structures to a variety of representations
laminas/laminas-servicemanager                   3.19.0           Factory-Driven Dependency Injection Container
laminas/laminas-stdlib                           3.15.0           SPL extensions, array utilities, error handlers, and more
laminas/laminas-validator                        2.26.0           Validation classes for a wide range of domains, and the ability to chain validators to create compl...
laminas/laminas-view                             2.24.0           Flexible view layer supporting and providing multiple view layers, helpers, and more

Is there another config I need to add to service factory load the filesystem ? Example in Adapters - laminas-cache - Laminas Docs is not working

Do I need to create my own factory for adapter ?

Loaded service

[service] => Array
        (
            [factories] => Array
                (
                    [FormAnnotationBuilder] => Laminas\Form\Annotation\BuilderAbstractFactory
                    [FormAttributeBuilder] => Laminas\Form\Annotation\BuilderAbstractFactory
                    [FormElementManager] => Laminas\Form\FormElementManagerFactory
                    [Laminas\Cache\Storage\AdapterPluginManager] => Laminas\Cache\Service\StorageAdapterPluginManagerFactory
                    [Laminas\Cache\Storage\PluginManager] => Laminas\Cache\Service\StoragePluginManagerFactory
                    [Laminas\Cache\Service\StoragePluginFactory] => Laminas\Cache\Service\StoragePluginFactoryFactory
                    [Laminas\Cache\Service\StoragePluginFactoryInterface] => Laminas\Cache\Service\StoragePluginFactoryFactory
                    [Laminas\Cache\Service\StorageAdapterFactory] => Laminas\Cache\Service\StorageAdapterFactoryFactory
                    [Laminas\Cache\Service\StorageAdapterFactoryInterface] => Laminas\Cache\Service\StorageAdapterFactoryFactory
                    [Laminas\Cache\Command\DeprecatedStorageFactoryConfigurationCheckCommand] => Laminas\Cache\Command\DeprecatedStorageFactoryConfigurationCheckCommandFactory
                )

            [abstract_factories] => Array
                (
                    [0] => Laminas\Cache\Service\StorageCacheAbstractServiceFactory
                )

            [aliases] => Array
                (
                    [Laminas\Form\Annotation\AnnotationBuilder] => FormAnnotationBuilder
                    [Laminas\Form\Annotation\AttributeBuilder] => FormAttributeBuilder
                    [Laminas\Form\FormElementManager] => FormElementManager
                )

        )
)

Hello and welcome to our forums! :smiley:

If you do it manually, then you must add the configuration of the filesystem adapter to your service container:

$container->configure(
    (new Laminas\Cache\Storage\Adapter\Filesystem\ConfigProvider())->getServiceDependencies()
);

This adds the adapter with the related factory and aliases:

(I hope my memory is correct here.)

So It can only be call using configure ?

Adding it manually to factories array not working.

Array
(
    [factories] => Array
        (
            [Laminas\Cache\Storage\Adapter\Filesystem] => Laminas\ServiceManager\Factory\InvokableFactory
            [Laminas\Cache\Storage\AdapterPluginManager] => Laminas\Cache\Service\StorageAdapterPluginManagerFactory
            [Laminas\Cache\Storage\PluginManager] => Laminas\Cache\Service\StoragePluginManagerFactory
            [Laminas\Cache\Service\StoragePluginFactory] => Laminas\Cache\Service\StoragePluginFactoryFactory
            [Laminas\Cache\Service\StoragePluginFactoryInterface] => Laminas\Cache\Service\StoragePluginFactoryFactory
            [Laminas\Cache\Service\StorageAdapterFactory] => Laminas\Cache\Service\StorageAdapterFactoryFactory
            [Laminas\Cache\Service\StorageAdapterFactoryInterface] => Laminas\Cache\Service\StorageAdapterFactoryFactory
            [Laminas\Cache\Command\DeprecatedStorageFactoryConfigurationCheckCommand] => Laminas\Cache\Command\DeprecatedStorageFactoryConfigurationCheckCommandFactory
        )

    [aliases] => Array
        (
            [filesystem] => Laminas\Cache\Storage\Adapter\Filesystem
            [Filesystem] => Laminas\Cache\Storage\Adapter\Filesystem
        )

    [delegators] => Array
        (
            [Laminas\Cache\Storage\AdapterPluginManager] => Array
                (
                    [0] => Laminas\Cache\Storage\Adapter\Filesystem\AdapterPluginManagerDelegatorFactory
                )

        )

    [abstract_factories] => Array
        (
            [0] => Laminas\Cache\Service\StorageCacheAbstractServiceFactory
        )
    )
]

Got this error

Entry "Laminas\Cache\Service\StorageAdapterFactoryInterface" cannot be resolved: the class is not instantiable

Wouldn’t it be better if cache adapter use Module.php and ConfigProvider.php style like the rest of the library ?

No, there are many ways but via the config provider class it is easy, because no manual configuration is needed. Make sure you added laminas-cache and the cache adapter to your service container:

$container = new Laminas\ServiceManager\ServiceManager();

// Add everything from laminas-cache
$container->configure(
    (new Laminas\Cache\ConfigProvider())->getDependencyConfig()
);

// Add everything from the filesystem adapter of laminas-cache
$container->configure(
    (new Laminas\Cache\Storage\Adapter\Filesystem\ConfigProvider())->getServiceDependencies()
);

See also:

That is already being done.

Strange, I added everything manually and compare the service config is the same. But it still got error
Unless I use configure then it won’t work.

Since I’m not using MVC and need to support other DI. My approach is too make sure the service config array is written correctly before init the container. But this doesn’t work for cache , other component still ok.

So this thing is actually happen before servicemanager (container) is created

Array
(
    [factories] => Array
        (
            [Laminas\Cache\Storage\Adapter\Filesystem] => Laminas\ServiceManager\Factory\InvokableFactory
            [Laminas\Cache\Storage\AdapterPluginManager] => Laminas\Cache\Service\StorageAdapterPluginManagerFactory
            [Laminas\Cache\Storage\PluginManager] => Laminas\Cache\Service\StoragePluginManagerFactory
            [Laminas\Cache\Service\StoragePluginFactory] => Laminas\Cache\Service\StoragePluginFactoryFactory
            [Laminas\Cache\Service\StoragePluginFactoryInterface] => Laminas\Cache\Service\StoragePluginFactoryFactory
            [Laminas\Cache\Service\StorageAdapterFactory] => Laminas\Cache\Service\StorageAdapterFactoryFactory
            [Laminas\Cache\Service\StorageAdapterFactoryInterface] => Laminas\Cache\Service\StorageAdapterFactoryFactory
            [Laminas\Cache\Command\DeprecatedStorageFactoryConfigurationCheckCommand] => Laminas\Cache\Command\DeprecatedStorageFactoryConfigurationCheckCommandFactory
        )

    [aliases] => Array
        (
            [filesystem] => Laminas\Cache\Storage\Adapter\Filesystem
            [Filesystem] => Laminas\Cache\Storage\Adapter\Filesystem
        )

    [delegators] => Array
        (
            [Laminas\Cache\Storage\AdapterPluginManager] => Array
                (
                    [0] => Laminas\Cache\Storage\Adapter\Filesystem\AdapterPluginManagerDelegatorFactory
                )

        )

    [abstract_factories] => Array
        (
            [0] => Laminas\Cache\Service\StorageCacheAbstractServiceFactory
        )
    )
]

You don’t need anything from the MVC part of Laminas and my examples don’t include any of that. So please explain in detail or with a code example what you are trying to do.

It looks like your other DI is trying to instantiate the interface:

…which is wrong.


We will find the solution. :smiley:

Let me clarify for this config I’m using Laminas ServiceManager
Just to make sure it compatible with other DI, I put everything in the array first manually
So no auto configuration at all

Then load the array into the service manager like in the document

use Laminas\ServiceManager\ServiceManager;
use Laminas\ServiceManager\Factory\InvokableFactory;

// Make sure everything is define in the array first, including laminas cache, filesystem and delegators
// I write it in My previous reply for the content of the $config
$config = [
  "factories" => [
    ...
  ]
]

// Create the container after
$serviceManager = new ServiceManager($config);

But go this error when creating filesystem

Entry "Laminas\Cache\Service\StorageAdapterFactoryInterface" cannot be resolved: the class is not instantiable

If I load the delegators part using configure

$container->configure(
    (new Laminas\Cache\Storage\Adapter\Filesystem\ConfigProvider())->getServiceDependencies()
);

This works ok. The laminas cache Module can be define directly in $config but not the filesytem delegators

Works as expected:

$config = [
    'factories'  => [
        Laminas\Cache\Storage\AdapterPluginManager::class           => Laminas\Cache\Service\StorageAdapterPluginManagerFactory::class,
        Laminas\Cache\Storage\PluginManager::class                  => Laminas\Cache\Service\StoragePluginManagerFactory::class,
        Laminas\Cache\Service\StoragePluginFactoryInterface::class  => Laminas\Cache\Service\StoragePluginFactoryFactory::class,
        Laminas\Cache\Service\StorageAdapterFactoryInterface::class => Laminas\Cache\Service\StorageAdapterFactoryFactory::class,
    ],
    'delegators' => [
        Laminas\Cache\Storage\AdapterPluginManager::class => [
            Laminas\Cache\Storage\Adapter\Filesystem\AdapterPluginManagerDelegatorFactory::class,
        ],
    ],
];

$container = new Laminas\ServiceManager\ServiceManager($config);

$storageFactory = $container->get(
    Laminas\Cache\Service\StorageAdapterFactoryInterface::class
);
$cache = $storageFactory->create(
    Laminas\Cache\Storage\Adapter\Filesystem::class
);

$cache->setItem('key', 'value');
if ($cache->hasItem('key')) {
    echo $cache->getItem('key'); // "value"
}

Using the constructor or the method configure of Laminas\ServiceManager\ServiceManager is the same:

Hi, its working ok. thanks for the info

The creation context in StorageAdapterFactory somehow load the wrong ServiceManager which hasn’t implement delegators system.