压缩并缩小PHP缓存页面

I am using the following page caching technique as described here and shown below:

<?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();
?>

That all works fine but I want to compress and minify the cached file.

I've added ob_gzhandler onto;

ob_start( 'ob_gzhandler' );

And have an htaccess file containing the following:

<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>

Yet when I use any online tools to check gzip compression they all come back No. Am I missing something?

Is there also a way to minify the cached HTML contained in ob_get_contents?

1个回答

There are a lot of issues with what you are doing here.

Normally the Apache config you've shown us here should handle the compression - but that is dependent on the order in which the handlers are stacked. Given the complication of having to deal with generating content for the current request, the output buffer and replaying a stored file, your life will be a lot simpler if your PHP code simply ignores the compression and this is handled by the webserver. So start trying to analyse one problem at a time: look at what the webserver is responding with when you request simple PHP generated HTML. If it's not compressed then go back and have a look at your webserver (did you check if mod_delfate is actually loaded successfuly?).

Compress and Minify a PHP Cached Page

Compression works by reducing redundancy. Minification works by reducing redundancy. Compression will reduce the size by around 80%. Unless your HTML contains a LOT of redundant tags (i.e. "<tag></tag>") AND your minifier is smart enough to identify and remove these (none I've seen can) OR a huge amount of whitespace, minification will only reduce the size by up to 5%. The effects are not additive.

You are adding a lot of cost (processing, programming) and complexity to your code using both and won't see any great benefit as a result.

Is there also a way to minify the cached HTML

That would be silly.

You can't assume that clients will accept compressed content nor which compression methods they will support. You may know that all your traffic is to web browsers which support (say) gzip - but you don't know how many of them are using brain damaged AV software or some other proxy to mediate the connection. So if you maintain the cached representation compressed you need to re-implement the logic around detecting the client capability and allow for decompression in your code.

That the naming schema only accomodates a singe page/cache file rather suggests that you don't have a huge amount of data to store in your serverside cache, and disk space is cheap. Store the cache data uncompressed.

ExpiresByType text/html "access plus 0 seconds"

This is, at best, redundant.

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

You could have a huge security issue here if you are not being really careful to prevent XSS - an XSS vulnerability can be used as a remote code injection exploit on your server.

include($cachefile);

If you know that the file should only contain HTML then why are you asking PHP to parse/compile/execute it? In addition to the security issue it creates a processing overhead and will cause your opcode cache to keep filling up and resetting.

There's also a risk of someone corrupting your cache by pulling the plug on the request before the cache file is written.

Consider:

 <?php
 ignore_user_abort(1);
 ...
 if (file_exists($cachefile) && time() - $cachetime < filemtime($cachefile)) 
 {
     while (ob_get_level()) ob_end_flsuh();
     readfile($cachefile);
     exit;
 }
 ...
dongta5621
dongta5621 它不会阻止XSS(跨站点脚本) - 使用include()而不是readfile()意味着如果存在XSS漏洞,则可以利用它来运行服务器上的代码。
接近 2 年之前 回复
doulaobi7988
doulaobi7988 感谢您回复我,并提供如此深入的信息。 非常感谢。 我没有意识到那里存在潜在的XXS漏洞,这是压缩/缩小之外的最大问题。 缓存的文件将始终为HTML。 你的最后一个使用readFile的代码片段包括 - while(ob_get_level())ob_end_flush(); ReadFile的($求CacheFile); ......防止XSS会走多远?
接近 2 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