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语法速查表
Jan 02 PHP
PHP+.htaccess实现全站静态HTML文件GZIP压缩传输(一)
Feb 15 PHP
浅析php header 跳转
Jun 17 PHP
php 下载保存文件保存到本地的两种实现方法
Aug 12 PHP
php获取远程图片体积大小的实例
Nov 12 PHP
php实现的Captcha验证码类实例
Sep 22 PHP
PHP中使用匿名函数操作数据库的例子
Nov 17 PHP
ThinkPHP中order()使用方法详解
Apr 19 PHP
Ajax中的JSON格式与php传输过程全面解析
Nov 14 PHP
ThinkPHP实现的rsa非对称加密类示例
May 29 PHP
微信企业转账之入口类分装php代码
Oct 01 PHP
PHP实现通过二维数组键值获取一维键名操作示例
Oct 11 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
Joomla下利用configuration.php存储简单数据
2010/05/19 PHP
php读取图片内容并输出到浏览器的实现代码
2013/08/08 PHP
php导出csv格式数据并将数字转换成文本的思路以及代码分享
2014/06/05 PHP
给ECShop添加最新评论
2015/01/07 PHP
Session 失效的原因汇总及解决丢失办法
2015/09/30 PHP
CI框架教程之优化验证码机制详解【验证码辅助函数】
2019/04/16 PHP
PHP 对象接口简单实现方法示例
2020/04/13 PHP
让iframe框架网页在任何浏览器下自动伸缩
2006/08/18 Javascript
在Iframe中获取父窗口中表单的值(示例代码)
2013/11/22 Javascript
通过JQuery将DIV的滚动条滚动到指定的位置方便自动定位
2014/05/05 Javascript
javascript手工制作悬浮菜单
2015/02/12 Javascript
JavaScript事件学习小结(五)js中事件类型之鼠标事件
2016/06/09 Javascript
Angularjs 自定义服务的三种方式(推荐)
2016/08/02 Javascript
AngularJs bootstrap搭载前台框架——准备工作
2016/09/01 Javascript
利用jQuery插件imgAreaSelect实现图片上传裁剪(同步显示图像位置信息)
2016/12/02 Javascript
AngularJS中ng-options实现下拉列表的数据绑定方法
2018/08/13 Javascript
pm2发布node配置文件ecosystem.json详解
2019/05/15 Javascript
小程序自动化测试的示例代码
2020/08/11 Javascript
Vue this.$router.push(参数)实现页面跳转操作
2020/09/09 Javascript
Python判断直线和矩形是否相交的方法
2015/07/14 Python
微信跳一跳python辅助脚本(总结)
2018/01/11 Python
Django项目中用JS实现加载子页面并传值的方法
2018/05/28 Python
Python实现的网页截图功能【PyQt4与selenium组件】
2018/07/12 Python
通过shell+python实现企业微信预警
2019/03/07 Python
使用pyqt5 tablewidget 单元格设置正则表达式
2019/12/13 Python
HTML5 Canvas API中drawImage()方法的使用实例
2016/03/25 HTML / CSS
IE支持HTML5的解决方法
2009/10/20 HTML / CSS
HTML5的hidden属性兼容老浏览器的方法
2014/04/23 HTML / CSS
AmazeUI中各种的导航式菜单与解决方法
2020/08/19 HTML / CSS
会议接待欢迎词
2014/01/12 职场文书
2014年国庆节庆祝建国65周年比赛演讲稿
2014/09/21 职场文书
四风个人对照检查材料思想汇报(办公室通用版)
2014/10/07 职场文书
医院见习报告范文
2014/11/03 职场文书
Python机器学习之底层实现KNN
2021/06/20 Python
Element实现动态表格的示例代码
2021/08/02 Javascript
python脚本框架webpy的url映射详解
2021/11/20 Python