Google Closure Compilerを利用したPHPクラスを作ってみる
前回の記事で利用した、Google Closure Compilerを使ってJavaスクリプトを圧縮するツールを作成してみます。
HTMLから呼び出すJavaスクリプトをPHPファイルにする
Javaスクリプトは、基本的には「*.js」ファイルですがPHPを指定することもできます。
もちろん指定したPHPが、Javaスクリプトを出力しなければなりません。
HTMLにてJavaスクリプト定義にPHPを指定する例
<script type="text/javascript" src="js.php"></script>
複数のJavaスクリプトを1つにまとめて、圧縮して出力するPHPクラス
これを利用して、複数のJavaスクリプトを1つにまとめて、圧縮して出力するPHPクラスを作成してみました。
ただまとめて圧縮するだけだと、表示するたびに処理が必要で遅くなるためキャッシュファイルを作成するようにしました。
class jsCompresser{ private $s=Array(); //JavaScriptライブラリ パス配列 private $cacheTime = 1209600; //キャッシュ時間(ミリ秒) デフォルト2週間 private $cacheDir = __DIR__."/"; //キャッシュ出力フォルダ private $cacheFile = null; //キャッシュファイル名 private $Error = ""; //エラーメッセージ private $compilation_level='SIMPLE_OPTIMIZATION'; /** * コンストラクタ * @param type $version */ function __construct($version=""){ //キャッシュファイル名作成 if($version == "" || $version == null) { //指定が無い場合は、対象フォルダを検索 $files = glob($this->cacheDir.'cache.*.js'); //存在する場合 if($files != false) { //既存のキャッシュファイルを設定 $this->cacheFile = $files[0]; } else { //キャッシュファイル名を作成 $this->cacheFile = $this->cacheDir.'cache.'.md5(date("Ymd")).'.js'; } }else{ //指定がある場合は、指定文字列でキャッシュファイルを作成 $this->cacheFile = $this->cacheDir.'cache.'.md5($version).'.js'; } } /** * 圧縮レベルを設定 * @param type $Level * WHITESPACE_ONLY 空白&コメント&改行削除 * SIMPLE_OPTIMIZATIONS 上記plus 変数名省略可 * ADVANCED_OPTIMIZATIONS 解析して高圧縮 */ public function setCompilationLevel($Level){ $this->compilation_level =$Level; } /** * 対象のスクリプトを設定する * @param type $key lib:ライブラリ、js:圧縮対象ファイル、code:JavaScriptコード * @param type $val */ public function setScript($key,$val) { $this->s[] = array($key=>$val); } /** * キャッシュの有効時間を設定する * @param $cacheTime int キャッシュ時間(ミリ秒) */ public function setCacheTime($cacheTime) { $this->cacheTime = $cacheTime; } /** * キャッシュの出力フォルダを指定する * @param $cacheDir text キャッシュの出力フォルダ */ public function setCacheDir($cacheDir) { $this->cacheDir = rtrim($cacheDir,'/').'/'; //指定が無い場合は、対象フォルダを検索 $files = glob($this->cacheDir.'cache.*.js'); //存在する場合 if($files != false) { //既存のキャッシュファイルを設定 $this->cacheFile = $files[0]; } else { //キャッシュファイル名を作成 $this->cacheFile = $this->cacheDir.'cache.'.md5(date("Ymd")).'.js'; } } /** * 圧縮したJavaスクリプトを取得する * @param なし */ public function getMinJs() { $MinJs = ""; //キャッシュが有効か確認する。 if($this->_chkCache()){ //キャッシュが有効なので、キャッシュ内容を返す return file_get_contents($this->cacheFile); } else { //キャッシュが無効なので、対象フォルダからキャッシュを削除 $files = glob($this->cacheDir.'cache.*.js'); for($i = 0;count($files) > $i;$i++) { unlink($files[$i]); } } //各種別ごとに内容をまとめる for($i = 0;count($this->s) > $i;$i++) { foreach ($this->s[$i] as $key => $value){ switch ($key) { case 'lib': $lib .= file_get_contents($value); break; case 'js': $MinJs .= file_get_contents($value); break; case 'code': $MinJs .= $value; break; } } } //圧縮対象コードがサイズオーバーの場合 if(strlen($MinJs) > 200000) { //ダメもとで、タブや改行を削除 $MinJs = preg_replace( "/(\t|\r\n|\r|\n)/s", "", $MinJs); } //ライブラリと圧縮結果を取得 $MinJs = $lib.$this->_miniJS($MinJs); //圧縮でエラーが発生していた場合 if(strlen($this->Error) > 0) { //エラーメッセージを戻す $MinJs = $this->Error; } else { //正常なので、キャッシュファイルを作成 file_put_contents( $this->cacheFile, $MinJs ); } return $MinJs; } /** * キャッシュファイル有効チェック * @return boolean */ private function _chkCache(){ // キャッシュファイルが無い if ( !is_file($this->cacheFile) ) { return false; } //キャッシュファイルの日付を取得 $cftime = filemtime($this->cacheFile); if ( !$cftime ) { return false; } // キャッシュ有効時間を過ぎている if ( time() > ($this->cacheTime + $cftime) ) { return false; } for($i = 0;count($this->s) > $i;$i++) { foreach ($this->s[$i] as $key => $value){ //Jsとlib以外は行わない if($key != 'js' && $key != 'lib' ) continue; //ファイル日付を取得 $jftime = filemtime($value); if ( !$jftime ) return false; //キャッシュファイルより新しい場合 if ( $cftime < $jftime ) return false; } } return true; } /** * Google Closure Compilerで圧縮実体 * @param type $js * @return type */ private function _miniJS($js){ $ch = curl_init('http://closure-compiler.appspot.com/compile'); curl_setopt($ch,CURLOPT_POST,true); curl_setopt($ch, CURLOPT_POSTFIELDS, 'output_format=json' .'&output_info=compiled_code' .'&output_info=warnings' .'&output_info=errors' .'&compilation_level='.$compilation_level .'&js_code=' . urlencode($js) ); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); curl_setopt($ch, CURLOPT_TIMEOUT, 30); $minified = curl_exec($ch); curl_close($ch); $rec=json_decode($minified); if(isset($rec->errors)) { for($i = 0;count($rec->errors) > $i;$i++) { foreach ($rec->errors[$i] as $key => $value){ $this->Error .= $key.':'.$value.'\n'; } } return ''; } return $rec->compiledCode; } }
コンストラクタ | 引数として文字列を渡すことで、任意のキャッシュファイル名を作成します。
省略時には、処理日をmd5ハッシュ値にし作成します。 |
setCompilationLevel | 圧縮レベルを指定します。(デフォルト SIMPLE_OPTIMIZATIONS)
WHITESPACE_ONLY 空白&コメント&改行削除 |
setScript | 対象のスクリプトパス、またはコードを設定します。
※libは圧縮されません。js+codeを圧縮します。 ※どの順番で指定した場合でも、libは先頭に出力されます。 lib ライブラリ js 圧縮対象ファイル code JavaScriptコード |
setCacheTime | キャッシュの有効時間をミリ秒で設定(デフォルト2週間) |
setCacheDir | キャッシュの出力フォルダを指定します(デフォルトPHPパス) |
getMinJs | setScriptで指定したコードを圧縮し戻します。 |
上記クラスの呼び出しサンプル
w2uiライブラリを使ってJavaスクリプトを作成していると、かなり大きなファイルになってしまいます。
設定部や処理部など、ファイルを分割しておいて、HTMLから呼び出されたときにまとめて圧縮して出力しています。
//クラス作成 $js = new jsCompresser(); //キャッシュ出力フォルダ $js->setCacheDir(__DIR__); //対象Javaスクリプト(行順に出力) $js->setScript("lib",__DIR__."/jquery.js"); $js->setScript("js",__DIR__."/global.js"); $js->setScript("js",__DIR__."/myclass.js"); $js->setScript("code","$(function () {w2utils.locale('locale/ja-jp.json');"); $js->setScript("js",__DIR__."/settings.js"); $js->setScript("js",__DIR__."/function.js"); $js->setScript("code","})"); //圧縮レベルの設定 $js->setCompilationLevel('ADVANCED_OPTIMIZATIONS'); //設定したスクリプトを圧縮して表示 echo $js->getMinJs();
本来ならコンパイルしてくれるツールなど沢山あるのでしょうが、PHPクラスにしておけばある程度環境に左右されないかと思います。
パッと考えて作ったクラスなので、あまり自信をもって公開できるものではありませんが・・・(;´・ω・)
何かのお役に立てれば幸いです。