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 相关文章推荐
用户的详细注册和判断
Oct 09 PHP
PHP iconv 函数转gb2312的bug解决方法
Oct 11 PHP
PHP 用数组降低程序的时间复杂度
Dec 04 PHP
php中全局变量global的使用演示代码
May 18 PHP
解析isset与is_null的区别
Aug 09 PHP
IIS6.0 开启Gzip方法及PHP Gzip函数分享
Jun 08 PHP
PHP实现股票趋势图和柱形图
Feb 07 PHP
PHP使用ODBC连接数据库的方法
Jul 18 PHP
浅析PHP中call user func()函数及如何使用call user func调用自定义函数
Nov 05 PHP
CI配置多数据库访问的方法
Mar 28 PHP
PHP url的pathinfo模式加载不同控制器的简单实现
Aug 12 PHP
java解析json方法总结
May 16 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 定界符 使用技巧
2009/06/14 PHP
PHP 获取文件路径(灵活应用__FILE__)
2013/02/15 PHP
PHP静态调用非静态方法的应用分析
2013/05/02 PHP
php版本的cron定时任务执行器使用实例
2014/08/19 PHP
php文件下载处理方法分析
2015/04/22 PHP
Yii视图CGridView实现操作按钮定义地址示例
2016/07/14 PHP
PHP精确计算功能示例
2016/11/29 PHP
在php7中MongoDB实现模糊查询的方法详解
2017/05/03 PHP
PHP培训要多少钱
2017/06/06 PHP
jquery下为Event handler传递动态参数的代码
2011/01/06 Javascript
JavaScript 代码压缩工具小结
2012/02/27 Javascript
正则表达式中特殊符号及正则表达式的几种方法总结(replace,test,search)
2013/11/26 Javascript
JS获取文本框,下拉框,单选框的值的简单实例
2014/02/26 Javascript
node.js中的http.request方法使用说明
2014/12/14 Javascript
js实现多选项切换导航菜单的方法
2015/02/06 Javascript
javascript实现数独解法
2015/03/14 Javascript
Javascript OOP之面向对象
2016/07/31 Javascript
jquery,js简单实现类似Angular.js双向绑定
2017/01/13 Javascript
js实现兼容PC端和移动端滑块拖动选择数字效果
2017/02/16 Javascript
javascript 取小数点后几位几种方法总结
2017/08/02 Javascript
vue中appear的用法
2017/08/17 Javascript
JavaScript实现短暂提示框功能
2018/04/04 Javascript
非递归的输出1-N的全排列实例(推荐)
2017/04/11 Python
python找出完数的方法
2018/11/12 Python
浅谈numpy中函数resize与reshape,ravel与flatten的区别
2020/06/18 Python
如何清空python的变量
2020/07/05 Python
python matlab库简单用法讲解
2020/12/31 Python
英文版网络工程师求职信
2013/10/28 职场文书
司仪主持词两篇
2014/03/22 职场文书
小学语文教研活动总结
2014/07/01 职场文书
大学新生军训自我鉴定
2014/09/18 职场文书
医院领导班子查摆问题对照检查材料思想汇报
2014/10/08 职场文书
幸福终点站观后感
2015/06/04 职场文书
2015年幼儿园国庆节活动总结
2015/07/30 职场文书
2015年终个人政治思想工作总结
2015/11/24 职场文书
MySQL 隔离数据列和前缀索引的使用总结
2021/05/14 MySQL