php使用gzip压缩传输js和css文件的方法


Posted in PHP onJuly 29, 2015

本文实例讲述了php使用gzip压缩传输js和css文件的方法。分享给大家供大家参考。具体如下:

<?php
  /**
   * 完整调用示例:
   * 1、combine.php?t=j&b=public&fs=jslib.jquery,function
   * 
   * 该例子调用的是网站根目录下的public/jslib/jquery.js和public/function.js
   * 
   * 2、combine.php?t=j&fs=jslib.jquery,function
   * 
   * 该例子调用的是网站根目录下的jslib/jquery.js和function.js
   * 
   * 3、combine.php?t=c&b=public.css&fs=common,index
   * 
   * 该例子调用的是网站根目录下的public/css/common.css和public/css/index.css
   * 
   * 4、combine.php?t=c&fs=css.common
   * 该例子调用的是网站根目录下的css/common.css
   * 
   * 注:多个文件名之间用,分隔;只有一个文件名最后不要有,
   *   用,分隔的多个文件会被压缩进一个文件,一次性传给浏览器
   **/
  $is_bad_request=false;
  $cache = true;
  $doc_root_uri=$_SERVER['DOCUMENT_ROOT'].'/';
  $cachedir = $doc_root_uri . 'public/cache';
  //文件类型,j为js,c为css
  $type=isset($_GET['t'])?($_GET['t']=='j'||$_GET['t']=='c'?$_GET['t']:''):'';
  //存放js和css文件的基目录, 例如:?b=public.js 代表的是/public/js文件夹,出发点是网站根目录
  //基目录参数不是必须的,如果有基目录那么这个基目录就会附加在文件名之前
  $base =isset($_GET['b'])?($doc_root_uri.str_replace('.','/',$_GET['b'])):$doc_root_uri;
  //文件名列表,文件名不带后缀名.比如基目录是
  //文件名的格式是 :基目录(如果有)+文件包名+文件名
  //例如:类型是j,
  //   文件名public.js.jquery
  //   如果有基路径且为public,
  //   那么转换后的文件名就是/public/public/js/jquery.js
  //   如果没有基路径
  //   那么转换后的文件名就是/public/js/jquery.js
  //多个文件名之间用,分隔
  $fs=isset($_GET['fs'])?str_replace('.','/',$_GET['fs']):'';
  $fs=str_replace(',','.'.($type=='j'?'js,':'css,'),$fs);
  $fs=$fs.($type=='j'?'.js':'.css');
  if($type==''||$fs==''){$is_bad_request=true;}
  //die($base);
  if($is_bad_request){header ("HTTP/1.0 503 Not Implemented");}
  $file_type=$type=='j'?'javascript':'css';
  $elements = explode(',',preg_replace('/([^?]*).*/', '\1', $fs));
  // Determine last modification date of the files
  $lastmodified = 0;
  while (list(,$element) = each($elements)) {
    $path =$base . '/' . $element;
    if (($type == 'j' && substr($path, -3) != '.js') || 
      ($type == 'c' && substr($path, -4) != '.css')) {
      header ("HTTP/1.0 403 Forbidden");
      exit;  
    }
    if (substr($path, 0, strlen($base)) != $base || !file_exists($path)) {
      header ("HTTP/1.0 404 Not Found");
      exit;
    }
    $lastmodified = max($lastmodified, filemtime($path));
  }
  // Send Etag hash
  $hash = $lastmodified . '-' . md5($fs);
  header ("Etag: \"" . $hash . "\"");
  if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && 
    stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) == '"' . $hash . '"') 
  {
    // Return visit and no modifications, so do not send anything
    header ("HTTP/1.0 304 Not Modified");
    header ("Content-Type: text/" . $file_type);
    header ('Content-Length: 0');
  } 
  else
  {
    // First time visit or files were modified
    if ($cache) 
    {
      // Determine supported compression method
      $gzip = strstr($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip');
      $deflate = strstr($_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate');
      // Determine used compression method
      $encoding = $gzip ? 'gzip' : ($deflate ? 'deflate' : 'none');
      // Check for buggy versions of Internet Explorer
      if (!strstr($_SERVER['HTTP_USER_AGENT'], 'Opera') && 
        preg_match('/^Mozilla\/4\.0 \(compatible; MSIE ([0-9]\.[0-9])/i', $_SERVER['HTTP_USER_AGENT'], $matches)) {
        $version = floatval($matches[1]);
        if ($version < 6)
          $encoding = 'none';
        if ($version == 6 && !strstr($_SERVER['HTTP_USER_AGENT'], 'EV1')) 
          $encoding = 'none';
      }
      // Try the cache first to see if the combined files were already generated
      $cachefile = 'cache-' . $hash . '.' . $file_type . ($encoding != 'none' ? '.' . $encoding : '');
      if (file_exists($cachedir . '/' . $cachefile)) {
        if ($fp = fopen($cachedir . '/' . $cachefile, 'rb')) {
          if ($encoding != 'none') {
            header ("Content-Encoding: " . $encoding);
          }
          header ("Content-Type: text/" . $file_type);
          header ("Content-Length: " . filesize($cachedir . '/' . $cachefile));
          fpassthru($fp);
          fclose($fp);
          exit;
        }
      }
    }
    // Get contents of the files
    $contents = '';
    reset($elements);
    while (list(,$element) = each($elements)) {
      $path = $base . '/' . $element;
      $contents .= "\n\n" . file_get_contents($path);
    }
    // Send Content-Type
    header ("Content-Type: text/" . $file_type);
    if (isset($encoding) && $encoding != 'none') 
    {
      // Send compressed contents
      $contents = gzencode($contents, 9, $gzip ? FORCE_GZIP : FORCE_DEFLATE);
      header ("Content-Encoding: " . $encoding);
      header ('Content-Length: ' . strlen($contents));
      echo $contents;
    } 
    else
    {
      // Send regular contents
      header ('Content-Length: ' . strlen($contents));
      echo $contents;
    }
    // Store cache
    if ($cache) {
      if ($fp = fopen($cachedir . '/' . $cachefile, 'wb')) {
        fwrite($fp, $contents);
        fclose($fp);
      }
    }
  }

希望本文所述对大家的php程序设计有所帮助。

PHP 相关文章推荐
php的access操作类
Apr 09 PHP
php数组应用之比较两个时间的相减排序
Aug 18 PHP
php设计模式 Singleton(单例模式)
Jun 26 PHP
php页面缓存ob系列函数介绍
Oct 18 PHP
Function eregi is deprecated (解决方法)
Jun 21 PHP
如何在Ubuntu下启动Apache的Rewrite功能
Jul 05 PHP
php强制文件下载而非在浏览器打开的自定义函数分享
May 08 PHP
跟我学Laravel之视图 &amp; Response
Oct 15 PHP
php中 ob_start等函数截取标准输出的方法
Jun 22 PHP
PHP使用星号隐藏用户名,手机和邮箱的实现方法
Sep 22 PHP
PHP魔术方法之__call与__callStatic使用方法
Jul 23 PHP
PHP语言对接抖音快手小红书视频/图片去水印API接口源码
Aug 11 PHP
PHP实现加强版加密解密类实例
Jul 29 #PHP
PHP之密码加密的几种方式
Jul 29 #PHP
PHP实现仿Google分页效果的分页函数
Jul 29 #PHP
PHP如何将log信息写入服务器中的log文件
Jul 29 #PHP
再Docker中架设完整的WordPress站点全攻略
Jul 29 #PHP
php去掉文件前几行的方法
Jul 29 #PHP
PHP实现的简单网络硬盘
Jul 29 #PHP
You might like
在WIN98下以apache模块方式安装php
2006/10/09 PHP
php操作路径的经典方法(必看篇)
2016/10/04 PHP
怎么让脚本或里面的函数在所有图片都载入完毕的时候执行
2006/10/17 Javascript
开发跨浏览器javascript常见注意事项
2009/01/01 Javascript
JavaScript 输入框内容格式验证代码
2010/02/11 Javascript
高亮显示web页表格行的javascript代码
2010/11/19 Javascript
jQuery 下拉列表 二级联动插件分享
2012/03/29 Javascript
javascript实现页面刷新时自动清空表单并选中的方法
2015/07/18 Javascript
JS实现的5级联动Select下拉选择框实例
2015/08/17 Javascript
jquery实现鼠标点击后展开列表内容的导航栏效果
2015/09/14 Javascript
JavaScript计划任务后台运行的方法
2015/12/18 Javascript
使用递归遍历对象获得value值的实现方法
2016/06/14 Javascript
js实现可键盘控制的简单抽奖程序
2016/07/13 Javascript
自己封装的一个简单的倒计时功能实例
2016/11/23 Javascript
JQuery实现动态操作表格
2017/01/11 Javascript
Angular2 PrimeNG分页模块学习
2017/01/14 Javascript
微信小程序  http请求封装详解及实例代码
2017/02/15 Javascript
JS简单实现数组去重的方法示例
2017/03/27 Javascript
vue下history模式刷新后404错误解决方法
2018/08/18 Javascript
从Vuex中取出数组赋值给新的数组,新数组push时报错的解决方法
2018/09/18 Javascript
Vue js 的生命周期(看了就懂)(推荐)
2019/03/29 Javascript
vue-cli history模式实现tomcat部署报404的解决方式
2019/09/06 Javascript
vue 避免变量赋值后双向绑定的操作
2020/11/07 Javascript
Python基础之函数用法实例详解
2014/09/10 Python
深入解析Python中的变量和赋值运算符
2015/10/12 Python
简介Python设计模式中的代理模式与模板方法模式编程
2016/02/02 Python
pandas抽取行列数据的几种方法
2020/12/13 Python
年会搞笑主持词
2014/03/27 职场文书
音乐兴趣小组活动总结
2014/07/07 职场文书
装修活动策划方案
2014/08/27 职场文书
学习计划书怎么写
2014/09/15 职场文书
群众路线剖析材料
2014/09/30 职场文书
行政处罚告知书
2015/07/01 职场文书
导游词之襄阳古城
2019/09/27 职场文书
《天净沙·秋思》教学反思三篇
2019/11/02 职场文书
浅谈JavaScript浅拷贝和深拷贝
2021/11/07 Javascript