php 压缩html css,php压缩多个CSS/JS资料

php压缩多个CSS/JS文件

1. 压缩css

compress.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();

实例化:

test.php

test

2. 压缩js

利用jsmin类

来源:http://code.google.com/p/minify/

compress.php

header('Content-type: text/javascript');

require 'jsmin.php';

echo JSMin::minify(file_get_contents('common.js') . file_get_contents('common2.js'));

common.js

alert('first js');

common.js

alert('second js');

jsmin.php

/**

* jsmin.php - extended PHP implementation of Douglas Crockford's JSMin.

*

*

* $minifiedJs = JSMin::minify($js);

*

*

* This is a direct port of jsmin.c to PHP with a few PHP performance tweaks and

* modifications to preserve some comments (see below). Also, rather than using

* stdin/stdout, JSMin::minify() accepts a string as input and returns another

* string as output.

*

* Comments containing IE conditional compilation are preserved, as are multi-line

* comments that begin with "/*!" (for documentation purposes). In the latter case

* newlines are inserted around the comment to enhance readability.

*

* 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 (PHP port)

* @author Steve Clay (modifications + cleanup)

* @author Andrea Giammarchi (spaceBeforeRegExp)

* @copyright 2002 Douglas Crockford (jsmin.c)

* @copyright 2008 Ryan Grove (PHP port)

* @license http://opensource.org/licenses/mit-license.php MIT License

* @link http://code.google.com/p/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 = "\n";

protected $b = '';

protected $input = '';

protected $inputIndex = 0;

protected $inputLength = 0;

protected $lookAhead = null;

protected $output = '';

/**

* Minify Javascript

*

* @param string $js Javascript to be minified

* @return string

*/

public static function minify($js)

{

// look out for syntax like "++ +" and "- ++"

$p = '\\+';

$m = '\\-';

if (preg_match("/([$p$m])(?:\\1 [$p$m]| (?:$p$p|$m$m))/", $js)) {

// likely pre-minified and would be broken by JSMin

return $js;

}

$jsmin = new JSMin($js);

return $jsmin->min();

}

/*

* Don't create a JSMin instance, instead use the static function minify,

* which checks for mb_string function overloading and avoids errors

* trying to re-minify the output of Closure Compiler

*

* @private

*/

public function __construct($input)

{

$this->input = $input;

}

/**

* Perform minification, return result

*/

public function min()

{

if ($this->output !== '') { // min already run

return $this->output;

}

$mbIntEnc = null;

if (function_exists('mb_strlen') && ((int)ini_get('mbstring.func_overload') & 2)) {

$mbIntEnc = mb_internal_encoding();

mb_internal_encoding('8bit');

}

$this->input = str_replace("\r\n", "\n", $this->input);

$this->inputLength = strlen($this->input);

$this->action(self::ACTION_DELETE_A_B);

while ($this->a !== null) {

// determine next command

$command = self::ACTION_KEEP_A; // default

if ($this->a === ' ') {

if (! $this->isAlphaNum($this->b)) {

$command = self::ACTION_DELETE_A;

}

} elseif ($this->a === "\n") {

if ($this->b === ' ') {

$command = self::ACTION_DELETE_A_B;

// in case of mbstring.func_overload & 2, must check for null b,

// otherwise mb_strpos will give WARNING

} elseif ($this->b === null

|| (false === strpos('{[(+-', $this->b)

&& ! $this->isAlphaNum($this->b))) {

$command = self::ACTION_DELETE_A;

}

} elseif (! $this->isAlphaNum($this->a)) {

if ($this->b === ' '

|| ($this->b === "\n"

&& (false === strpos('}])+-"\'', $this->a)))) {

$command = self::ACTION_DELETE_A_B;

}

}

$this->action($command);

}

$this->output = trim($this->output);

if ($mbIntEnc !== null) {

mb_internal_encoding($mbIntEnc);

}

return $this->output;

}

/**

* ACTION_KEEP_A = Output A. Copy B to A. Get the next B.

* ACTION_DELETE_A = Copy B to A. Get the next B.

* ACTION_DELETE_A_B = Get the next B.

*/

protected function action($command)

