欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2024-02-29 10:20:52
本文实例讲述了php实现压缩合并js的方法。分享给大家供大家参考,具体如下: test.php文件如下: require_once('jsmin.php');...

本文实例讲述了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目录操作技巧汇总》、《php基本语法入门教程》、《php运算与运算符用法总结》、《php面向对象程序设计入门教程》、《php网络编程技巧总结》、《php字符串(string)用法总结》、《php数组(array)操作技巧大全》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总

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