php实现压缩多个CSS与JS文件的方法


Posted in PHP onNovember 11, 2014

本文实例讲述了php实现压缩多个CSS与JS文件的方法。分享给大家供大家参考。具体实现方法如下:

1. 压缩css

<?php    

header('Content-type: text/css');    

ob_start("compress");    

function compress($buffer) {    

    /* remove comments */    

    $buffer = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $buffer);    

    /* remove tabs, spaces, newlines, etc. */    

    $buffer = str_replace(array("\r\n", "\r", "\n", "\t", '  ', '    ', '    '), '', $buffer);    

    return $buffer;    

}      

    

/* your css files */    

include('galleria.css');    

include('articles.css');    

    

ob_end_flush();

使用方法如下:
<link href="compress.php" rel="stylesheet" type="text/css" /><span id="tester">test</span>

2. 压缩js,利用jsmin类:

本实例源自:http://code.google.com/p/minify/

header('Content-type: text/javascript');    

require 'jsmin.php';    

echo JSMin::minify(file_get_contents('common.js') . file_get_contents('common2.js'));

其中jsmin.php文件如下:

<?php

/**

 * jsmin.php - PHP implementation of Douglas Crockford's JSMin.

 *

 * This is pretty much a direct port of jsmin.c to PHP with just a few

 * PHP-specific performance tweaks. Also, whereas jsmin.c reads from stdin and

 * outputs to stdout, this library accepts a string as input and returns another

 * string as output.

 *

 * PHP 5 or higher is required.

 *

 * Permission is hereby granted to use this version of the library under the

 * same terms as jsmin.c, which has the following license:

 *

 * --

 * Copyright (c) 2002 Douglas Crockford  (www.crockford.com)

 *

 * Permission is hereby granted, free of charge, to any person obtaining a copy of

 * this software and associated documentation files (the "Software"), to deal in

 * the Software without restriction, including without limitation the rights to

 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies

 * of the Software, and to permit persons to whom the Software is furnished to do

 * so, subject to the following conditions:

 *

 * The above copyright notice and this permission notice shall be included in all

 * copies or substantial portions of the Software.

 *

 * The Software shall be used for Good, not Evil.

 *

 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE

 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE

 * SOFTWARE.

 * --

 *

 * @package JSMin

 * @author Ryan Grove <ryan@wonko.com>

 * @copyright 2002 Douglas Crockford <douglas@crockford.com> (jsmin.c)

 * @copyright 2008 Ryan Grove <ryan@wonko.com> (PHP port)

 * @copyright 2012 Adam Goforth <aag@adamgoforth.com> (Updates)

 * @license http://opensource.org/licenses/mit-license.php MIT License

 * @version 1.1.2 (2012-05-01)

 * @link https://github.com/rgrove/jsmin-php

 */

class JSMin {

  const ORD_LF            = 10;

  const ORD_SPACE         = 32;

  const ACTION_KEEP_A     = 1;

  const ACTION_DELETE_A   = 2;

  const ACTION_DELETE_A_B = 3;

  protected $a           = '';

  protected $b           = '';

  protected $input       = '';

  protected $inputIndex  = 0;

  protected $inputLength = 0;

  protected $lookAhead   = null;

  protected $output      = '';

  // -- Public Static Methods --------------------------------------------------

  /**

   * Minify Javascript

   *

   * @uses __construct()

   * @uses min()

   * @param string $js Javascript to be minified

   * @return string

   */

  public static function minify($js) {

    $jsmin = new JSMin($js);

    return $jsmin->min();

  }

  // -- Public Instance Methods ------------------------------------------------

  /**

   * Constructor

   *

   * @param string $input Javascript to be minified

   */

  public function __construct($input) {

    $this->input       = str_replace("\r\n", "\n", $input);

    $this->inputLength = strlen($this->input);

  }

  // -- Protected Instance Methods ---------------------------------------------

  /**

   * Action -- do something! What to do is determined by the $command argument.

   *

   * action treats a string as a single character. Wow!

   * action recognizes a regular expression if it is preceded by ( or , or =.

   *

   * @uses next()

   * @uses get()

   * @throws JSMinException If parser errors are found:

   *         - Unterminated string literal

   *         - Unterminated regular expression set in regex literal

   *         - Unterminated regular expression literal

   * @param int $command One of class constants:

   *      ACTION_KEEP_A      Output A. Copy B to A. Get the next B.

   *      ACTION_DELETE_A    Copy B to A. Get the next B. (Delete A).

   *      ACTION_DELETE_A_B  Get the next B. (Delete B).

  */

