Script Compressor

Item 7 of 9

» Download this file

1   <?php
2   
3   //======================================================================================================
4   // title:        PHP based Javascript Compressor
5   // author:       Daniel Pupius (pupius.co.uk)
6   // created:      13/06/2003
7   // description:  PHP function that takes in a string of javascript and compresses all the whitespace
8   //               and strips the comments.  It is directly based on the JavaScript Crunchinator by Mike
9   //               Hall that can be found at BrainJar.com (http://www.brainjar.com/js/crunch/)
10  //
11  //               The main difference is that this script doesn't crunch everything onto one line, the
12  //               aim was to reduce the filesize of imported JavaScript behaviours for size critical
13  //               e-learning material.  But in order to ensure the script still runs we only remove as
14  //               many lines as we can without compromising the code (e.g. incase of missing ';')
15  //
16  //               This method also has the added advantage that it is still possible to debug compressed
17  //               code.
18  //
19  //               We also leave /* */ style comments, to allow some form of copyright or information to
20  //               be left in the final output.
21  //
22  //               I believe it also works quite successfully with cascading style sheets...
23  //
24  //               To use simply call the function on a string of javascript, or pass it a filename, e.g:
25  //                       $newstring = compress_javascript($rawstring);
26  //                       $newstring = compress_javascript($filename,true);
27  //======================================================================================================
28  
29  function compress_javascript($str,$isfile=false) {
30  
31  	//if the $str actually holds a filename then open the file:
32  	if($isfile) {
33  		$fp = fopen ($str, "rb");
34  		$str = fread ($fp, filesize ($str));
35  		fclose ($fp);
36  	}
37  
38  
39  	//remove windows cariage returns
40  	$str = str_replace("\r","",$str);
41  
42  	//array to store replaced literal strings
43  	$literal_strings = array();
44  
45  	//explode the string into lines
46  	$lines = explode("\n",$str);
47  
48  
49  	//loop through all the lines, building a new string at the same time as removing literal strings
50  	$clean = "";
51  	$inComment = false;
52  	$literal = "";
53  	$inQuote = false;
54  	$escaped = false;
55  	$quoteChar = "";
56  
57  	for($i=0;$i<count($lines);$i++) {
58  		$line = $lines[$i];
59  
60  		$inNormalComment = false;
61  
62  		//loop through line's characters and take out any literal strings, replace them with ___i___ where i is the index of this string
63  		for($j=0;$j<strlen($line);$j++) {
64  			$c = substr($line,$j,1);
65  			$d = substr($line,$j,2);
66  
67  			//look for start of quote
68  			if(!$inQuote && !$inComment) {
69  				//is this character a quote or a comment
70  				if(($c=="\"" || $c=="'") && !$inComment && !$inNormalComment) {
71  					$inQuote = true;
72  					$inComment = false;
73  					$escaped = false;
74  					$quoteChar = $c;
75  					$literal = $c;
76  
77  				} else if($d=="/*" && !$inNormalComment) {
78  					$inQuote = false;
79  					$inComment = true;
80  					$escaped = false;
81  					$quoteChar = $d;
82  					$literal = $d;
83  
84  					$j++;
85  
86  				//ignore string markers that are found inside comments
87  				} else if($d=="//") {
88  					$inNormalComment = true;
89  					$clean .= $c;
90  				} else {
91  					$clean .= $c;
92  				}
93  
94  
95  			//allready in a string so find end quote
96  			} else {
97  				if($c == $quoteChar && !$escaped && !$inComment) {
98  					$inQuote = false;
99  					$literal .= $c;
100 
101 					//subsitute in a marker for the string
102 					$clean .= "___" . count($literal_strings) . "___";
103 
104 					//push the string onto our array
105 					array_push($literal_strings,$literal);
106 
107 				} else if($inComment && $d=="*/") {
108 					$inComment = false;
109 					$literal .= $d;
110 
111 					//subsitute in a marker for the string
112 					$clean .= "___" . count($literal_strings) . "___";
113 
114 					//push the string onto our array
115 					array_push($literal_strings,$literal);
116 
117 					$j++;
118 
119 				} else if($c == "\\" && !$escaped) $escaped = true;
120 				else $escaped = false;
121 
122 				$literal .= $c;
123 			}
124 		}
125 
126 		if($inComment) $literal .= "\n";
127 		$clean .= "\n";
128 	}
129 
130 	//explode the clean string into lines again
131 	$lines = explode("\n",$clean);
132 
133 
134 	//now process each line at a time
135 	for($i=0;$i<count($lines);$i++) {
136 		$line = $lines[$i];
137 
138 		//remove comments
139 		$line = preg_replace("/\/\/(.*)/","",$line);
140 
141 		//strip leading and trailing whitespace
142 		$line = trim($line);
143 
144 		//remove all whitespace with a single space
145 		$line = preg_replace("/\s+/"," ",$line);
146 
147 		//remove any whitespace that occurs after/before an operator
148 		$line = preg_replace("/\s*([!\}\{;,&=\|\-\+\*\/\)\(:])\s*/","\\1",$line);
149 
150 		$lines[$i] = $line;
151 	}
152 
153 	//implode the lines
154 	$str = implode("\n",$lines);
155 
156 	//make sure there is a max of 1 \n after each line
157 	$str = preg_replace("/[\n]+/","\n",$str);
158 
159 	//strip out line breaks that immediately follow a semi-colon
160 	$str = preg_replace("/;\n/",";",$str);
161 
162 	//curly brackets aren't on their own
163 	$str = preg_replace("/[\n]*\{[\n]*/","{",$str);
164 
165 	//finally loop through and replace all the literal strings:
166 	for($i=0;$i<count($literal_strings);$i++) $str = str_replace("___".$i."___",$literal_strings[$i],$str);
167 
168 	//print_r($literal_strings);
169 
170 	return $str;
171 }
172 
173 //header("Content-Type: text/plain");
174 //$str = compress_javascript("../styles/_interface.css",true);
175 //$str = compress_javascript("../behaviours/act_api.js",true);
176 //echo $str;
177 
178 ?>
179 

Back to top