PHP:使用状态缓存页面

5
我想在几个页面上使用缓存:
1. 博客页面 2. index.php 但是,在设计我的系统后,我发现我的页面标题根据状态会微微地改变(例如,如果您已登录,则会显示类似“您好,johnnie@example.com”的内容)。因此,我希望确保它不会意外地在顶部显示错误的用户名或电子邮件。
很遗憾,我不想在页面上缓存这样一个小东西,却被迫不在我的网站上缓存任何内容。
有什么解决方法吗?
7个回答

8

您需要考虑为什么要进行缓存。缓存是一种优化,因此只有在必要的情况下才应该进行。

如果您不确定是否需要缓存,请返回并进行一些研究以确保。这将涉及在测试实验室中对生产级硬件进行性能测试。

一旦您确定它是必要的,那么您就会知道需要多少改进。您可以考虑仅缓存页面的某些部分-这将比缓存完整页面在前端和缓存层上效率低,但可能会减轻后端的负载,因为您将获得更高的缓存命中率。

考虑一个具有个性化元素(例如,Hello Johnnie)和计算成本相对较高但相对不经常更改且适用于所有用户的部分(例如某些股票价格)的页面。

您可以将页面的股票价格部分缓存5分钟,并每次生成页面的个性化部分。这样,您就不会因为股票价格而使后端负担过重,仍然可以向正确的人显示正确的页面。

大多数公司发现生成前端相当耗费计算资源(组合HTML非常耗时),但可扩展性很好-这意味着当速度不够快时,您可以简单地添加更多硬件。另一方面,后端服务器可以执行更多的工作,但可扩展性较差-例如数据库-您无法简单地添加更多服务器,因为存在一致性/同步问题,限制了可扩展性。


如果您坚持需要页面的某些部分是动态的,那么您必须真正评估缓存页面片段是否值得努力。使用片段缓存,您将增加一定的容量,但仍必须为每个页面请求调用PHP解释器,从而使您的缓存整个页面的能力远低于您所能实现的水平。+1 - Ben James

4
我曾多次使用的一种方法是:
  • 生成页面并将其存储到缓存中,其中包含类似于“Hello, %%PLACEHOLDER_NAME%%”而不是实际名称的内容。
  • 当用户加载页面时:
    • 加载缓存页面
    • 使用 (快速) str_replace 替换 %%PLACEHOLDER_NAME%% 标记为用户的姓名
    • 发送以这种方式创建的 "部分动态" 页面。
这意味着您需要进行一些PHP操作,不能缓存整个页面或将其作为静态文件提供...
但它也意味着几乎整个页面都在缓存中 - 例如,如果名称存储在会话中,则无需执行任何数据库查询。
有人会说它有点“肮脏”,但在只有一两个小部分必须是动态的情况下,它确实非常有效(在您的情况下似乎是这样)。
如果你有一天开始有太多这些占位符,你就必须考虑不缓存页面,而是缓存生成页面所需的数据。
这意味着您必须从缓存中获取数据并将它们粘合在一起以生成页面 - 但是��这样做仍然可以避免一些SQL查询,因为大部分数据都将从缓存中加载。

2
您可以将用户特定参数用作大多数缓存库中使用的Cache_ID或Cache_ID_Key:

例如:

$id = sh1($userMail);
$cache->save($id);

这是一个最简单的例子。其思想是“密钥应包括特定于每个用户的用户特定信息”。
希望你能理解这个思路。

这可能会帮助我加载页面的特定部分...这不是一个坏主意。 - johnnietheblack

1
不要缓存整个页面 - 只需缓存需要实际缓存的部分(例如可以避免打开数据库连接的部分)。然后页面的其余部分仍然可以是动态的,我假设您正在将用户名存储在会话变量中,所以仍然可以执行例如以下操作:
echo "Hello ".$_SESSION['username'];

1
你在使用哪个模板引擎?Smarty吗?如果是的话,你可以像这样强制不缓存网页的某些动态部分。
{nocache}
Hello {$username} This is your Email {$email}
{/nocache}

其实我自己写了一个来学习内部结构...虽然这个想法也不错。但听起来相当复杂,而且可能带来的好处很少...对吧? - johnnietheblack
1
Smarty并不复杂。它非常易于使用,并且有很好的文档支持。我可以向所有需要分离应用逻辑和设计逻辑的人推荐它。 - streetparade

1
你想要缓存到哪里?
在你的服务器上?你可能需要看看Smarty。
在代理/客户端上?那么可以使HTML页面可缓存,用空的div替换任何动态内容,并使用JavaScript编写值 - JavaScript可能会将一些信息缓存在cookie中,并返回服务器获取其余部分。
或者看看“Varies:Cookie”头文件,了解如何进行会话导向的缓存。
C.

1

对于您想要的功能来说,这可能有点过头了,但是ESI可以解决您面临的问题。

然而,您还应该考虑这一点:有多少流量是已登录的?对于许多Web应用程序来说,90%以上的流量都是匿名的,并且所有匿名页面都呈现相同。简单地缓存匿名页面可能会为您带来您所寻求的大部分好处,而几乎不需要任何工作。

此外,请考虑缓存页面中可能在许多页面上重复使用的小部分内容--例如,如果您有一个标签云显示在所有页面上,并且需要200毫秒才能生成,请将其缓存。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接