本文实例讲述了php实现压缩多个CSS与JS文件的方法。分享给大家供大家参考。具体实现方法如下:
1. 压缩css
代码如下:
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();
使用方法如下:
代码如下:
test
2. 压缩js,利用jsmin类:
本实例源自:https://www.php1.cn/
代码如下:
header('Content-type: text/Javascript');
require 'jsmin.php';
echo JSMin::minify(file_get_contents('common.js') . file_get_contents('common2.js'));
其中jsmin.php文件如下:
代码如下:
* @copyright 2002 Douglas Crockford(jsmin.c) * @copyright 2008 Ryan Grove (PHP port) * @copyright 2012 Adam Goforth (Updates) * @license https://www.php1.cn/ MIT License * @version 1.1.2 (2012-05-01) * @link https://www.php1.cn/ */ 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 = &#39;&#39;; protected $b = &#39;&#39;; protected $input = &#39;&#39;; protected $inputIndex = 0; protected $inputLength = 0; protected $lookAhead = null; protected $output = &#39;&#39;; // -- 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 === "&#39;" || $this->a === &#39;"&#39;) { 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(&#39;Unterminated string literal.&#39;); } if ($this->a === &#39;\\&#39;) { $this->output .= $this->a; $this->a = $this->get(); } } } case self::ACTION_DELETE_A_B: $this->b = $this->next(); if ($this->b === &#39;/&#39; && ( $this->a === &#39;(&#39; || $this->a === &#39;,&#39; || $this->a === &#39;=&#39; || $this->a === &#39;:&#39; || $this->a === &#39;[&#39; || $this->a === &#39;!&#39; || $this->a === &#39;&&#39; || $this->a === &#39;|&#39; || $this->a === &#39;?&#39; || $this->a === &#39;{&#39; || $this->a === &#39;}&#39; || $this->a === &#39;;&#39; || $this->a === "\n" )) { $this->output .= $this->a . $this->b; for (;;) { $this->a = $this->get(); if ($this->a === &#39;[&#39;) { /* inside a regex [...] set, which MAY contain a &#39;/&#39; itself. Example: mootools Form.Validator near line 460: return Form.Validator.getValidator(&#39;IsEmpty&#39;).test(element) || (/^(?:[a-z0-9!#$%&&#39;*+/=?^_`{|}~-]\.?){0,63}[a-z0-9!#$%&&#39;*+/=?^_`{|}~-]@(?:(?:[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(&#39;value&#39;)); */ for (;;) { $this->output .= $this->a; $this->a = $this->get(); if ($this->a === &#39;]&#39;) { break; } elseif ($this->a === &#39;\\&#39;) { $this->output .= $this->a; $this->a = $this->get(); } elseif (ord($this->a) <= self::ORD_LF) { throw new JSMinException(&#39;Unterminated regular expression set in regex literal.&#39;); } } } elseif ($this->a === &#39;/&#39;) { break; } elseif ($this->a === &#39;\\&#39;) { $this->output .= $this->a; $this->a = $this->get(); } elseif (ord($this->a) <= self::ORD_LF) { throw new JSMinException(&#39;Unterminated regular expression literal.&#39;); } $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 &#39; &#39;; } /** * Is $c a letter, digit, underscore, dollar sign, or non-ASCII character. * * @return bool */ protected function isAlphaNum($c) { return ord($c) > 126 || $c === &#39;\\&#39; || preg_match(&#39;/^[\w\$]$/&#39;, $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 &#39; &#39;: 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 &#39;{&#39;: case &#39;[&#39;: case &#39;(&#39;: case &#39;+&#39;: case &#39;-&#39;: case &#39;!&#39;: case &#39;~&#39;: $this->action(self::ACTION_KEEP_A); break; case &#39; &#39;: $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 &#39; &#39;: 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 &#39;}&#39;: case &#39;]&#39;: case &#39;)&#39;: case &#39;+&#39;: case &#39;-&#39;: case &#39;"&#39;: case "&#39;": $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 &#39;/&#39; is followed by a &#39;/&#39; or &#39;*&#39;. * * @uses get() * @uses peek() * @throws JSMinException On unterminated comment. * @return string */ protected function next() { $c = $this->get(); if ($c === &#39;/&#39;) { switch($this->peek()) { case &#39;/&#39;: for (;;) { $c = $this->get(); if (ord($c) <= self::ORD_LF) { return $c; } } case &#39;*&#39;: $this->get(); for (;;) { switch($this->get()) { case &#39;*&#39;: if ($this->peek() === &#39;/&#39;) { $this->get(); return &#39; &#39;; } break; case null: throw new JSMinException(&#39;Unterminated comment.&#39;); } } 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 {} ?>