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程序中的常见漏洞进行攻击(下)
Oct 09 PHP
PHP连接MongoDB示例代码
Sep 06 PHP
基于header的一些常用指令详解
Jun 06 PHP
解析smarty 截取字符串函数 truncate的用法介绍
Jun 20 PHP
php使用json_encode对变量json编码
Apr 07 PHP
PHP开发微信支付的代码分享
May 25 PHP
教你php如何实现验证码
Jan 20 PHP
PHP CURL post数据报错 failed creating formpost data
Oct 16 PHP
ThinkPHP 3.2.2实现事务操作的方法
May 05 PHP
php注册系统和使用Xajax即时验证用户名是否被占用
Aug 31 PHP
php时间戳转换代码详解
Aug 04 PHP
laravel利用中间件防止未登录用户直接访问后台的方法
Sep 30 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
我的论坛源代码(六)
2006/10/09 PHP
基于Swoole实现PHP与websocket聊天室
2016/08/03 PHP
PHP 使用二进制保存用户状态的实例
2018/01/29 PHP
Laravel中10个有用的用法小结
2019/05/06 PHP
arguments对象
2006/11/20 Javascript
JQuery入门——事件切换之hover()方法应用介绍
2013/02/05 Javascript
.net,js捕捉文本框回车键事件的小例子(兼容多浏览器)
2013/03/11 Javascript
js单例模式的两种方案
2013/10/22 Javascript
jquery实现手机发送验证码的倒计时代码
2014/02/12 Javascript
javascript中html字符串转化为jquery dom对象的方法
2015/08/27 Javascript
jQuery中iframe的操作(点击按钮新增窗口)
2016/04/20 Javascript
jQuery操作iframe中js函数的方法小结
2016/07/06 Javascript
jquery dialog获取焦点的方法
2017/02/09 Javascript
基于Bootstrap的标签页组件及bootstrap-tab使用说明
2017/07/25 Javascript
JS实现浏览上传文件的代码
2017/08/23 Javascript
Vue.js组件通信的几种姿势
2017/10/23 Javascript
javascript面向对象程序设计实践常用知识点总结
2019/07/29 Javascript
JS如何实现网站中PC端和手机端自动识别并跳转对应的代码
2020/01/08 Javascript
原生js+ajax分页组件
2020/01/30 Javascript
python如何获取当前文件夹下所有文件名详解
2019/01/25 Python
Python修改文件往指定行插入内容的实例
2019/01/30 Python
Django使用Jinja2模板引擎的示例代码
2019/08/09 Python
python程序中的线程操作 concurrent模块使用详解
2019/09/23 Python
Django框架获取form表单数据方式总结
2020/04/22 Python
python将数据插入数据库的代码分享
2020/08/16 Python
CSS3结构性伪类选择器九种写法
2012/04/18 HTML / CSS
洲际酒店集团美国官网:IHG美国
2017/11/16 全球购物
英国Office鞋店德国网站:在线购买鞋子、靴子和运动鞋
2018/12/19 全球购物
缓刑人员的思想汇报
2014/01/11 职场文书
高二政治教学反思
2014/02/01 职场文书
创建青年文明号材料
2014/05/09 职场文书
党的群众路线教育实践活动个人对照检查材料(教师)
2014/11/04 职场文书
宿舍管理制度范本
2015/08/07 职场文书
mysql数据库入门第一步之创建表
2021/05/14 MySQL
深入浅析Redis 集群伸缩原理
2021/05/15 Redis
python模拟浏览器 使用selenium进入好友QQ空间并留言
2022/04/12 Python