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 相关文章推荐
自动分页的不完整解决方案
Jan 12 PHP
解析PHP计算页面执行时间的实现代码
Jun 18 PHP
php中filter_input函数用法分析
Nov 15 PHP
php rsa加密解密使用详解
Jan 14 PHP
php中使用in_array() foreach array_search() 查找数组是否包含时的性能对比
Apr 14 PHP
PHP设计模式之观察者模式实例
Feb 22 PHP
php远程下载类分享
Apr 13 PHP
Yii2框架制作RESTful风格的API快速入门教程
Nov 08 PHP
Win7环境下Apache连接MySQL提示连接已重置的解决办法
May 09 PHP
PHP实现删除多重数组对象属性并重新赋值的方法
Jun 07 PHP
PHP实现通过strace定位故障原因的方法
Apr 29 PHP
如何通过Apache在本地配置多个虚拟主机
Jul 29 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
PHP关联链接常用代码
2012/11/05 PHP
php实现将任意进制数转换成10进制的方法
2015/04/17 PHP
PHP+AJAX实现投票功能的方法
2015/09/28 PHP
实例介绍PHP中zip_open()函数用法
2019/02/15 PHP
Laravel框架实现简单的学生信息管理平台案例
2019/05/07 PHP
js静态方法与实例方法分析
2011/07/04 Javascript
理解JSON:3分钟课程
2011/10/28 Javascript
JavaScript调试技巧之console.log()详解
2014/03/19 Javascript
浅谈Javascript变量作用域问题
2014/12/16 Javascript
js实现点击左右按钮轮播图片效果实例
2015/01/29 Javascript
jQuery获取DOM节点实例分析(2种方式)
2015/12/15 Javascript
jquery弹出框插件jquery.ui.dialog用法分析
2016/08/20 Javascript
Bootstrap table简单使用总结
2017/02/15 Javascript
Material(包括Material Icon)在Angular2中的使用详解
2018/02/11 Javascript
代码分析vue中如何配置less
2018/09/28 Javascript
JavaScript函数式编程(Functional Programming)箭头函数(Arrow functions)用法分析
2019/05/22 Javascript
Vue中使用Lodop插件实现打印功能的简单方法
2019/12/19 Javascript
JavaScript对象原型链原理解析
2020/01/22 Javascript
JS实现单张或多张图片持续无缝滚动的示例代码
2020/05/10 Javascript
JavaScript基于用户照片姓名生成海报
2020/05/29 Javascript
python服务器与android客户端socket通信实例
2014/11/12 Python
Python 中的 else详解
2016/04/23 Python
Python编程实现的简单神经网络算法示例
2018/01/26 Python
python3.6实现学生信息管理系统
2019/02/21 Python
python flask框架实现传数据到js的方法分析
2019/06/11 Python
Python Django 简单分页的实现代码解析
2019/08/21 Python
python求质数列表的例子
2019/11/24 Python
html5 css3 动态气泡按钮实例演示
2012/12/02 HTML / CSS
诺心蛋糕官网:LE CAKE
2018/08/25 全球购物
英国最大的在线时尚眼镜店:Eyewearbrands
2019/03/12 全球购物
印度电子产品购物网站:Vijay Sales
2021/02/16 全球购物
垃圾回收的优点和原理。并考虑2种回收机制
2016/10/16 面试题
品恩科技软件测试面试题
2014/10/26 面试题
2015年见习期工作总结
2014/12/12 职场文书
2015年暑期社会实践报告
2015/07/13 职场文书
Pandas实现DataFrame的简单运算、统计与排序
2022/03/31 Python