如何在ZF2中处理缓存



我刚刚开始把我的头脑放在缓存上。我有一个简单的indexAction(),它获取所有给定的数据集。我的方法是:

  • 检查现有密钥"controllername index index">
  • 如果存在:返回键的值
  • 如果不存在,请执行正常操作并添加密钥

键内的值应该是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;
}

出于测试目的,对缓存部分进行了注释,但基本上这就是我所做的全部工作。缓存配置/服务如下所示:

<?php
'cache' => function () {
return ZendCacheStorageFactory::factory(array(
'adapter' => array(
'name' => 'filesystem',
'options' => array(
'cache_dir' => __DIR__ . '/../../data/cache',
'ttl' => 100
),
),
'plugins' => array(
array(
'name' => 'serializer',
'options' => array(
)
)
)
));
},

序列化和缓存工作得很好,但我对丢失的结果感到惊讶。根据ZendDevelopersToolbar告诉我的,不进行缓存的时间在1.8s到2.5s之间。取消缓存部分的注释(启用)并不能真正改善页面的加载时间。

所以我的问题是:这种方法完全错误吗?有没有不同的、更快速的部件可以通过一些巧妙的配置技巧来保存?

我觉得2秒的页面加载时间肯定太慢了。对我来说,1是给定大量数据的最大值,但肯定不会超过这个值:S

我们将非常感谢所有的帮助/提示/建议。提前感谢!

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

namespace MyModule;
use ZendMvcMvcEvent;
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%复制/粘贴,而是概念)可以工作,因为如果在路由或调度事件期间返回Response,应用程序将使应用程序流短路,并停止进一步触发侦听器。然后,它将按原样提供此响应。

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

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

最新更新