Php Symfony 3中的ESI缓存
我已经在我的Symfony 3应用程序中启用了ESI,我在Php Symfony 3中的ESI缓存,php,caching,symfony,http-caching,esi,Php,Caching,Symfony,Http Caching,Esi,我已经在我的Symfony 3应用程序中启用了ESI,我在app\u dev.php中也启用了ESI: $kernel = new AppKernel('dev', true); $kernel = new AppCache($kernel); 现在我有了config.yml: framework: esi: { enabled: true } fragments: { path: /_fragment } 在我的控制器中: /** * @Route("/foo/bar/{
app\u dev.php
中也启用了ESI:
$kernel = new AppKernel('dev', true);
$kernel = new AppCache($kernel);
现在我有了config.yml
:
framework:
esi: { enabled: true }
fragments: { path: /_fragment }
在我的控制器中:
/**
* @Route("/foo/bar/{fooId}", name="AppBundle_Foo_bar")
*/
public function barAction(int $fooId, Request $request)
{
//some database querying from repositroy
$response = $this->render('AppBundle:Foo:bar.html.twig',['foo' => $foo]);
$response->setETag(md5($response->getContent()));
$response->setPublic();
$response->isNotModified($request);
return $response;
}
这是我要缓存的视图(bar.html.twig
),看起来像:
{{foo}}
{% extends 'AppBundle::layout.html.twig' %}
{% block content %}
{{ render_esi(controller('AppBundle:Foo:bar', { 'fooId': fooId })) }}
{% endblock content %}
现在,我有另一个方法来渲染主视图
/**
* @Route("/baz/{fooId}", name="AppBundle_Foo_baz")
* @Template
*/
public function bazAction(int $fooId)
{
return [
'fooId' => $fooId
];
}
我的baz.html.twig
看起来像:
{{foo}}
{% extends 'AppBundle::layout.html.twig' %}
{% block content %}
{{ render_esi(controller('AppBundle:Foo:bar', { 'fooId': fooId })) }}
{% endblock content %}
因此,我希望主要使用非缓存视图(baz)和嵌套barAction()
,并将其缓存
但是,我得到了:
Cache-Control:must-revalidate, no-cache, private
即使我将其显式设置为public,我也得到:
X-Symfony-Cache:GET /baz/1: miss;
每次刷新页面时,我都会得到:
GET /_fragment?_hash=aO.....Details: stale, invalid, store
如果我刷新,无效变为有效。但我不能设置缓存
编辑:
我读过关于ESI和验证缓存的文章,但它们似乎不能一起工作。所以我尝试了验证缓存并添加了
$response->setSharedMaxAge(15);
$response->headers->addCacheControlDirective('must-revalidate', true);
而不是ETag。同样的结果…我遵循了您的代码/设置,但我添加了一个时间戳以打印在
bar.html.twig
中。它肯定会缓存ESI块。您提到的响应头是主请求上的响应头还是ESI块上的响应头?即使缓存公共块,主请求仍然可以是私有的。尝试向模板添加一个时间戳,看看它是否被缓存或更改。嗯,我认为当在其他头中调用一个控制器时,其他头将被合并。我将尝试添加时间戳以检查缓存。我也会在主请求中添加登录按钮。所以当我通过chrome登录时,它会打印我的用户名而不是登录按钮,当我在firefox中打开页面时,我会看到登录按钮而不是chrome会话中的用户名。我会报告结果。试着在Symfony之外思考。ESI可以由许多反向代理(例如:Varnish)支持。在您的例子中,它是AppCache类。当您得到一个反向代理来构造发送到客户端的页面时会发生什么:1。代理加载第2页。ESI检查包括标签3。if tag found对该块发出另一个HTTP请求(如果public或vary头允许,则从缓存提供服务)4。将构造好的HTML发送到客户端注意:要小心缓存的块,它不应该包含私有信息(除非使用vary,但那是另一回事)!是的,你说得对。今天晚些时候,我将尝试从我的示例构建ESI并报告结果。