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 相关文章推荐
Win2003服务器安全加固设置--进一步提高服务器安全性
May 23 PHP
PHP 加密/解密函数 dencrypt(动态密文,带压缩功能,支持中文)
Jan 30 PHP
php adodb操作mysql数据库
Mar 19 PHP
PHP迅雷、快车、旋风下载专用链转换代码
Jun 15 PHP
重新封装zend_soap实现http连接安全认证的php代码
Jan 12 PHP
ThinkPHP2.0读取MSSQL提示Incorrect syntax near the keyword 'AS'的解决方法
Jun 25 PHP
php禁止浏览器使用缓存页面的方法
Nov 07 PHP
php生成酷炫的四个字符验证码
Apr 22 PHP
PHP实现阿里大鱼短信验证的实例代码
Jul 10 PHP
PHP使用PDO访问oracle数据库的步骤详解
Sep 29 PHP
php给数组赋值的实例方法
Sep 26 PHP
PHP下载文件函数与用法示例
Sep 27 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构造函数实例讲解
2013/11/13 PHP
PHP实现把MySQL数据库导出为.sql文件实例(仿PHPMyadmin导出功能)
2014/05/10 PHP
PHP获取表单数据与HTML嵌入PHP脚本的实现
2017/02/09 PHP
php获取网站根目录物理路径的几种方法(推荐)
2017/03/04 PHP
利用JQuery为搜索栏增加tag提示
2009/06/22 Javascript
JavaScript和JQuery实用代码片段(一)
2010/04/07 Javascript
基于jQuery实现最基本的淡入淡出效果实例
2015/02/02 Javascript
谈谈我对JavaScript原型和闭包系列理解(随手笔记9)
2015/12/24 Javascript
Ajax的概述与实现过程
2016/11/18 Javascript
jQuery轻松实现无缝轮播效果
2017/03/22 jQuery
jfinal与bootstrap的登出实战详解
2017/11/27 Javascript
karma+webpack搭建vue单元测试环境的方法示例
2018/05/24 Javascript
vue2.0$nextTick监听数据渲染完成之后的回调函数方法
2018/09/11 Javascript
关于vue里页面的缓存详解
2019/11/04 Javascript
ES2020系列之空值合并运算符 '??'
2020/07/22 Javascript
Vue自定义多选组件使用详解
2020/09/08 Javascript
js canvas实现俄罗斯方块
2020/10/11 Javascript
[57:28]2018DOTA2亚洲邀请赛 4.6 淘汰赛 TNC vs Liquid 第一场
2018/04/10 DOTA
Python语言的12个基础知识点小结
2014/07/10 Python
python处理二进制数据的方法
2015/06/03 Python
在django中使用自定义标签实现分页功能
2017/07/04 Python
python3.6 +tkinter GUI编程 实现界面化的文本处理工具(推荐)
2017/12/20 Python
解决django的template中如果无法引用MEDIA_URL问题
2020/04/07 Python
Python学习之os模块及用法
2020/06/03 Python
python中return不返回值的问题解析
2020/07/22 Python
Html5 Geolocation获取地理位置信息实例
2016/12/09 HTML / CSS
美国环保婴儿用品公司:The Honest Company
2017/11/23 全球购物
介绍一下SQL注入攻击的种类和防范手段
2012/02/18 面试题
学前教育专业求职信
2014/09/02 职场文书
甲乙双方合作协议书
2014/10/13 职场文书
运动会开幕式通讯稿
2015/07/18 职场文书
2017大学生寒假社会实践心得体会
2016/01/14 职场文书
写给消防战士们的一封慰问信
2019/10/07 职场文书
Linux安装Nginx步骤详解
2021/03/31 Servers
详解redis分布式锁的这些坑
2021/05/19 Redis
SpringBoot快速入门详解
2021/07/21 Java/Android