douren9077 2019-01-11 11:02
浏览 148

压缩并缩小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条回答

  • drwurqczo39355510 2019-01-11 12:43
    关注

    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;
     }
     ...
    
    评论

报告相同问题?

悬赏问题

  • ¥50 永磁型步进电机PID算法
  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥200 uniapp长期运行卡死问题解决
  • ¥15 latex怎么处理论文引理引用参考文献
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?
  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?