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 之 没有mysql支持时的替代方案
Oct 09 PHP
新手配置 PHP 调试环境(IIS+PHP+MYSQL)
Jan 10 PHP
PHP 变量的定义方法
Jan 26 PHP
php在线代理转向代码
May 05 PHP
php页面消耗内存过大的处理办法
Mar 18 PHP
php 验证码(倾斜,正弦干扰线,黏贴,旋转)
Jun 29 PHP
php header功能的使用
Oct 28 PHP
通过curl模拟post和get方式提交的表单类
Apr 23 PHP
dedecms中使用php语句指南
Nov 13 PHP
Yii模型操作之criteria查找数据库的方法
Jul 15 PHP
phpstorm 配置xdebug的示例代码
Mar 31 PHP
PHP SESSION跨页面传递失败解决方案
Dec 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
一个基于PDO的数据库操作类(新) 一个PDO事务实例
2011/07/03 PHP
ThinkPHP多表联合查询的常用方法
2020/03/24 PHP
将CMYK颜色值和RGB颜色相互转换的PHP代码
2014/07/28 PHP
分享PHP守护进程类
2015/12/30 PHP
php版阿里云OSS图片上传类详解
2016/12/01 PHP
PHP count_chars()函数讲解
2019/02/14 PHP
JavaScript使用prototype定义对象类型(转)[
2006/12/22 Javascript
理解Javascript_01_理解内存分配原理分析
2010/10/11 Javascript
jquery 结合C#后台的数组对文章的关键字自动添加链接的代码
2011/07/15 Javascript
Jquery多选框互相内容交换的实例代码
2013/07/04 Javascript
jquery ajax请求方式与提示用户正在处理请稍等
2014/09/01 Javascript
javascript常用方法汇总
2014/12/02 Javascript
angularJS中router的使用指南
2015/02/09 Javascript
jQuery下拉美化搜索表单效果代码分享
2015/08/25 Javascript
javascript检测移动设备横竖屏
2016/05/21 Javascript
js倒计时小实例(多次定时)
2016/12/08 Javascript
微信小程序 两种滑动方式(横向滑动,竖向滑动)详细及实例代码
2017/01/13 Javascript
Javascript中引用类型传递的知识点小结
2017/03/06 Javascript
Vue组件通信之Bus的具体使用
2017/12/28 Javascript
Node.js API详解之 module模块用法实例分析
2020/05/13 Javascript
[40:19]2018完美盛典CS.GO表演赛
2018/12/17 DOTA
详解Python3.1版本带来的核心变化
2015/04/07 Python
在ironpython中利用装饰器执行SQL操作的例子
2015/05/02 Python
python设计模式大全
2016/06/27 Python
目前最全的python的就业方向
2018/06/05 Python
Python删除n行后的其他行方法
2019/01/28 Python
PyCharm 创建指定版本的 Django(超详图解教程)
2019/06/18 Python
Python Django切换MySQL数据库实例详解
2019/07/16 Python
PyQt5+python3+pycharm开发环境配置教程
2020/03/24 Python
解决Python安装cryptography报错问题
2020/09/03 Python
教师业务学习制度
2014/01/25 职场文书
活动志愿者自荐信
2014/01/27 职场文书
个人剖析材料范文
2014/09/30 职场文书
工厂清洁工岗位职责
2015/02/14 职场文书
2015年学校政教处工作总结
2015/05/26 职场文书
MySQL基础(一)
2021/04/05 MySQL