  protected function action($command) {

    switch($command) {

      case self::ACTION_KEEP_A:

        $this->output .= $this->a;

      case self::ACTION_DELETE_A:

        $this->a = $this->b;

        if ($this->a === "'" || $this->a === '"') {

          for (;;) {

            $this->output .= $this->a;

            $this->a       = $this->get();

            if ($this->a === $this->b) {

              break;

            }

            if (ord($this->a) <= self::ORD_LF) {

              throw new JSMinException('Unterminated string literal.');

            }

            if ($this->a === '\\') {

              $this->output .= $this->a;

              $this->a       = $this->get();

            }

          }

        }

      case self::ACTION_DELETE_A_B:

        $this->b = $this->next();

        if ($this->b === '/' && (

            $this->a === '(' || $this->a === ',' || $this->a === '=' ||

            $this->a === ':' || $this->a === '[' || $this->a === '!' ||

            $this->a === '&' || $this->a === '|' || $this->a === '?' ||

            $this->a === '{' || $this->a === '}' || $this->a === ';' ||

            $this->a === "\n" )) {

          $this->output .= $this->a . $this->b;

          for (;;) {

            $this->a = $this->get();

            if ($this->a === '[') {

              /*

                inside a regex [...] set, which MAY contain a '/' itself. Example: mootools Form.Validator near line 460:

                  return Form.Validator.getValidator('IsEmpty').test(element) || (/^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]\.?){0,63}[a-z0-9!#$%&'*+/=?^_`{|}~-]@(?:(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\])$/i).test(element.get('value'));

              */

              for (;;) {

                $this->output .= $this->a;

                $this->a = $this->get();

                if ($this->a === ']') {

                    break;

                } elseif ($this->a === '\\') {

                  $this->output .= $this->a;

                  $this->a       = $this->get();

                } elseif (ord($this->a) <= self::ORD_LF) {

                  throw new JSMinException('Unterminated regular expression set in regex literal.');

                }

              }

            } elseif ($this->a === '/') {

              break;

            } elseif ($this->a === '\\') {

              $this->output .= $this->a;

              $this->a       = $this->get();

            } elseif (ord($this->a) <= self::ORD_LF) {

              throw new JSMinException('Unterminated regular expression literal.');

            }

            $this->output .= $this->a;

          }

          $this->b = $this->next();

        }

    }

  }

  /**

   * Get next char. Convert ctrl char to space.

   *

   * @return string|null

   */

  protected function get() {

    $c = $this->lookAhead;

    $this->lookAhead = null;

    if ($c === null) {

      if ($this->inputIndex < $this->inputLength) {

        $c = substr($this->input, $this->inputIndex, 1);

        $this->inputIndex += 1;

      } else {

        $c = null;

      }

    }

    if ($c === "\r") {

      return "\n";

    }

    if ($c === null || $c === "\n" || ord($c) >= self::ORD_SPACE) {

      return $c;

    }

    return ' ';

  }

  /**

   * Is $c a letter, digit, underscore, dollar sign, or non-ASCII character.

   *

   * @return bool

   */

  protected function isAlphaNum($c) {

    return ord($c) > 126 || $c === '\\' || preg_match('/^[\w\$]$/', $c) === 1;

  }

  /**

   * Perform minification, return result

   *

   * @uses action()

   * @uses isAlphaNum()

   * @uses get()

   * @uses peek()

   * @return string

   */

  protected function min() {

    if (0 == strncmp($this->peek(), "\xef", 1)) {

        $this->get();

        $this->get();

        $this->get();

    } 

    $this->a = "\n";

    $this->action(self::ACTION_DELETE_A_B);

    while ($this->a !== null) {

      switch ($this->a) {

        case ' ':

          if ($this->isAlphaNum($this->b)) {

            $this->action(self::ACTION_KEEP_A);

          } else {

            $this->action(self::ACTION_DELETE_A);

          }

          break;

        case "\n":

          switch ($this->b) {

            case '{':

            case '[':

            case '(':

            case '+':

            case '-':

            case '!':

            case '~':

              $this->action(self::ACTION_KEEP_A);

              break;

            case ' ':

              $this->action(self::ACTION_DELETE_A_B);

              break;

            default:

              if ($this->isAlphaNum($this->b)) {

                $this->action(self::ACTION_KEEP_A);

              }

              else {

                $this->action(self::ACTION_DELETE_A);

              }

          }

          break;

        default:

          switch ($this->b) {

            case ' ':

              if ($this->isAlphaNum($this->a)) {

                $this->action(self::ACTION_KEEP_A);

                break;

              }

              $this->action(self::ACTION_DELETE_A_B);

              break;

            case "\n":

              switch ($this->a) {

                case '}':

                case ']':

                case ')':

                case '+':

                case '-':

                case '"':

                case "'":

                  $this->action(self::ACTION_KEEP_A);

                  break;

                default:

                  if ($this->isAlphaNum($this->a)) {

                    $this->action(self::ACTION_KEEP_A);

                  }

                  else {

                    $this->action(self::ACTION_DELETE_A_B);

                  }

              }

              break;

            default:

              $this->action(self::ACTION_KEEP_A);

              break;

          }

      }

    }

    return $this->output;

  }

  /**

   * Get the next character, skipping over comments. peek() is used to see

   *  if a '/' is followed by a '/' or '*'.

   *

   * @uses get()

   * @uses peek()

   * @throws JSMinException On unterminated comment.

   * @return string

   */

