本文实例讲述了php实现压缩多个CSS与JS文件的方法。分享给大家供大家参考。具体实现方法如下:
1. 压缩css
<?php
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();
使用方法如下:
<link href=\"compress.php\" rel=\"stylesheet\" type=\"text/css\" /><span id=\"tester\">test</span>
2. 压缩js,利用jsmin类:
本实例源自:http://code.google.com/p/minify/
header(\'Content-type: text/javascript\');
require \'jsmin.php\';
echo JSMin::minify(file_get_contents(\'common.js\') . file_get_contents(\'common2.js\'));
其中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程序设计有所帮助。