Symfony2:使用http缓存

时间:2015-08-04 09:24:46

标签: symfony http caching

在Symfony2中,我尝试将http缓存用于少数几天返回相同内容的ajax调用。

我的控制器代码完成:

    $response = new JsonResponse($data);
    $response->setPublic();
    $response->setExpires(new \DateTime("+1 hour"));
    $response->setMaxAge(3600);
    return $response;

在响应中(来自Firefox或IE11),我可以找到预期的标题。但它总是返回200代码(OK)而不是304(未修改)。这意味着服务器总是生成响应,而我的目标是使我的服务器负载不足。

我也尝试使用相同结果的@Cache注释。

如何让它发挥作用?

3 个答案:

答案 0 :(得分:2)

您可以通过在app.php中使用AppCache内核(用PHP编写的反向代理)使symfony返回304响应

@Controller
@RequestMapping(produces = {"application/json; charset=UTF-8","*/*;charset=UTF-8"})
public class MyController{
 ...
}

在制作时,您应该考虑使用真正的反向代理服务器,例如Varnish。

http://symfony.com/doc/current/book/http_cache.html

答案 1 :(得分:2)

通过在响应中添加LastModified标头,我成功缓存了您的示例响应。 我做以下两件事:

<强> 1。将Symfony配置为反向代理

我创建了一个自定义环境,在web文件夹中,我创建了一个名为app_cache的文件。如下所述here in the doc

#web/app_cache.php
<?php

// web/app.php
require_once __DIR__.'/../app/bootstrap.php.cache';
require_once __DIR__.'/../app/AppKernel.php';
require_once __DIR__.'/../app/AppCache.php';

use Symfony\Component\HttpFoundation\Request;

$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();
// wrap the default AppKernel with the AppCache one
$kernel = new AppCache($kernel);

$request = Request::createFromGlobals();

$response = $kernel->handle($request);
$response->send();

$kernel->terminate($request, $response);

<强> 2。在响应中添加Last Modified标头

我使用这个控制器:

/**
 * @Route("/cache-me", name="cacheme")
 */
public function cacheMeAction(Request $request)
{
    $data = array("hello" => "symfony");

    $response = new JsonResponse($data);
    $response->setPublic();
    $response->setExpires(new \DateTime("+1 hour"));
    $response->setLastModified(new \DateTime("-1 hour"));

    return $response;
}

第3。测试

我清除prod环境的缓存(app/cache -e=prod)并使用我的浏览器向网址发出两个请求:

  

http://sf.localhost/app_cache.php/cache-me

第一次返回200 Ok而第二次304未修改

希望这个帮助

答案 2 :(得分:0)

另一种方法是在控制器中使用cache服务手动缓存数据,然后执行常见的操作,例如查询数据库和获取内容,只检查是否已存在缓存数据,然后将此数据发送给用户。通常的东西,并在缓存中保存新鲜数据。 JsonResponse类在此处获取状态代码的第二个参数,您可以手动设置304

$cache = $this->container->get( 'cache' );
$cache_key = 'trafficfeed';
    if ( $cache->contains( $cache_key ) ) {
        $data  = $cache->fetch($cache_key  );
        /** here $data is a cached data */
        /** Response::HTTP_NOT_MODIFIED => 304*/
        $response = new JsonResponse($data,Response::HTTP_NOT_MODIFIED);
        return $response;
    }
/** Fetch fresh data and save in cache */
$cache->save( $cache_key, $data, 3600 );
$response = new JsonResponse($data);

对于缓存服务,您需要在配置

中定义它
services:

    cache:
        class: Doctrine\Common\Cache\PhpFileCache
        arguments: [%kernel.cache_dir%]