【问题标题】:Varnish and conditional codes in phpphp中的清漆和条件代码
【发布时间】:2017-02-03 20:12:07
【问题描述】:
我在 PHP 中有这样的代码
//get referer
$reffere_Url = $_SERVER['HTTP_REFERER'];
//if referer is abc.com then show the referer slider at home.
if (strpos($reffere_Url, 'abc') !== false && $home_referal_slider!="")
{
$home_slider = $home_referal_slider;
}
else
{
$home_slider = $home_slider;
}
但即使条件为真,它也总是返回 $home_slider。
这是因为 varnish 已安装并且它提供网页的缓存版本。请帮助如何实现相同的目标。
【问题讨论】:
标签:
php
wordpress
varnish
【解决方案1】:
你需要告诉 Varnish 缓存什么以及如何缓存。
第一个选项是覆盖 Varnish 中的 vcl_hash 以包含引用者:
sub vcl_hash {
hash_data(req.http.referer);
hash_data(req.url);
if (req.http.host) {
hash_data(req.http.host);
} else {
hash_data(server.ip);
}
return (lookup);
}
但这可能会非常严重地影响您的缓存比率 - 每个不同的引用者都将获得他们唯一的缓存池。
更简洁的方法是使用来自后端的 Vary 标头 - 这再次让 Varnish 知道此响应缓存取决于引用标头。我主要使用 Vary 标头,因此我可以从后端控制 Varnish 的行为方式。
在原版 PHP 中:
header('Vary', 'Referer');
但请注意,无论您服务哪个$home_slider,都需要设置此项。因此,如果您在每个页面上都有逻辑,这又会严重影响您的缓存率。
另一种选择是使用 Edge Side Includes (ESI) 从后端获取滑块,以便可以正常缓存页面的其余部分,但这要复杂得多。
因此,最好的解决方案可能是将所有带有referer abc.com 的流量传递到后端。希望这不是您的大多数访问者,它对您的缓存比率的影响最小。
sub vcl_recv {
if (req.http.referer ~ "abc\.com") {
return (pass);
}
}
(基于 Varnish 4 的示例)
【解决方案2】:
我曾尝试检查 vcl_rec 中的 req.http.Referer 值以返回(通过),但没有成功。
还有另一种解决方案,只需将查询字符串 (?ex=exTrDz) 添加到引用页面的 url。这样就可以了。