  protected function next() {

    $c = $this->get();

    if ($c === '/') {

      switch($this->peek()) {

        case '/':

          for (;;) {

            $c = $this->get();

            if (ord($c) <= self::ORD_LF) {

              return $c;

            }

          }

        case '*':

          $this->get();

          for (;;) {

            switch($this->get()) {

              case '*':

                if ($this->peek() === '/') {

                  $this->get();

                  return ' ';

                }

                break;

              case null:

                throw new JSMinException('Unterminated comment.');

            }

          }

        default:

          return $c;

      }

    }

    return $c;

  }

  /**

   * Get next char. If is ctrl character, translate to a space or newline.

   *

   * @uses get()

   * @return string|null

   */

  protected function peek() {

    $this->lookAhead = $this->get();

    return $this->lookAhead;

  }

}

// -- Exceptions ---------------------------------------------------------------

class JSMinException extends Exception {}

?>

希望本文所述对大家的php程序设计有所帮助。

PHP 相关文章推荐
source.php查看源文件
Dec 09 PHP
在Windows系统上安装PHP运行环境文字教程
Jul 19 PHP
php中使用exec,system等函数调用系统命令的方法(不建议使用,可导致安全问题)
Sep 07 PHP
php缓冲 output_buffering的使用详解
Jun 13 PHP
php动态生成函数示例
Mar 21 PHP
30个php操作redis常用方法代码例子
Jul 05 PHP
PHP缓存集成库phpFastCache用法
Dec 15 PHP
简单实现php上传文件功能
Sep 21 PHP
php递归函数怎么用才有效
Feb 24 PHP
PHP+ajax实现上传、删除、修改单张图片及后台处理逻辑操作详解
Feb 12 PHP
PHP实现倒计时功能
Nov 16 PHP
PHP获取真实IP及IP模拟方法解析
Nov 24 PHP
详谈PHP文件目录基础操作
Nov 11 #PHP
浅谈PHP解析URL函数parse_url和parse_str
Nov 11 #PHP
php 魔术方法详解
Nov 11 #PHP
php多个文件及图片上传实例详解
Nov 10 #PHP
PHP文件上传判断file是否己选择上传文件的方法
Nov 10 #PHP
php数组操作之键名比较与差集、交集赋值的方法
Nov 10 #PHP
php json转换成数组形式代码分享
Nov 10 #PHP
You might like
PHP 开发环境配置(Zend Server安装)
2010/04/28 PHP
php park、unpark、ord 函数使用方法(二进制流接口应用实例)
2010/10/19 PHP
php记录日志的实现代码
2011/08/08 PHP
php中Session的生成机制、回收机制和存储机制探究
2014/08/19 PHP
php异步多线程swoole用法实例
2014/11/14 PHP
php遍历替换目录下文件指定内容的方法
2016/11/10 PHP
PHP重置数组为连续数字索引的几种方式总结
2018/03/12 PHP
js loading加载效果实现代码
2009/11/24 Javascript
IE6-IE9不支持table.innerHTML的解决方法分享
2012/09/14 Javascript
用js调用迅雷下载代码的二种方法
2013/04/15 Javascript
js清除input中type等于file的值域(示例代码)
2013/12/24 Javascript
jquery为页面增加快捷键示例
2014/01/31 Javascript
DIV始终居中的js代码
2014/02/17 Javascript
分享JavaScript与Java中MD5使用两个例子
2015/12/23 Javascript
JS实现一次性弹窗的方法【刷新后不弹出】
2016/12/26 Javascript
微信小程序 仿美团分类菜单 swiper分类菜单
2017/04/12 Javascript
浅析Visual Studio Code断点调试Vue
2018/02/27 Javascript
微信小程序云开发(数据库)详解
2019/05/17 Javascript
vue路由传参页面刷新参数丢失问题解决方案
2019/10/08 Javascript
vue3修改link标签默认icon无效问题详解
2019/10/09 Javascript
详解Nuxt.js 实战集锦
2019/11/19 Javascript
[00:55]2015国际邀请赛中国区预选赛5月23日——28日约战上海
2015/05/25 DOTA
Python中的zip函数使用示例
2015/01/29 Python
python使用opencv进行人脸识别
2017/04/07 Python
Python操作mysql数据库实现增删查改功能的方法
2018/01/15 Python
对django中render()与render_to_response()的区别详解
2018/10/16 Python
使用Python的Turtle绘制哆啦A梦实例
2019/11/21 Python
CSS超出文本指定宽度用省略号代替和文本不换行
2016/05/05 HTML / CSS
UGG英国官方网站:UGG UK
2018/02/08 全球购物
体育纪念品、亲笔签名的体育收藏品:Steiner Sports
2020/07/31 全球购物
重阳节登山活动方案
2014/02/03 职场文书
材料物理专业求职信
2014/09/01 职场文书
员工离职通知函
2015/04/25 职场文书
金正昆讲礼仪观后感
2015/06/11 职场文书
2016计算机专业毕业生自荐信
2016/01/28 职场文书
详解Vue3使用axios的配置教程
2022/04/29 Vue.js