Php Autowire symfony CacheInterface取决于环境

Php Autowire symfony CacheInterface取决于环境,php,symfony,caching,autowired,psr-6,Php,Symfony,Caching,Autowired,Psr 6,我正在尝试在我的环境中使用不同的缓存系统。例如,对于dev我希望有Filesystem,对于prod我希望有memcached 我正在使用symfony 3.3.10 为了实现这一点,我希望自动连接CacheInterface,如下所示: use Psr\SimpleCache\CacheInterface; class Api { public function __construct(CacheInterface $cache) { $this->c

我正在尝试在我的环境中使用不同的缓存系统。例如,对于dev我希望有
Filesystem
,对于prod我希望有
memcached

我正在使用symfony 3.3.10

为了实现这一点,我希望自动连接CacheInterface,如下所示:

use Psr\SimpleCache\CacheInterface;

class Api {

    public function __construct(CacheInterface $cache)
    {
        $this->cache = $cache;
    }
}
以下是我的配置文件:

配置开发yml

framework:
    cache:
        app: cache.adapter.filesystem
framework:
    cache:
        app: cache.adapter.memcached
        ...
framework:
    # ...
    cache:
        pools:
            app.cache.api:
                default_lifetime: 3600
# ...
Psr\Cache\CacheItemPoolInterface:
    alias: 'app.cache.api'
// AppBundle/Cache/CacheFactory.php

namespace AppBundle\Cache;

final class CacheFactory
{
    public function create(string $environment): CacheInterface
    {
        if ($environment === 'prod') {
            // do this
            return new ...;
        }

        // default 
        return new ...;
    }
}
配置产品yml

framework:
    cache:
        app: cache.adapter.filesystem
framework:
    cache:
        app: cache.adapter.memcached
        ...
framework:
    # ...
    cache:
        pools:
            app.cache.api:
                default_lifetime: 3600
# ...
Psr\Cache\CacheItemPoolInterface:
    alias: 'app.cache.api'
// AppBundle/Cache/CacheFactory.php

namespace AppBundle\Cache;

final class CacheFactory
{
    public function create(string $environment): CacheInterface
    {
        if ($environment === 'prod') {
            // do this
            return new ...;
        }

        // default 
        return new ...;
    }
}
以下是我得到的错误:

将FilesystemCache声明为服务时,错误消失:

services:
    Symfony\Component\Cache\Simple\FilesystemCache: ~
但是现在我不能为测试环境使用另一个缓存系统,比如NullCache。事实上,我只需要声明一个从CacheInterface继承的服务。这是不可能的,因为配置测试也在使用配置开发

这是服务的开始。yml如果可以帮助:

services:
    _defaults:
        autowire: true
        autoconfigure: true
        public: false
您知道如何根据环境自动连接不同的缓存系统吗?

编辑: 以下是工作配置:

use Psr\Cache\CacheItemPoolInterface;

class MyApi
{
    /**
     * @var CacheItemPoolInterface
     */
    private $cache;

    public function __construct(CacheItemPoolInterface $cache)
    {
        $this->cache = $cache;
    }
}
config.yml

framework:
    cache:
        app: cache.adapter.filesystem
framework:
    cache:
        app: cache.adapter.memcached
        ...
framework:
    # ...
    cache:
        pools:
            app.cache.api:
                default_lifetime: 3600
# ...
Psr\Cache\CacheItemPoolInterface:
    alias: 'app.cache.api'
// AppBundle/Cache/CacheFactory.php

namespace AppBundle\Cache;

final class CacheFactory
{
    public function create(string $environment): CacheInterface
    {
        if ($environment === 'prod') {
            // do this
            return new ...;
        }

        // default 
        return new ...;
    }
}
服务。yml

framework:
    cache:
        app: cache.adapter.filesystem
framework:
    cache:
        app: cache.adapter.memcached
        ...
framework:
    # ...
    cache:
        pools:
            app.cache.api:
                default_lifetime: 3600
# ...
Psr\Cache\CacheItemPoolInterface:
    alias: 'app.cache.api'
// AppBundle/Cache/CacheFactory.php

namespace AppBundle\Cache;

final class CacheFactory
{
    public function create(string $environment): CacheInterface
    {
        if ($environment === 'prod') {
            // do this
            return new ...;
        }

        // default 
        return new ...;
    }
}

Symfony 3.3+/4和2017/2019中,您可以省略任何配置依赖项,并使用工厂模式保持对行为的完全控制:

framework:
    cache:
        app: cache.adapter.filesystem
framework:
    cache:
        app: cache.adapter.memcached
        ...
framework:
    # ...
    cache:
        pools:
            app.cache.api:
                default_lifetime: 3600
# ...
Psr\Cache\CacheItemPoolInterface:
    alias: 'app.cache.api'
// AppBundle/Cache/CacheFactory.php

namespace AppBundle\Cache;

final class CacheFactory
{
    public function create(string $environment): CacheInterface
    {
        if ($environment === 'prod') {
            // do this
            return new ...;
        }

        // default 
        return new ...;
    }
}
services.yml
当然:

# app/config/services.yml
services:
    Psr\SimpleCache\CacheInterface:
        factory: 'AppBundle\Cache\CacheFactory:create'
        arguments: ['%kernel.environment%']
请参阅中有关服务工厂的更多信息



您可以在我的帖子中了解更多信息。

尽管factory模式是解决此类问题的一个很好的选择,但对于Symfony缓存系统,通常不需要这样做。改为键入提示
CacheItemPoolInterface

use Psr\Cache\CacheItemPoolInterface;

public function __construct(CacheItemPoolInterface $cache)
它会根据活动环境自动注入当前的
cache.app
服务,因此Symfony会为您完成这项工作

只需确保为每个环境配置文件配置
framework.cache.app

# app/config/config_test.yml
imports:
    - { resource: config_dev.yml }

framework:
    #...
    cache:
        app: cache.adapter.null

services:
    cache.adapter.null:
        class: Symfony\Component\Cache\Adapter\NullAdapter
        arguments: [~] # small trick to avoid arguments errors on compile-time.

由于默认情况下,
cache.adapter.null
服务不可用,您可能需要手动定义它。

nice+1:)能否使用工厂方法显示最终的
Api
服务定义,谢谢!几个小时后就可以了,现在就要走了。非常感谢,我不知道这是可能的,我会记住;)谢谢这就是我一直在寻找的答案!但是池的默认生命周期似乎不起作用。你能添加那个配置吗
$item->expiresAfter(10)
有效,但我想定义一个默认值默认生命周期也可以配置,请检查。我已经尝试过了,但没有考虑它。我正在使用文件系统。如果你能复制这个问题,请报告给。我马上就做。