PhpRiot
News Archive
PhpRiot Newsletter
Your Email Address:

More information

How to Roll Your Own JavaScript Compressor with PHP and the Closure Compiler

Note: This article was originally published at Planet PHP on 31 August 2010.
Planet PHP

In my previous post, I discussed the Closure Compiler's REST API. In this article, we'll develop a small PHP program that shows how the API can be used to compress JavaScript code whenever you need it.

Why write your own system?

You'll find that several free tools handle this task; one of the first PHP JavaScript compressors was written by Ed Eliot. Sometimes, however, they require technologies you don't use - such as Java - or may not cater for internal workflow processes, including:

  • distributing uncompressed JavaScript to developer PCs
  • integration with source control systems
  • automating your build, and so on
Important: This is not production-level code!

The code below implements a rudimentary JavaScript compressor in PHP to illustrate the basics. The code calls the Closure Compiler compression API every time a request is made, so it's likely to be slower than multiple uncompressed JavaScript files. You should add your own functions to handle caching to a file or database.

The html

Assume you normally include the following script tags at the bottom of your html:

We'll replace this block with a single script tag that references all three files.
The .js is removed and the file names are separated with an ampersand:

The PHP

We now require an index.php file within our script folder. The first code block transforms the GET parameters into an array (file1, file2, file3) and initializes the variables:

We now loop through the JS files, read the content, and append it to the $js[mono?] string. If a file is unable to be found or read, its name is appended to the $err[mono?] string:*

// fetch JavaScript files for ($i = 0, $j = count($jsfiles); $i

If any files are missing, we can generate a JavaScript alert to inform the developer:

if ($err != '') { // error: missing files $jscomp = "alert('The following JavaScript files could not be read:\\n$err');"; }

If there are no errors and we have some JavaScript code, we can proceed with the compression. The $apiArgs array contains a list of Closure Compiler API options - you can add, remove, or modify these as necessary. The arguments are encoded and appended to the $args string:

else if ($js != '') { // REST API arguments $apiArgs = array('compilation_level'='ADVANCED_OPTIMIZATIONS', 'output_format' = 'text', 'output_info' = 'compiled_code'); $args = 'js_code=' . urlencode($js); foreach ($apiArgs as $key = $value) { $args .= '&' . $key .'='. urlencode($value); }

We can now call the Closure Compiler API using PHP's cURL library. The compressed JavaScript is returned to the $jscomp string:

// API call using cURL $call = curl_init(); curl_setopt_array($call, array(CURLOPT_URL = 'http://closure-compiler.appspot.com/compile', CURLOPT_POST = 1, CURLOPT_POSTFIELDS = $args, CURLOPT_RETURNTRANSFER = 1, CURLOPT_HEADER = 0, CURLOPT_FOLLOWLOCATION = 0)); $jscomp = curl_exec($call); curl_close($call);

Finally, we return our compressed code to the browser with the appropriate MIME type:

}
// output content
header('Content-type: text/javascript');
echo $jscomp;

Truncated by Planet PHP, read more at the original (another 3262 bytes)