{

switch ($command) {

case self::ACTION_KEEP_A:

$this->output .= $this->a;

// fallthrough

case self::ACTION_DELETE_A:

$this->a = $this->b;

if ($this->a === "'" || $this->a === '"') { // string literal

$str = $this->a; // in case needed for exception

while (true) {

$this->output .= $this->a;

$this->a = $this->get();

if ($this->a === $this->b) { // end quote

break;

}

if (ord($this->a) <= self::ORD_LF) {

throw new JSMin_UnterminatedStringException(

"JSMin: Unterminated String at byte "

. $this->inputIndex . ": {$str}");

}

$str .= $this->a;

if ($this->a === '\\') {

$this->output .= $this->a;

$this->a = $this->get();

$str .= $this->a;

}

}

}

// fallthrough

case self::ACTION_DELETE_A_B:

$this->b = $this->next();

if ($this->b === '/' && $this->isRegexpLiteral()) { // RegExp literal

$this->output .= $this->a . $this->b;

$pattern = '/'; // in case needed for exception

while (true) {

$this->a = $this->get();

$pattern .= $this->a;

if ($this->a === '/') { // end pattern

break; // while (true)

} elseif ($this->a === '\\') {

$this->output .= $this->a;

$this->a = $this->get();

$pattern .= $this->a;

} elseif (ord($this->a) <= self::ORD_LF) {

throw new JSMin_UnterminatedRegExpException(

"JSMin: Unterminated RegExp at byte "

. $this->inputIndex .": {$pattern}");

}

$this->output .= $this->a;

}

$this->b = $this->next();

}

// end case ACTION_DELETE_A_B

}

}

protected function isRegexpLiteral()

{

if (false !== strpos("\n{;(,=:[!&|?", $this->a)) { // we aren't dividing

return true;

}

if (' ' === $this->a) {

$length = strlen($this->output);

if ($length < 2) { // weird edge case

return true;

}

// you can't divide a keyword

if (preg_match('/(?:case|else|in|return|typeof)$/', $this->output, $m)) {

if ($this->output === $m[0]) { // odd but could happen

return true;

}

// make sure it's a keyword, not end of an identifier

$charBeforeKeyword = substr($this->output, $length - strlen($m[0]) - 1, 1);

if (! $this->isAlphaNum($charBeforeKeyword)) {

return true;

}

}

}

return false;

}

/**

* Get next char. Convert ctrl char to space.

*/

protected function get()

{

$c = $this->lookAhead;

$this->lookAhead = null;

if ($c === null) {

if ($this->inputIndex < $this->inputLength) {

$c = $this->input[$this->inputIndex];

$this->inputIndex += 1;

} else {

return null;

}

}

if ($c === "\r" || $c === "\n") {

return "\n";

}

if (ord($c) < self::ORD_SPACE) { // control char

return ' ';

}

return $c;

}

/**

* Get next char. If is ctrl character, translate to a space or newline.

*/

protected function peek()

{

$this->lookAhead = $this->get();

return $this->lookAhead;

}

/**

* Is $c a letter, digit, underscore, dollar sign, escape, or non-ASCII?

*/

protected function isAlphaNum($c)

{

return (preg_match('/^[0-9a-zA-Z_\\$\\\\]$/', $c) || ord($c) > 126);

}

protected function singleLineComment()

{

$comment = '';

while (true) {

$get = $this->get();

$comment .= $get;

if (ord($get) <= self::ORD_LF) { // EOL reached

// if IE conditional comment

if (preg_match('/^\\/@(?:cc_on|if|elif|else|end)\\b/', $comment)) {

return "/{$comment}";

}

return $get;

}

}

}

protected function multipleLineComment()

{

$this->get();

$comment = '';

while (true) {

$get = $this->get();

if ($get === '*') {

if ($this->peek() === '/') { // end of comment reached

$this->get();

// if comment preserved by YUI Compressor

if (0 === strpos($comment, '!')) {

return "\n/*" . substr($comment, 1) . "*/\n";

}

// if IE conditional comment

if (preg_match('/^@(?:cc_on|if|elif|else|end)\\b/', $comment)) {

return "/*{$comment}*/";

}

return ' ';

}

} elseif ($get === null) {

throw new JSMin_UnterminatedCommentException(

"JSMin: Unterminated comment at byte "

. $this->inputIndex . ": /*{$comment}");

}

$comment .= $get;

}

}

/**

* Get the next character, skipping over comments.

* Some comments may be preserved.

*/

protected function next()

{

$get = $this->get();

if ($get !== '/') {

return $get;

}

switch ($this->peek()) {

case '/': return $this->singleLineComment();

case '*': return $this->multipleLineComment();

default: return $get;

}

}

}

class JSMin_UnterminatedStringException extends Exception {}

class JSMin_UnterminatedCommentException extends Exception {}

class JSMin_UnterminatedRegExpException extends Exception {}

实例化:

test.php

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值