Caching 如何在ZF2中实现缓存

Caching 如何在ZF2中实现缓存,caching,zend-framework2,Caching,Zend Framework2,我刚刚开始把我的头脑作为一个整体来进行缓存。我有一个简单的indexAction()来获取所有给定的数据集。我的做法是: 检查现有键“controllername索引” 如果存在:返回键的值 如果不存在,则执行正常操作并添加键 键内的值应该是将生成并填充“我的数据”的ViewModel 以下是我迄今为止所做的工作: <?php public function indexAction() { $sl = $this->getServiceLocator(); // $ca

我刚刚开始把我的头脑作为一个整体来进行缓存。我有一个简单的indexAction()来获取所有给定的数据集。我的做法是:

  • 检查现有键“controllername索引”
  • 如果存在:返回键的值
  • 如果不存在,则执行正常操作并添加键
键内的值应该是将生成并填充“我的数据”的ViewModel

以下是我迄今为止所做的工作:

<?php
public function indexAction()
{
    $sl = $this->getServiceLocator();
//  $cache = $sl->get('cache');
//  $key = 'kennzahlen-index-index';
//
//  if ($cache->hasItem($key)) {
//      return $cache->getItem($key);
//  }

    $viewModel = new ViewModel();
    $viewModel->setTemplate('kennzahlen/index/index');
    $entityService = $sl->get('kennzahlen_referenzwert_service');
    $viewModel->setVariable('entities', $entityService->findAll());

//  $cache->setItem($key, $viewModel);

    return $viewModel;
}

一个选项是缓存页面的完整输出,例如基于路由匹配。您需要在路由和调度之间侦听找到的匹配路由,然后采取相应的行动:

namespace MyModule;

use Zend\Mvc\MvcEvent;

class Module
{
    public function onBootstrap(MvcEvent $e)
    {
        // A list of routes to be cached
        $routes = array('foo/bar', 'foo/baz');

        $app = $e->getApplication();
        $em  = $app->getEventManager();
        $sm  = $app->getServiceManager();

        $em->attach(MvcEvent::EVENT_ROUTE, function($e) use ($sm) {
            $route = $e->getRouteMatch()->getMatchedRouteName();
            $cache = $sm->get('cache-service');
            $key   = 'route-cache-' . $route;

            if ($cache->hasItem($key)) {
                // Handle response
                $content  = $cache->getItem($key);

                $response = $e->getResponse();
                $response->setContent($content);

                return $response;
            }
        }, -1000); // Low, then routing has happened

        $em->attach(MvcEvent::EVENT_RENDER, function($e) use ($sm, $routes) {
            $route = $e->getRouteMatch()->getMatchedRouteName();
            if (!in_array($route, $routes)) {
                return;
            }

            $response = $e->getResponse();
            $content  = $response->getContent();

            $cache = $sm->get('cache-service');
            $key   = 'route-cache-' . $route;
            $cache->setItem($key, $content);
        }, -1000); // Late, then rendering has happened
    }
}
第二个侦听器在呈现事件时进行检查。如果发生这种情况,响应的结果将被缓存

此系统(可能不是100%复制/粘贴,而是概念)工作,因为如果在路由或调度事件期间返回
响应
,应用程序将使应用程序流短路并停止进一步触发侦听器。然后,它将按原样提供此响应

请记住,这将是完整的页面(包括布局)。如果您不希望这样做(仅限于控制器),请将逻辑移到控制器。第一个事件(现在是路由)是调度控制器。早点听,这样动作的正常执行就会被忽略。要缓存结果,请检查要侦听的视图层的渲染事件


/更新:我写了一个小模块,在你的应用程序中使用这个干版:

你确定是这个特定的部分导致了这个问题吗?我的ZF2页面通常在100ms以下运行,因此应该还有另一个原因。另外,我更喜欢缓存特定的查询结果,而不是视图模型。如果要缓存任何与视图相关的内容,请缓存视图渲染,以便跳过对.phtml文件的解析。否则,缓存服务的结果。问题是,在哪里注入代码以便缓存视图渲染?虽然很明显,我会明智的建议,看看是什么让我的脚本这么慢。没有启用很多模块,zfcuser、bjyauthorize、ZenddeveloperToolbar和doctrine stuff+my模块使用doctrine获取一些db实体:SI回答了一个可能的缓存选项,可以缓存html结果。安装Xdebug并执行一些分析操作,以了解应用程序的真正瓶颈是什么。可能查询速度快,因此缓存没有好处。除此之外,我建议使用APC进行缓存。这将比使用文件系统快得多。众所周知,问题是我们的服务器人员由于一些不相关的原因不会给我们APC(或MC):所以文件系统是我唯一的选择…感谢您提供这些示例。XDebug确实将是下一步要做的事情。然而,对我来说,这个例子是EventManager用法的一个很好的参考,这是我还没有完全弄清楚的:)谢谢你,我们将在周一报告;)我会接受这个答案,因为它具有普遍的目的。不过,经过一些XDebugg之后,我的错误似乎是我的DB连接,它在本地xampp环境中需要1s,所以必须设法弄清楚;)谢谢你的帮助!我想我在某个地方读到,
pre
post
事件是缓存东西的好方法。Pre用于检查缓存中是否存在(然后返回if-so)以及Post用于在执行引导/任何操作后添加到缓存。@DominicWatson Pre/Post是ZF1的典型挂钩,这个问题是关于您与
Pre
交谈的ZF2Ah@DominicWatson以及
Post
关于自定义事件的问题。我的答案使用事件管理器(检查我发布的代码),我短路并返回响应。如果你在“早期”中说pre,那正是
route
所做的。如果你在“late”中说post,那正是
render
所做的。任何缓存解决方案都使用命中早期返回和延迟侦听器进行存储。一般来说,这样的模式可以是名称
pre
post
,但对于Zend Framework 2的应用程序流程,我会使用
路由
渲染
事件。
namespace MyModule;

use Zend\Mvc\MvcEvent;

class Module
{
    public function onBootstrap(MvcEvent $e)
    {
        // A list of routes to be cached
        $routes = array('foo/bar', 'foo/baz');

        $app = $e->getApplication();
        $em  = $app->getEventManager();
        $sm  = $app->getServiceManager();

        $em->attach(MvcEvent::EVENT_ROUTE, function($e) use ($sm) {
            $route = $e->getRouteMatch()->getMatchedRouteName();
            $cache = $sm->get('cache-service');
            $key   = 'route-cache-' . $route;

            if ($cache->hasItem($key)) {
                // Handle response
                $content  = $cache->getItem($key);

                $response = $e->getResponse();
                $response->setContent($content);

                return $response;
            }
        }, -1000); // Low, then routing has happened

        $em->attach(MvcEvent::EVENT_RENDER, function($e) use ($sm, $routes) {
            $route = $e->getRouteMatch()->getMatchedRouteName();
            if (!in_array($route, $routes)) {
                return;
            }

            $response = $e->getResponse();
            $content  = $response->getContent();

            $cache = $sm->get('cache-service');
            $key   = 'route-cache-' . $route;
            $cache->setItem($key, $content);
        }, -1000); // Late, then rendering has happened
    }
}