I worked out a filesystem cache adapter as
then I changed it into a redis one like
These part is too complicate Adapters - laminas-cache - Laminas Docs
Generally, I would like to store a redis connection instance inside the container before. This way will keep just one instance in the whole lifecycle. But was told that not to change container and keep it stateless.
What should I do with a normal redis operation, not for a cache purpose?
Your entire BaseFuncModel
class is only a workaround. It looks like a class that creates different objects of your application, so it combines different factories in one class.
I think the following could work: create a separate factory for the cache and then you can create a factory for Redis itself that fetches Redis from the cache.
But I don’t know why you want to access Redis directly because you make the whole principle of the laminas-cache component and the interchangeable adapters useless!
Becuase I want to use Redis not as a cache purpose, in my opinion, lpush/rpop, such kind of list operation doesn’t sound like cache.
Okay, I will try. Should I register a service-kind class? with a factory to do the DI job?
And then register it via the moduel.config.php’s service_manager key?
Or register it in Module.php’s getServiceConfig() method?
Is there any difference between moduel.config.php’s service_manager key and Module.php’s getServiceConfig() method?
Example
module/Application/config/module.config.php
:
return [
'service_manager' => [
'factories' => [
Redis::class => Application\MyRedisFactory::class,
],
],
// …
];
Use only one option and I recommend the configuration file.
Ok, thank you! Your suggestion is obviously the best solution!
I tried to follow your recommendation,
I typed Redis in the phpstorm IDE, it suggested as follow:
If I choose the first one, then it import
use Laminas\Cache\Storage\Adapter\Redis;
If I choose the second one, then
\Redis::class
Which one should I choose? If I choose the first one, will it affect my function redisCacheApdater()
Besides, what should I do when I need to inject the Redis::class into my controller’s __construct method?
I didn’t create a factory for each controller. I use abstract_factories LazyControllerAbstractFactory::class
You don’t want the cache adapter, so do not use his name. The Redis::class
comes with redis extension of PHP, use this. But create a custom factory for it.
If you register Redis::class
in the service manager or something else like Foobar::class
or Something::class
then the LazyControllerAbstractFactory::class
of laminas-mvc or the ReflectionBasedAbstractFactory
of laminas-servicemanager will find it under these names.
There is no magic, only some simple matching! 
I got the error
Unable to create controller "Application\Controller\ForumController"; unable to resolve parameter "redis" using type hint "Application\Controller\Redis"
my module.config.php
I wrote a CommonRedisFactory like
<?php
/**
* single instance of redis connnection
*/
namespace Application\Service\Factory;
use Interop\Container\ContainerInterface;
use Interop\Container\Exception\ContainerException;
use Laminas\ServiceManager\Exception\ServiceNotCreatedException;
use Laminas\ServiceManager\Exception\ServiceNotFoundException;
use Laminas\ServiceManager\Factory\FactoryInterface;
class CommonRedisFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$redis = new \Redis();
$redis->connect('localhost', 6379);
return $redis;
}
}
controller __construct like:
class ForumController extends AbstractActionController
{
public $forumMainTable;
public $userFavoriteTable;
public $baseFuncModel;
public $forumClassTable;
public $redis;
public function __construct(ForumMainTable $forumMainTable, UserFavoriteTable $userFavoriteTable, BaseFuncModel $baseFuncModel, ForumClassTable $forumClassTable, Redis $redis)
{
$this->forumMainTable = $forumMainTable;
$this->userFavoriteTable = $userFavoriteTable;
$this->baseFuncModel = $baseFuncModel;
$this->forumClassTable = $forumClassTable;
$this->redis = $redis;
}
Not work in this way.
See the error message because there is no class Application\Controller\Redis
and for that reason PHPStorm highlights Redis
in your controller.
Typical namespace error: you must import the Redis
in your controller class:
// …
use Laminas\Mvc\Controller\AbstractActionController;
use Redis;
class ForumController extends AbstractActionController
{
// …
}
@froschdesign
Thank you! I adopt your way. I belive it is the best way! Thank you so much for your time and efforts.