Patrick Hunlock氏のブログにて、複数ファイルに分かれたJavaScriptを1つにまとめる方法が解説されています。このスクリプトはPHPを使っているため、自前でキャッシュ制御を行うことで、ブラウザのキャッシュ問題に対応したり、ファイルに変更を加えたときにも自動的にキャッシュが再作成されるようになっています。
Patrick Hunlock氏のブログにて、複数ファイルに分かれたJavaScriptを1つにまとめる方法が解説されています。このスクリプトはPHPを使っているため、自前でキャッシュ制御を行うことで、ブラウザのキャッシュ問題に対応したり、ファイルに変更を加えたときにも自動的にキャッシュが再作成されるようになっています。
以下、記事の概要を紹介します。
いろいろなJavaScriptライブラリを使っていると、以下のようなコードになることがあります。
<script src = "yahoo.js" ></script> <script src = "dom.js" ></script> <script src = "event.js" ></script> <script src = "dragdrop.js" ></script> <script src = "slider.js" ></script>
これを、以下のようにして読み込めるようにするのが、今回紹介するスクリプトの内容です。
<script src = "scripts/yahoo.js, dom.js, event.js, dragdrop.js, slider.js">
</script>
動作をするためにはApache WebサーバーとPHPが必要です。まず、.htaccessを編集し、以下のように記述します。
<FilesMatch "^scripts$">
ForceType application/x-httpd-php
</FilesMatch>
これで、/scriptsからはじまるアクセスがあった時には、「scripts」というファイル名のPHPスクリプトが実行されるようになります。scriptsがディレクトリだったり、scripts.phpというファイル名にならないことに注意してください。
次に、scriptsファイルを作成します。Apacheのドキュメントルートにて、scriptsというファイルを作り、以下のコードを入力します。
<?php // このスクリプトはPUBLIC DOMAIN形式ですので、 // 自由にお使いいただけます // gzipを重複して使用しないように // zlibエクステンションを停止する ini_set("zlib.output_compression", "Off"); // Content-Typeヘッダーをセットする header("Content-Type: text/javascript; charset=UTF-8"); // cache-controlヘッダーをセットする // HTTP 1.1 ブラウザーは、必ずrevalidateにセット header("Cache-Control: must-revalidate"); // ファイル名の一覧を取り出す // URLから/をもとに分解 $expl = explode("/",$HTTP_SERVER_VARS["REQUEST_URI"]); // URLデコードを行い、%20をスペースに変換 $fileList = trim(urldecode($expl[count($expl)-1])); // 残りの文字列に対し、,文字で分解 $fileNames = explode(",",$fileList); // $fileNamesに、ファイル名の一覧が配列で格納される // last-modifierヘッダーを送信するため、 // 各ファイルを検査し、最終更新日を取り出す $newestFile = 0; $longFilename = ''; for ($i=0; ($i < count($fileNames)); $i++) { $fileNames[$i] = trim($fileNames[$i]); $longFilename .= $fileNames[$i]; $lastMod = @filemtime($fileNames[$i]); if ($lastMod > $newestFile) { $newestFile = $lastMod; } } ////////////////////////////////////////////////// // ブラウザのキャッシュ制御を行う $fileHash = md5($longFilename); $hash = $fileHash . '-'.$newestFile; $headers = getallheaders(); if (ereg($hash, $headers['If-None-Match'])) { header('Last-Modified: '.gmdate('D, d M Y H:i:s', $newestFile).' GMT', true, 304); die(); } header("ETag: \"{$hash}\""); if (isset($headers['If-Modified-Since'])) { if ($newestFile <= strtotime($headers['If-Modified-Since'])) { // No change so send a 304 header and terminate header('Last-Modified: '.gmdate('D, d M Y H:i:s', $newestFile).' GMT', true, 304); die(); } } header('Last-Modified: '.gmdate('D, d M Y H:i:s', $newestFile).' GMT'); ////////////////////////////////////////////////// ////////////////////////////////////////////////// // ファイルシステムのキャッシュ制御を行う $fp = @fopen("cache/$fileHash.txt","r"); if ($fp) { if ($newestFile>@filemtime("cache/$fileHash.txt")) { fclose($fp); $fp=false;} } if (!$fp) { $buffer=''; for ($i=0; ($i < count($fileNames)); $i++) { $buffer .= @file_get_contents($fileNames[$i]) . "\n\n"; } $fp = @fopen("cache/$fileHash.txt","w"); @fwrite($fp,$buffer); @fclose($fp); $fp = @fopen("cache/$fileHash.gz","w"); $buffer = gzencode($buffer, 9, FORCE_GZIP); @fwrite($fp,$buffer); @fclose($fp); } ////////////////////////////////////////////////// // 出力を行う if (strstr($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')) { header ("Content-Encoding: gzip"); header ("Content-Length: " . filesize("cache/$fileHash.gz")); readfile("cache/$fileHash.gz"); } else { header ("Content-Length: " . filesize("cache/$fileHash.txt")); readfile("cache/$fileHash.txt"); } ////////////////////////////////////////////////// ?>
最後に、cacheディレクトリを作成します。このディレクトリは、scriptsファイルがあるディレクトリと同じ階層になります。このディレクトリは、scriptsファイルが作成するキャッシュファイルを格納するディレクトリで、ファイル名は連結されたファイル名をMD5化したものに、.txtが付加したもの、あるいは.gzを付加したものとなります。Javascriptファイルに修正が加わっても、自動的にキャッシュファイルは新しい内容に更新されます。
このスクリプトは簡単に試すことができます。たとえば、以下のように記述するだけで、自動的にfile1.js、file2.js、file3.jsをまとめて、キャッシュに残してくれます。なお、これらのファイルはscriptsディレクトリと同階層に設置します。
<script src = "scripts/file1.js, file2.js, file3.js"></script>
またscripts/の後ろの順序は、すべてのページで同一にしておきます。そうしないと、キャッシュを作成したときに、別々の名前でファイルが生成されてしまいます。
より詳しい解説は、筆者のブログのSupercharged Javascriptにて確認してください。(PHPプロ!)
関連リンク
関連ニュース
転載元
PHPプロ!:最新のPHPニュース
この記事は参考になりましたか?
- この記事の著者
-
PHPプロ!(PHPプロ!)
「PHPプロ!」は、アシアル株式会社が運営するPHP開発者のためのポータル&コミュニティサイトです。同サイトでは、PHP最新ニュースや、困ったときのQ&A掲示板、初心者向けのPHP講座、PHP中級者のためのTIPSメーリングリスト、中・上級者向けの技術ノウハウ満載のPHPプロ!マガジンの提供など、PHP開発...
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です