php实现压缩合并js的方法【附demo源码下载】
程序员文章站
2024-04-02 14:35:22
本文实例讲述了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程序设计有所帮助。
下一篇: php简单压缩css样式示例
推荐阅读