在ZF2项目中启用Doctrine 2缓存

4
如何在使用Zend Framework 2和Doctrine 2的项目中启用缓存?应该启用哪种缓存,Doctrine缓存还是Zend缓存?以下是我尝试过的方法,但在执行时间上没有看到任何区别。需要编辑module\Application\config\module.config.php文件。
 'doctrine.cache.my_memcache' => function ($sm) {
            $cache = new \Doctrine\Common\Cache\MemcacheCache();
            $memcache = new \Memcache();
            $memcache->connect('localhost', 11211);
            $cache->setMemcache($memcache);
        return $cache;
      }, 


    'doctrine.cache.apc' => function ($sm){
            $apc = new \Doctrine\Common\Cache\ApcCache();
            return $apc;
    },



    // Doctrine config
    'doctrine' => array(
        'driver' => array(
            __NAMESPACE__ . '_driver'   => array(
                'class' => 'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
                'cache' => 'array',
                'paths' => array(__DIR__ . '/../src/' . __NAMESPACE__ . '/Entity'),
            ),
            'orm_default' => array(
                'drivers' => array(
                    __NAMESPACE__ . '\Entity' => __NAMESPACE__ . '_driver'
                ),
            )
        ),
        'configuration' => array(
            'orm_defaults' => array(
                'metadata_cache'    => 'apc',
                'query_cache'       => 'apc',
                'result_cache'      => 'my_memcache',
            )
        )
    ),

任何帮助、想法或解释都会受到欢迎。谢谢。

1个回答

9
为了避免不必要的麻烦,开发时应始终使用array缓存,而在生产环境中运行应用程序时应使用memcachedredisapc
您应该将工厂定义放在service_manager>factories键下,而不是直接放在模块配置数组中。
请在您的module.config.php中尝试此操作:
return [
    'doctrine' => [
        'configuration' => [
            'orm_default' => [
                'metadata_cache' => 'mycache',
                'query_cache' => 'mycache',
                'result_cache' => 'mycache',
                'hydration_cache' => 'mycache',
            ]
        ],
    ],

    'service_manager' => [
        'factories' => [
            'doctrine.cache.mycache' => function ($sm) {
                $cache = new \Doctrine\Common\Cache\MemcacheCache();
                $memcache = new \Memcache();
                $memcache->connect('localhost', 11211);
                $cache->setMemcache($memcache);

                return $cache;
            },
        ],
    ],
];

我强烈建议将工厂移动到单独的工厂类中,这样,在生产环境中,你将拥有更可读、可维护和高效的应用程序,并且可以借助合并配置缓存来实现。

例如:

'service_manager' => [
    'factories' => [
        'doctrine.cache.mycache' => \App\Memcache\Factory::class // implement FactoryInterface
        ],
    ],
];

几年后的更新:

在编写定制化的工厂创建各种Doctrine组件,例如实体管理器、配置或缓存之前,我强烈建议您先研究roave/psr-container-doctrine。作为该库的贡献者,我可以说它适用于我目前大部分需要的用例。当您确实需要一个专门的工厂时,可以扩展、组合或修饰提供的工厂,并在其上添加自己的逻辑。


谢谢您的回复...我现在会去做,但是我可以问一个问题吗?我怎么知道缓存是否正在工作? - user3911183
您可以在任何服务定位器感知类中尝试从Doctrine配置中提取。例如,$config = $this->getServiceLocator()->get('doctrine.configuration.orm_default');$cache = $config->getQueryCacheImpl(); - edigu
文件缓存保存在哪里? - user3911183
非常幼稚的问题:这是否应该自动工作?我看到一些文档和评论(例如在Stack上)似乎暗示它是这样的。或者你必须明确地在你的存储库类中使用fetch|contains|save|delete API等?文档也给出了一些例子。 - David
是的,元数据缓存、查询缓存和结果缓存在正确配置后会被Doctrine自动利用。所有这些缓存提供程序都有良好的接口($cache->save($key, $item, $ttl)、$cache->has($key)),当然您也可以在应用程序的不同层中利用它们来处理与业务相关的数据。 - edigu
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接