php实现压缩合并js的方法【附demo源码下载】


Posted in PHP onSeptember 22, 2016

本文实例讲述了php实现压缩合并js的方法。分享给大家供大家参考,具体如下:

test.php文件如下:

require_once('jsmin.php');
$files = glob("js/*.js");
$js = "";
foreach($files as $file) {
  $js .= JSMin::minify(file_get_contents($file));
}
file_put_contents("combined.js", $js);
echo "success";

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 相关文章推荐
php对gzip文件或者字符串解压实例参考
Jul 25 PHP
phpmyadmin 3.4 空密码登录的实现方法
May 29 PHP
php中转义mysql语句的实现代码
Jun 24 PHP
PHP中文分词的简单实现代码分享
Jul 17 PHP
基于PHP array数组的教程详解
Jun 05 PHP
php while循环得到循环次数
Oct 26 PHP
PHP实现指定字段的多维数组排序函数分享
Mar 09 PHP
PHP比较运算符的详细介绍
Sep 29 PHP
PHP在线书签系统分享
Jan 04 PHP
PHP实现十进制、二进制、八进制和十六进制转换相关函数用法分析
Apr 25 PHP
PHP 二维array转换json的实例讲解
Aug 21 PHP
TP5(thinkPHP5)框架基于ajax与后台数据交互操作简单示例
Sep 03 PHP
php简单压缩css样式示例
Sep 22 #PHP
php 伪造HTTP_REFERER页面URL来源的三种方法
Sep 22 #PHP
PHP mysqli_free_result()与mysqli_fetch_array()函数详解
Sep 21 #PHP
Yii2.0 Basic代码中路由链接被转义的处理方法
Sep 21 #PHP
php5.2的curl-bug 服务器被php进程卡死问题排查
Sep 19 #PHP
php支付宝在线支付接口开发教程
Sep 19 #PHP
iOS10推送通知开发教程
Sep 19 #PHP
You might like
关于crontab的使用详解
2013/06/24 PHP
Zend Framework教程之Loader以及PluginLoader用法详解
2016/03/09 PHP
比较完整的微信开发php代码
2016/08/02 PHP
php实现的pdo公共类定义与用法示例
2017/07/19 PHP
PHP实现提取多维数组指定一列的方法总结
2019/12/04 PHP
javascript &amp;&amp;和||运算法的另类使用技巧
2009/11/28 Javascript
分享27款非常棒的jQuery 表单插件
2011/03/28 Javascript
Jquery创建一个层当鼠标移动到层上面不消失效果
2013/12/12 Javascript
jQuery中get()方法用法实例
2014/12/27 Javascript
jQuery超简单选项卡完整实例
2015/09/26 Javascript
js实现搜索框关键字智能匹配代码
2020/03/26 Javascript
jQuery表格插件datatables用法详解
2020/11/23 Javascript
利用Vue.js指令实现全选功能
2016/09/08 Javascript
AnjularJS中$scope和$rootScope的区别小结
2016/09/18 Javascript
vue组件父与子通信详解(一)
2017/11/07 Javascript
在React 组件中使用Echarts的示例代码
2017/11/08 Javascript
JS监听滚动和id自动定位滚动
2018/12/18 Javascript
Webpack4+Babel7+ES6兼容IE8的实现
2019/04/10 Javascript
js实现无缝滚动双图切换效果
2019/07/09 Javascript
解决nuxt 自定义全局方法,全局属性,全局变量的问题
2020/11/05 Javascript
[04:09]显微镜下的DOTA2第十二期—NaVi美如画的团战
2014/06/23 DOTA
[01:05]DOTA2完美大师赛趣味视频之选手教你打职业
2017/11/23 DOTA
Python中你应该知道的一些内置函数
2017/03/31 Python
Python 利用pydub库操作音频文件的方法
2019/01/09 Python
详解如何用TensorFlow训练和识别/分类自定义图片
2019/08/05 Python
美国婴儿和儿童家具网上商店:ABaby.com
2018/07/02 全球购物
EMU Australia澳大利亚官网:澳大利亚本土雪地靴品牌
2019/07/24 全球购物
简单的JAVA编程面试题
2013/03/19 面试题
教师党员思想汇报
2014/01/06 职场文书
离职证明标准格式
2014/09/15 职场文书
2015年南京大屠杀纪念日活动总结
2015/03/24 职场文书
给校长的建议书作文500字
2015/09/14 职场文书
二年级作文之动物作文
2019/11/13 职场文书
浅谈Python 中的复数问题
2021/05/19 Python
MySQL删除和插入数据很慢的问题解决
2021/06/03 MySQL
解决linux下redis数据库overcommit_memory问题
2022/02/24 Redis