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 不同编码下的字符串长度区分
Sep 26 PHP
php 数学运算验证码实现代码
Oct 11 PHP
在php中判断一个请求是ajax请求还是普通请求的方法
Jun 28 PHP
php中Smarty模板初体验
Aug 08 PHP
php中的路径问题与set_include_path使用介绍
Feb 11 PHP
PHP中如何使用session实现保存用户登录信息
Oct 20 PHP
PHP微信开发之文本自动回复
Jun 23 PHP
php实现微信企业号支付个人的方法详解
Jul 26 PHP
PHP多进程之pcntl_fork的实例详解
Oct 15 PHP
PHP生成随机数的方法总结
Mar 01 PHP
ThinkPHP5.0框架控制器继承基类和自定义类示例
May 25 PHP
PHP实现长轮询消息实时推送功能代码实例讲解
Feb 26 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
[FAQ]PHP中的一些常识:类篇
2006/10/09 PHP
php压缩多个CSS为一个css的代码并缓存
2011/04/21 PHP
ThinkPHP3.1新特性之动态设置自动完成和自动验证示例
2014/06/19 PHP
如何实现php图片等比例缩放
2015/07/28 PHP
Yii2中datetime类的使用
2016/12/17 PHP
Laravel框架模板加载,分配变量及简单路由功能示例
2018/06/11 PHP
PhpStorm+xdebug+postman调试技巧分享
2020/09/15 PHP
jQuery 版本的文本输入框检查器Input Check
2009/07/09 Javascript
Javascript学习笔记5 类和对象
2010/01/11 Javascript
jQuery源码分析-03构造jQuery对象-源码结构和核心函数
2011/11/14 Javascript
Jquery异步请求数据实例代码
2011/12/28 Javascript
Javascript创建自定义对象 创建Object实例添加属性和方法
2012/06/04 Javascript
jquery中常用的SET和GET$(”#msg”).html循环介绍
2013/10/09 Javascript
编写js扩展方法判断一个数组中是否包含某个元素
2013/11/08 Javascript
jquery实现邮箱自动补全功能示例分享
2014/02/17 Javascript
JS实现鼠标箭头变成一个燃烧烛光效果的方法
2015/02/28 Javascript
浅谈Angular中ngModel的$render
2016/10/24 Javascript
JavaScript实现两个select下拉框选项左移右移
2017/03/09 Javascript
详解angularJS自定义指令间的相互交互
2017/07/05 Javascript
vue2.0实现移动端的输入框实时检索更新列表功能
2018/05/08 Javascript
vue-cli安装使用流程步骤详解
2018/11/08 Javascript
JS实现换肤功能的方法实例详解
2019/01/30 Javascript
layui的数据表格+springmvc实现搜索功能的例子
2019/09/28 Javascript
小程序跳转到的H5页面再跳转回跳小程序的方法
2020/03/06 Javascript
vue相关配置文件详解及多环境配置详细步骤
2020/05/19 Javascript
Python中apply函数的用法实例教程
2014/07/31 Python
利用python库在局域网内传输文件的方法
2018/06/04 Python
python将控制台输出保存至文件的方法
2019/01/07 Python
Python连接字符串过程详解
2020/01/06 Python
Django框架models使用group by详解
2020/03/11 Python
html5记忆翻牌游戏实现思路及代码
2013/07/25 HTML / CSS
英国第二大营养品供应商:Vitabiotics
2016/10/01 全球购物
美体小铺英国官网:The Body Shop英国
2017/01/24 全球购物
幼教毕业生自我鉴定
2014/01/12 职场文书
学术会议邀请函范文
2014/01/22 职场文书
CSS实现单选折叠菜单功能
2021/11/01 HTML / CSS