超简单的静态文件(html)php网站缓存

6
我有一个网站,基本上只显示一些内容,没有任何表单和提交。这个网站是基于PHP的,并托管在共享主机上。它很少改变。我想为这个网站启用缓存。由于是共享主机,所以我需要一个解决方案:
  • 不使用Memcached
  • 不需要将我的网站移动到VPS
  • 不使用APC或其他东西
所以基本上我想要实现的是将每个子站点缓存为HTML,并告诉PHP获取当前子站点的HTML缓存版本并将其显示给用户5分钟。 5分钟后刷新缓存。
我已经在互联网上寻找了一段时间,有一些教程和框架支持这种奇怪的缓存方式。但我只需要一个非常易于使用的好库。
我希望它能按照以下方式工作:
<?

if (current_site_cache_is_valid())
{
   display_cached_version();
   die;
}

..mywebsite rendering code

?>

虽然听起来很简单,但我希望一些优秀的开发者之前已经做过这种库。所以你知道这样的成品可用、实现不需要太多时间的解决方案吗?


如果您可以使用PEAR,那么PEAR_Cache可能是您所需的全部内容:http://pear.php.net/package/Cache - nikc.org
你有安装Apache和.htaccess吗? - hakre
可能是重复的问题:如何为PHP网站实现HTML缓存? - hakre
很抱歉,@nikc.org,我不能这样做。hakre,我有Apache和htaccess,但不是这个问题。 - Tom Smykowski
5个回答

5
这是我通常的做法,但我不知道你的URL设计和目录/文件布局。
我使用.htaccessmod_rewrite­Docs来实现。
Web服务器检查是否存在缓存的HTML文件,如果是,则传递该文件。您还可以检查它的年龄。
如果太旧或不存在,则启动您的PHP脚本。在脚本开始时,启动输出缓冲区­Docs。在脚本结束时,获取输出缓冲区并将内容放入缓存文件中,然后输出它。
这种解决方案的好处是,如果静态文件存在且不需要调用PHP进程,则Apache将提供静态文件。如果您只使用PHP完成所有操作,则无法获得此优势。
我甚至会进一步运行 cron 作业来删除旧的缓存文件,而不是在 .htaccess 中进行时间检查。完成后,您可以使重写更简单,以优先选择 .php.cached 文件而不是 .php 文件。

@tomaszs:根据您的url /文件/缓存布局,需要使用它。如果您正在寻找示例和想法,我认为这篇文章非常有见地:[Advanced Cache Mechanism Using PHP,C ++&Apache mod_rewrite](http://sven.webiny.com/advanced-cache-mechanism-using-php-cpp-and-apache/)-此外,请参阅此相关问题:[RewriteRule checking file in rewriten file path exists](https://dev59.com/j3RB5IYBdhLWcg3w6bUD) - hakre

3

我有一个简单的HTML缓存算法,基于以下条件:

  • 用户是访客(已登录的用户有一个blog_user cookie设置)
  • 请求URI是一个不包含请求参数的GET请求
  • 文件的HTML缓存版本存在

然后,一个.htaccess重写规则启动,将请求映射到缓存文件。其他任何内容都被认为是上下文特定的,因此不能被缓存。请注意,我在我的博客中使用维基百科风格的URI映射,所以当没有缓存时,/article-23会被映射到/index.php=article-23

我在我的DOCUMENT_ROOT目录中使用单个HTML访问文件,这里是相关的摘录。第三个重写规则可以实现你想要的功能。生成可缓存输出的任何脚本都将其包装在ob_start() ob_get_clean()对中,并写出HTML缓存文件(尽管这一切都由我的模板引擎处理)。更新也会根据需要刷新HTML缓存目录。

RewriteEngine on
RewriteBase /

# ...
# Handle blog index
RewriteRule ^blog/$                                    blog/index               [skip=1]

# If the URI maps to a file that exists then stop.  This will kill endless loops

RewriteCond %{REQUEST_FILENAME}                        -f
RewriteRule ^blog/.*                                   -                        [last]

# If the request is HTML cacheable (a GET to a specific list, with no query params)
# the user is not logged on and the HTML cache file exists then use it instead of executing PHP

RewriteCond %{HTTP_COOKIE}                             !blog_user
RewriteCond %{REQUEST_METHOD}%{QUERY_STRING}           =GET                     [nocase]
RewriteCond %{DOCUMENT_ROOT}/blog/html_cache/$1.html   -f
RewriteRule ^blog/(article-\d+|index|sitemap.xml|search-\w+|rss-[0-9a-z]*)$ \
                                                       blog/html_cache/$1.html  [last]

# Anything else relating to the blog pass to index.php
RewriteRule blog/(.*)                                  blog/index.php?page=$1   [qsappend,last]

希望这可以帮助您。我的博客详细描述了这个问题。 :-)

2
为了让nico的回答更加适用于通用的复制粘贴使用,节省输入每个缓存文件名的时间,以下是一些补充内容。
原文:
$cachefile = 'cache/index-cached.html';

修改时间:

$cachefile = $_SERVER['DOCUMENT_ROOT'].'/cache/'.pathinfo($_SERVER['SCRIPT_NAME'], PATHINFO_FILENAME).'-cached.html';

这段代码的作用是获取当前文件的文件名(在我的情况下是.php),去掉扩展名,然后在文件名后面添加“-cached.html”标签和新的扩展名以创建缓存文件。虽然可能有更高效的方法,但它对我很有效,希望也能为其他人节省时间和精力。


2

虽然你之前问过这个问题已经有一段时间了,但是由于它仍在不断地被搜索,我想给你一个更好的答案。

你可以在PHP中进行静态缓存,而不需要使用.htaccess或其他诡计。我在http://simonwillison.net/2003/may/5/cachingwithphp/上找到了这个方法:

<?php
$cachefile = 'cache/index-cached.html';
$cachetime = 5 * 60;
// Serve from the cache if it is younger than $cachetime
if (file_exists($cachefile) && time() - $cachetime < filemtime($cachefile)) {
    include($cachefile);
    echo "<!-- Cached copy, generated ".date('H:i', filemtime($cachefile))." -->\n";
    exit;
}
ob_start(); // Start the output buffer

/* The code to dynamically generate the page goes here */

// Cache the output to a file
$fp = fopen($cachefile, 'w');
fwrite($fp, ob_get_contents());
fclose($fp);
ob_end_flush(); // Send the output to the browser
?>

1
这不是静态文件缓存,每个请求仍然涉及到 PHP 进程,这就打败了静态文件缓存的整个意义。 - kizzx2

1

你应该试试 skycache编辑:这个项目看起来也很酷:cacheme

另一个解决方案是使用auto_prepend_file/auto_append_file。像这篇教程中描述的那样:初学者的输出缓存


skycache 看起来很有趣,但在安全模式下似乎无法工作。有什么想法吗? - Tom Smykowski

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