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 相关文章推荐
第1次亲密接触PHP5(1)
Oct 09 PHP
php 多个submit提交表单 处理方法
Jul 07 PHP
PHP中foreach循环中使用引用要注意的地方
Jan 02 PHP
深入PHP内存相关的功能特性详解
Jun 08 PHP
测试php连接mysql是否成功的代码分享
Jan 24 PHP
百度ping方法使用示例 自动ping百度
Jan 26 PHP
PHP的数组中提高元素查找与元素去重的效率的技巧解析
Mar 03 PHP
简单概括PHP的字符串中单引号与双引号的区别
May 07 PHP
PHP isset()与empty()的使用区别详解
Feb 10 PHP
thinkPHP+phpexcel实现excel报表输出功能示例
Jun 06 PHP
启用OPCache提高PHP程序性能的方法
Mar 21 PHP
PHP7中I/O模型内核剖析详解
Apr 14 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
全国FM电台频率大全 - 6 辽宁省
2020/03/11 无线电
php版本的cron定时任务执行器使用实例
2014/08/19 PHP
yii2中LinkPager增加总页数和总记录数的实例
2017/08/28 PHP
33个优秀的 jQuery 图片展示插件分享
2012/03/14 Javascript
详解JavaScript语法对{}处理的坑爹之处
2014/06/05 Javascript
JS 在指定数组中随机取出N个不重复的数据
2014/06/10 Javascript
Nodejs Post请求报socket hang up错误的解决办法
2014/09/25 NodeJs
node.js中的http.createClient方法使用说明
2014/12/15 Javascript
BootStrap框架个人总结(bootstrap框架、导航条、下拉菜单、轮播广告carousel、栅格系统布局、标签页tabs、模态框、菜单定位)
2016/12/01 Javascript
解析预加载显示图片艺术
2016/12/05 Javascript
Angular实现购物车计算示例代码
2017/02/21 Javascript
Bootstrap的Carousel配合dropload.js实现移动端滑动切换图片
2017/03/10 Javascript
详解webpack 入门总结和实践(按需异步加载,css单独打包,生成多个入口文件)
2017/06/20 Javascript
微信小程序实现折叠面板
2018/01/31 Javascript
AngularJS与后端php的数据交互方法
2018/08/13 Javascript
微信小程序实现购物页面左右联动
2019/02/15 Javascript
JS实现集合的交集、补集、差集、去重运算示例【ES5与ES6写法】
2019/02/18 Javascript
JavaScript遍历数组的三种方法map、forEach与filter实例详解
2019/02/27 Javascript
layui实现下拉框三级联动
2019/07/26 Javascript
微信小程序引入模块中wxml、wxss、js的方法示例
2019/08/09 Javascript
使用layui 的layedit定义自己的toolbar方法
2019/09/18 Javascript
线程和进程的区别及Python代码实例
2015/02/04 Python
Python读取数据集并消除数据中的空行方法
2018/07/12 Python
详解Python Matplot中文显示完美解决方案
2019/03/07 Python
python try except返回异常的信息字符串代码实例
2019/08/15 Python
Python Django模板之模板过滤器与自定义模板过滤器示例
2019/10/18 Python
python2.7使用scapy发送syn实例
2020/05/05 Python
一款超酷的js+css3实现的3D标签云特效兼容ie7/8/9
2013/11/18 HTML / CSS
关于Java finally的面试题
2016/04/27 面试题
老教师工作总结的自我评价
2013/09/27 职场文书
销售演讲稿范文
2014/01/08 职场文书
大学生职业生涯规划范文
2014/01/22 职场文书
员工年终自我评价
2014/09/14 职场文书
2015感人爱情寄语
2015/02/26 职场文书
公司董事任命书
2015/09/21 职场文书
使用Python的开发框架Brownie部署以太坊智能合约
2021/05/28 Python