根据环境

时间:2017-10-23 16:06:47

标签: php symfony caching autowired psr-6

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

我正在使用 symfony 3.3.10

为实现这一目标,我想按照以下方式自动装载 CacheInterface

use Psr\SimpleCache\CacheInterface;

class Api {

    public function __construct(CacheInterface $cache)
    {
        $this->cache = $cache;
    }
}

以下是我的配置文件:

config_dev.yml

framework:
    cache:
        app: cache.adapter.filesystem

config_prod.yml

framework:
    cache:
        app: cache.adapter.memcached
        ...

这是我得到的错误: enter image description here

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

services:
    Symfony\Component\Cache\Simple\FilesystemCache: ~

但现在我无法为测试环境提供另一个缓存系统,例如 NullCache 。实际上,我必须声明只有一个服务继承自 CacheInterface 。由于 config_test 也在使用 config_dev ,因此无法实现。

这是 services.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:
        pools:
            app.cache.api:
                default_lifetime: 3600

services.yml

# ...
Psr\Cache\CacheItemPoolInterface:
    alias: 'app.cache.api'

2 个答案:

答案 0 :(得分:5)

即使工厂模式是解决此类问题的好选择,通常您也不需要为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服务默认不可用,您可能需要手动定义它。

答案 1 :(得分:3)

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

// 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%']

Symfony Documentation中查看有关服务工厂的更多信息。


您可以在我的Why Config Coding Sucks帖子中详细了解这一点。