キャッシュハンドラ関数

デフォルトのファイルベースのキャッシュメカニズムの代替として、キャッシュファイルの読み書きや破棄を直接行うキャッシュハンドラ関数を指定できます。

まず、アプリケーション内にSmartyがキャッシュハンドラとして使用するための関数を定義します。そしてその関数名を$cache_handler_funcで指定します。Smartyはキャッシュハンドラ関数の名前を取得するためにこれを参照します。第1パラメータにはキャッシュの動作を表す文字列('read', 'write', 'clear')のうちのどれか1つが渡され、第2パラメータにはSmartyのオブジェクトが渡されます。第3パラメータには、'write'の場合はキャッシュされたコンテンツが渡され、'read'の場合はキャッシュされたコンテンツが参照によって渡され、'clear'の場合はこのパラメータの値を使用しないのでダミーの変数が渡されます。第4パラメータはテンプレートファイル名です('read'又は'write'の場合に必要)。任意の第5パラメータにはキャッシュIDが渡されます。任意の第6パラメータにはコンパイルIDが渡されます。

注意: 最後のパラメータ ($exp_time) は Smarty-2.6.0 で追加されました。

例 14-5. キャッシュソースとしてMySQLを使用する例

<?php
/*

使用例:

include('Smarty.class.php');
include('mysql_cache_handler.php');

$smarty = new Smarty;
$smarty->cache_handler_func = 'mysql_cache_handler';

$smarty->display('index.tpl');


MySQLデータベースのスキーマ定義:
    
create database SMARTY_CACHE;

create table CACHE_PAGES(
CacheID char(32) PRIMARY KEY,
CacheContents MEDIUMTEXT NOT NULL
);

*/

function mysql_cache_handler($action, &$smarty_obj, &$cache_content, $tpl_file=null, $cache_id=null, $compile_id=null, $exp_time=null)
{
    
// ここでDBのホスト名・ユーザ名・パスワードを指定する
    
$db_host = 'localhost';
    
$db_user = 'myuser';
    
$db_pass = 'mypass';
    
$db_name = 'SMARTY_CACHE';
    
$use_gzip = false;
    
    
/// ユニークなキャッシュIDを作成する
    
$CacheID = md5($tpl_file.$cache_id.$compile_id);
    
    if(!
$link = mysql_pconnect($db_host, $db_user, $db_pass)) {
        
$smarty_obj->_trigger_error_msg("cache_handler: could not connect to database");
        return
false;
    }
    
mysql_select_db($db_name);

    switch (
$action) {
        case
'read':
            
// キャッシュをデータベースから読み込む
            
$results = mysql_query("select CacheContents from CACHE_PAGES where CacheID='$CacheID'");
            if(!
$results) {
                
$smarty_obj->_trigger_error_msg("cache_handler: query failed.");            
            }
            
$row = mysql_fetch_array($results,MYSQL_ASSOC);
            
            if(
$use_gzip && function_exists("gzuncompress")) {
                
$cache_contents = gzuncompress($row["CacheContents"]);
            } else {
                
$cache_contents = $row["CacheContents"];
            }
            
$return = $results;
            break;
        case
'write':
            
// キャッシュをデータベースに保存する
            
            
if($use_gzip && function_exists("gzcompress")) {
                
// 記憶効率のために内容を圧縮する
                
$contents = gzcompress($cache_content);
            } else {
                
$contents = $cache_content;
            }
            
$results = mysql_query("replace into CACHE_PAGES values(
                            '$CacheID',
                            '"
.addslashes($contents)."')
                        "
);
            if(!
$results) {
                
$smarty_obj->_trigger_error_msg("cache_handler: query failed.");            
            }
            
$return = $results;
            break;
        case
'clear':
            
// キャッシュ情報を破棄する
            
if(empty($cache_id) && empty($compile_id) && empty($tpl_file)) {
                
// 全てのキャッシュを破棄する
                
$results = mysql_query("delete from CACHE_PAGES");            
            } else {
                
$results = mysql_query("delete from CACHE_PAGES where CacheID='$CacheID'");            
            }
            if(!
$results) {
                
$smarty_obj->_trigger_error_msg("cache_handler: query failed.");            
            }
            
$return = $results;
            break;
        default:
            
// エラー・未知の動作
            
$smarty_obj->_trigger_error_msg("cache_handler: unknown action \"$action\"");
            
$return = false;
            break;
    }
    
mysql_close($link);
    return
$return;
    
}

?>