キャッシュを作ってみよう。
篠原 隆司
アフィリエイト広告を利用しています
このページの内容が役に立ったら X (旧twitter) でフォローして頂けると励みになります
挨拶や報告は無しで大丈夫です
PHP高速化のために、ページ内容をデータベースやファイルにキャッシュする方法って色々紹介されてますね。
ってことで、今さらなんかなーって思いつつも。
実は私は、他ブログやニュースなどで、色々なキャッシュ方法を見聞きしてますが、実際に使ったことはありません。
「こういうのがあるよー」ってことを知っている程度です。
なぜか?って。
だって、自分でキャッシュの仕組みを作っちゃってたから。
では、コードの前に特徴から。
キャッシュの保存先はデータベースです。
最初は、ファイルベースでを作ってたんだけど、数万ページを超えるようなサイトだと、キャッシュファイルだけでもかなりの数になり、しかもFTPしか使えない状況だと大変なことになってきてたので、データベースに切り替えました。
キャッシュは、ページの任意の範囲で行えます。
ログイン機能など、ユーザーごとに微妙に表示内容の異なるサイトで威力を発揮します。
ヘッダーだけキャッシュ、内容だけキャッシュなど、キャッシュできる範囲は自由です。
もちろん、ページまるごとキャッシュも可能です。
1箇所のキャッシュで、任意の数の値をキャッシュできます。
キャッシュ用の変数は配列です。
ページ内容だけでなく、時間、商品名、説明文などなど、配列なので、好きなだけセットしてください。
例えば、body部はまるごと、meta keywordや、meta descriptionは、個別にキャッシュしたいなどに対応できます。
●データベースにテーブルを作成する。
CREATE TABLE IF NOT EXISTS `AultaCacheData` ( `CacheId` varchar(30) NOT NULL COMMENT 'キャッシュID', `CacheData` mediumtext NOT NULL, `CacheDatetime` datetime NOT NULL, PRIMARY KEY (`CacheId`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Aultaキャッシュ';
●定数宣言
// キャッシュ機能の有効・無効 define('CA_FILE_CACHE_ON', true);
●キャッシュからロードする
/* * DBからキャッシュデータをロードする * $cacheId : キャッシュID * $expire : 有効期限(ミリ秒) */ function loadCacheDb($cacheId, $expire = 31536000){ // 戻り値の初期化 $returnData = array( 'isLoaded' => false // キャッシュから正常に読込みした , 'timeStamp' => 0 // キャッシュファイルのタイムスタンプ(秒) , 'header' => array() // ヘッダ , 'data' => array() // データ ); // 開発時などは CA_FILE_CACHE_ON = false でキャッシュを無効化 if ( ! CA_FILE_CACHE_ON) return $returnData; // キャッシュのチェック $result = dbGetFields( "select CacheData, CacheDatetime from AultaCacheData" . " where CacheId = '" . dbRealEscape($cacheId) . "'" ); if ($result !== false){ // キャッシュファイルが存在する $t = strtotime($result['CacheDatetime']); if ($t > (time() - $expire)){ // タイムスタンプが有効期限以内なら $returnData = (array)json_decode($result['CacheData'], true); $returnData['timeStamp'] = $t; // ファイルのタイムスタンプをセット $returnData['isLoaded'] = true; } } return $returnData; }
●キャッシュに書き込む
/* * キャッシュをDBに登録する * $cacheId : キャッシュID * $content : キャッシュする内容(配列) */ function saveCacheDb($cacheId, &$cacheData){ unset($cacheData['isLoaded']); unset($cacheData['timeStamp']); dbRunSql( "replace into AultaCacheData (CacheId, CacheData, CacheDatetime)" . " values (" . " '" . dbRealEscape($cacheId) . "'" . ", '" . dbRealEscape(json_encode($cacheData)) . "'" . ", now()" . ")" ); }
●●使用例
$isCreate = true; $cacheId = 'URLや任意の文字など、識別するためのキー'; $data = loadCacheDb($cacheId, (12 * 3600)); if ($data['isLoaded']){ // キャッシュが見つかり、有効期限内 $isCreate = false; } else { // キャッシュが無いので作成する。 $data = array( 'header' => array() 'data' => array() ); ~~~~~ $dataにキャッシュ内容をセットする。 $data['header']、$data['data']に、キャッシュしたい内容を放り込んでいく。 データベースには、$data配列のまま保存し、配列のまま取り出すので、好きなように値をセットできます。 ~~~~~ saveCacheDb($cacheId, $dataContentInfo); }
サンプル作る途中で、ちょこっと端折ったけど、ページが随時更新されるコミュニティ系のサイトなんかだと、最終の投稿日を「header」に入れておいて、ロード時に、データベース側の最終更新日時と突き合わせたほうが良いと思います。
あーー!!
書き終えて気づいた。。。
dbRunSql() と dbGetFields() と dbRealEscape() は、独自関数でした。
とりあえず、
http://blog.aulta.net/2008/08/10/utilityphp-%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E3%82%92%E6%A5%BD%E3%81%AB%E3%81%99%E3%82%8B-function/
を読んでください。
その後、変更したり、追加したメソッドもあるから、はてなダのほうには、また後日載せます。