CACHE_LITE
技術開発部の岸田です。今回は、PEARライブラリーのCACHE_LITEを使ってキャッシュをお手軽に活用としてみたいと思います。
[CACHE_LITEを使用する前準備]
pear install Cache_Lite
今回の流れとしまして、一意なIDによって紐づけられている商品情報を取得し、その情報をキャッシュし、その商品情報に変更が生じた際にキャッシュを破棄し、新しくキャッシュを生成するです。
そんなこんなでこんな感じです。↓
こんな感じでお手軽にキャッシュを生成し、その情報に変更があれば最新の情報をキャッシュとして保存させる事が出来ます。
[CACHE_LITEを使用する前準備]
pear install Cache_Lite
今回の流れとしまして、一意なIDによって紐づけられている商品情報を取得し、その情報をキャッシュし、その商品情報に変更が生じた際にキャッシュを破棄し、新しくキャッシュを生成するです。
そんなこんなでこんな感じです。↓
// 接続情報
define ('DB_TYPE', 'pgsql');
define ('DB_USER', 'admin');
define ('DB_PASSWORD', '********');
define ('DB_SERVER', '127.0.0.1');
define ('DB_NAME', '********_db');
define ('DB_PORT', '5432');
if(defined('DB_TYPE') && defined('DB_USER') && defined('DB_PASSWORD') && defined('DB_SERVER') && defined('DB_PORT') && defined('DB_NAME')) {
// サイト用DB
define ("DEFAULT_DSN", DB_TYPE . "://" . DB_USER . ":" . DB_PASSWORD . "@" . DB_SERVER . ":" .DB_PORT . "/" . DB_NAME);
}
// キャッシュ用情報
$cache_option = array(
// キャッシュを保存するフォルダ
'cacheDir' => '../cache/tmp/',
// キャッシュの有効/無効
'caching' => "true",
// 自動シリアライズの有効/無効
'automaticSerialization' => "true",
// キャッシュ生存期間を秒単位で指定します
'lifeTime' => 100
);
require_once("MDB2.php");
require_once('cache/lite.php');
$mdb2 =& MDB2::factory(DEFAULT_DSN);
$cache = new Cache_Lite($cache_option);
if (PEAR::isError($mdb2)) {
// 接続エラー
die($mdb2->getMessage());
}else{
/* 本来ならばこっちのID使用
if(sfIsInt($_GET['product_id'])){
処理継続
}else{
echo '商品IDが不正です';
}
*/
// 今回は決め打ちで商品IDを固定する
$product_id = "3";
// キャッシュファイルがあれば、キャッシュファイル内の情報を表示
// [product_id3⇒商品情報]
if($cache_data = $cache->get('product_id'.$product_id)){
// 商品情報表示
print_r($cache_data);
// キャッシュファイルがなければ、キャッシュファイルを生成
}else{
// 商品IDから商品情報を取得
$product_info = lfGetProductInfo($product_id);
if($product_info == false){
// エラー処理
echo '商品がありません';
}else{
echo 'キャッシュ成功'."
";
// キャッシュファイル[product_id商品ID⇒商品情報]として生成
$cache->save($product_info, 'product_id'.$product_id);
print_r($product_info);
}
}
}
// 商品情報の在庫が一個減る
//lfCustomerBuy($product_id);
// 商品IDで紐付いてる商品情報されているキャッシュを削除
$cache->remove('product_id'.$product_id);
// お客様が商品を購入された場合
/**
* lfBuyProduct
*
*/
function lfCustomerBuy($product_id){
global $cache;
/* 在庫用のテーブルから、在庫を一つ減らす処理 */
省略
}
/**
* lfGetProductInfo
* 商品情報を配列に格納し、returnしてくれる
* @param $date array(integer) 商品IDを格納した配列
* @return $
*/
function lfGetProductInfo($product_id){
global $mdb2;
$tmp_product_id = array($product_id);
// プレースホルダー用SQL作成
$prepare = $mdb2->prepare('SELECT * FROM dtb_products WHERE product_id = ?', NULL, MDB2_PREPARE_RESULT );
// SQL実行
$exe = $prepare->execute($tmp_product_id);
// 取得結果を配列の形にして取得
$product_info = $exe->fetchAll(MDB2_FETCHMODE_ASSOC);
if(!is_array($product_info) AND "0" < count($product_info)){
// 商品情報が配列に格納されていなかったら、例外処理
return false;
}else{
// 商品情報をreturn
return $product_info;
}
}
// INT型の数値チェック
function sfIsInt($value) {
if($value != "" && strlen($value) <= INT_LEN && is_numeric($value)) {
return true;
}
return false;
}
こんな感じでお手軽にキャッシュを生成し、その情報に変更があれば最新の情報をキャッシュとして保存させる事が出来ます。


コメント (3)
はじめまして。フォーラムではお世話になっております。
EC-CUBE で CACHE_LITE を使おうか迷っていてこの記事を見ましたが、
参考までに 2 点ほど質問させて頂いてもよろしいでしょうか。
今回のソースでは、キャッシュの有無を見る前に、
DB 接続確認をしていますが、キャッシュがない場合のみ
DB 関連の処理をすると不都合が出るのでしょうか?
(コネクション取得コストがどれほどのものかわかりませんが)
DB にアクセスして情報を取得した場合と、キャッシュを利用した場合で、
パフォーマンスがどのくらい違うのかを比較した結果があればぜひ紹介してほしいと思います。
(今回、どのくらいのデータ量で比較したなど)
勝手な質問で申し訳ありませんがよろしくお願いします。
投稿者: guestkun | 2007年11月08日 09:55
guestkun様へ
返信有難う御座います、ロックオンの岸田です。
■キャッシュの有無を見る前に、
DB 接続確認をしていますが、キャッシュがない場合のみ
DB 関連の処理をすると不都合が出るのでしょうか?
◎キャッシュで保存されているデータのみ必要なページにおきましては、キャッシュ確認⇒なければDBに接続で問題ないです。
■DB にアクセスして情報を取得した場合と、キャッシュを利用した場合で、パフォーマンスがどのくらい違うのかを比較した>結果
◎検証しておりませんので、こちら確認する事が出来ておりません。しかしながら、アクセスの多いページ・DB接続を多様しているページにおきましてはキャッシュを利用する事で、DBへの接続が減少しコストパフォーマンスに繋がると考えられます。
以上で回答となっておりますでしょうか。
今後とも宜しくお願い致します。
投稿者: ロックオンの岸田です。 | 2007年11月12日 19:19
お返事ありがとうございました。
投稿者: guestkun | 2007年11月12日 21:51