首页 > 解决方案 > 压缩和缩小 PHP 缓存页面

问题描述

我正在使用此处描述的以下页面缓存技术,如下所示:

<?php
$cachefile = 'cached-files/'.date('M-d-Y').'.php';
$cachetime = 18000;

// Check if the cached file is still fresh. If it is, serve it up and exit.
if (file_exists($cachefile) && time() - $cachetime < filemtime($cachefile)) 
{
    include($cachefile);
    exit;
}

// no file OR the file to too old, render the page and capture the HTML.
ob_start( 'ob_gzhandler' );
?>

<html>
    <!-- CONTENT GOES HERE -->
</html>

<?php
// Save the cached content to a file
$fp = fopen($cachefile, 'w');
fwrite($fp, ob_get_contents());
fclose($fp);

// finally send browser output
ob_end_flush();
?>

一切正常,但我想压缩和缩小缓存文件。

我已经添加ob_gzhandler到;

ob_start( 'ob_gzhandler' );

并有一个包含以下内容的 htaccess 文件:

<IfModule mod_deflate.c>
  # Compress HTML, CSS, JavaScript, Text, XML and fonts
  AddOutputFilterByType DEFLATE application/javascript
  AddOutputFilterByType DEFLATE application/rss+xml
  AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
  AddOutputFilterByType DEFLATE application/x-font
  AddOutputFilterByType DEFLATE application/x-font-opentype
  AddOutputFilterByType DEFLATE application/x-font-otf
  AddOutputFilterByType DEFLATE application/x-font-truetype
  AddOutputFilterByType DEFLATE application/x-font-ttf
  AddOutputFilterByType DEFLATE application/x-javascript
  AddOutputFilterByType DEFLATE application/xhtml+xml
  AddOutputFilterByType DEFLATE application/xml
  AddOutputFilterByType DEFLATE font/opentype
  AddOutputFilterByType DEFLATE font/otf
  AddOutputFilterByType DEFLATE font/ttf
  AddOutputFilterByType DEFLATE image/svg+xml
  AddOutputFilterByType DEFLATE image/x-icon
  AddOutputFilterByType DEFLATE text/css
  AddOutputFilterByType DEFLATE text/html
  AddOutputFilterByType DEFLATE text/javascript
  AddOutputFilterByType DEFLATE text/plain
  AddOutputFilterByType DEFLATE text/xml

  # Remove browser bugs (only needed for really old browsers)
  BrowserMatch ^Mozilla/4 gzip-only-text/html
  BrowserMatch ^Mozilla/4\.0[678] no-gzip
  BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
  Header append Vary User-Agent
</IfModule>

<IfModule mod_expires.c>
  ExpiresActive on

# Your document html
  ExpiresByType text/html "access plus 0 seconds"

# Media: images, video, audio
  ExpiresByType audio/ogg "access plus 1 month"
  ExpiresByType image/gif "access plus 1 month"
  ExpiresByType image/jpeg "access plus 1 month"
  ExpiresByType image/png "access plus 1 month"
  ExpiresByType video/mp4 "access plus 1 month"
  ExpiresByType video/ogg "access plus 1 month"
  ExpiresByType video/webm "access plus 1 month"

# CSS and JavaScript
  ExpiresByType application/javascript "access plus 1 week"
  ExpiresByType text/css "access plus 1 week”

# Fonts
  AddType application/vnd.ms-fontobject .eot
  AddType application/x-font-ttf .ttf
  AddType application/x-font-opentype .otf
  AddType application/x-font-woff .woff
  AddType image/svg+xml .svg

  AddOutputFilterByType DEFLATE application/x-font-ttf application/x-font-opentype image/svg+xml

  ExpiresByType application/vnd.ms-fontobject "access plus 1 year"
  ExpiresByType application/x-font-ttf "access plus 1 year"
  ExpiresByType application/x-font-opentype "access plus 1 year"
  ExpiresByType application/x-font-woff "access plus 1 year"
  ExpiresByType image/svg+xml "access plus 1 year"
</IfModule>

然而,当我使用任何在线工具检查 gzip 压缩时,它们都会返回不。我错过了什么吗?

还有一种方法可以缩小中包含的缓存 HTMLob_get_contents吗?

标签: phpcachingcompressiongzipminify

解决方案


你在这里做的事情有很多问题。

通常,您在此处向我们展示的 Apache 配置应该处理压缩 - 但这取决于处理程序的堆叠顺序。鉴于必须处理为当前请求生成内容、输出缓冲区和重放存储文件的复杂性,如果您的 PHP 代码简单地忽略压缩并由网络服务器处理,您的生活将会简单得多。因此,开始尝试一次分析一个问题:查看当您请求简单的 PHP 生成的 HTML 时,网络服务器的响应是什么。如果它没有被压缩然后回去看看你的网络服务器(你检查过 mod_delfate 是否真的成功加载了吗?)。

压缩和缩小 PHP 缓存页面

压缩通过减少冗余来工作。缩小通过减少冗余来工作。压缩将减小大约 80% 的大小。除非您的 HTML 包含大量冗余标签(即“ <tag></tag>”)并且您的缩小器足够聪明,可以识别和删除这些(我没有看到可以)或大量空白,否则缩小最多只能将大小减少 5 %。效果不是累加的。

使用这两种方法都会为代码增加大量成本(处理、编程)和复杂性,因此不会看到任何巨大的好处。

还有一种方法可以缩小缓存的 HTML

那将是愚蠢的。

您不能假设客户端会接受压缩内容,也不能假设它们会支持哪些压缩方法。您可能知道您的所有流量都流向支持(例如)gzip 的网络浏览器 - 但您不知道其中有多少使用脑损伤的 AV 软件或其他代理来调解连接。因此,如果您将缓存的表示保持为压缩状态,则需要重新实现围绕检测客户端功能的逻辑并允许在代码中解压缩。

命名模式仅容纳单个页面/缓存文件,而不是表明您没有大量数据要存储在服务器端缓存中,并且磁盘空间很便宜。存储未压缩的缓存数据。

ExpiresByType text/html "访问加 0 秒"

这充其量是多余的。

$cachefile = '缓存文件/'.date('MdY').'.php';

如果你没有非常小心地防止 XSS,你可能会遇到一个巨大的安全问题 - XSS 漏洞可以用作服务器上的远程代码注入漏洞。

包括($缓存文件);

如果您知道该文件应该只包含 HTML,那么您为什么要求 PHP 解析/编译/执行它?除了安全问题之外,它还会产生处理开销,并将导致您的操作码缓存不断填充和重置。

还有人在写入缓存文件之前通过拔出请求的插件来破坏您的缓存的风险。

考虑:

 <?php
 ignore_user_abort(1);
 ...
 if (file_exists($cachefile) && time() - $cachetime < filemtime($cachefile)) 
 {
     while (ob_get_level()) ob_end_flsuh();
     readfile($cachefile);
     exit;
 }
 ...

推荐阅读